xref: /csrg-svn/usr.bin/pascal/src/yypanic.c (revision 15998)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 #ifndef lint
4 static	char sccsid[] = "@(#)yypanic.c 2.1 02/08/84";
5 #endif
6 
7 #include "whoami.h"
8 #include "0.h"
9 #include "tree_ty.h"	/* must be included for yy.h */
10 #include "yy.h"
11 
12 struct yytok oldpos;
13 /*
14  * The routine yyPerror coordinates the panic when
15  * the correction routines fail. Three types of panics
16  * are possible - those in a declaration part, those
17  * in a statement part, and those in an expression.
18  *
19  * Declaration part panics consider insertion of "begin",
20  * expression part panics will stop on more symbols.
21  * The panics are otherwise the same.
22  *
23  * ERROR MESSAGE SUPPRESSION STRATEGY: August 11, 1977
24  *
25  * If the parser has not made at least 2 moves since the last point of
26  * error then we want to suppress the supplied error message.
27  * Otherwise we print it.
28  * We then skip input up to the next solid symbol.
29  */
30 yyPerror(cp, kind)
31 	char *cp;
32 	register int kind;
33 {
34 	register int ishifts, brlev;
35 
36 	copy((char *) (&oldpos), (char *) (&Y), sizeof oldpos);
37 	brlev = 0;
38 	if (yychar < 0)
39 		yychar = yylex();
40 	for (ishifts = yyshifts; ; yychar = yylex(), yyshifts++)
41 		switch (yychar) {
42 			case YILLCH:
43 				yerror("Illegal character");
44 				if (ishifts == yyshifts)
45 					yyOshifts = 0;
46 				continue;
47 			case YEOF:
48 				if (kind == PDECL) {
49 					/*
50 					 * we have paniced to end of file
51 					 * during declarations. Separately
52 					 * compiled segments can syntactically
53 					 * exit without any error message, so
54 					 * we force one here.
55 					 */
56 					yerror(cp);
57 					continuation();
58 					yyunexeof();
59 				}
60 				goto quiet;
61 			case ';':
62 				if (kind == PPROG)
63 					continue;
64 				if (kind == PDECL)
65 					yychar = yylex();
66 				goto resume;
67 			case YEND:
68 				if (kind == PPROG)
69 					continue;
70 			case YPROCEDURE:
71 			case YFUNCTION:
72 				goto resume;
73 			case YLABEL:
74 			case YTYPE:
75 			case YCONST:
76 			case YVAR:
77 				if (kind == PSTAT) {
78 					yerror("Declaration found when statement expected");
79 					goto quiet;
80 				}
81 			case YBEGIN:
82 				goto resume;
83 			case YFOR:
84 			case YREPEAT:
85 			case YWHILE:
86 			case YGOTO:
87 			case YIF:
88 				if (kind != PDECL)
89 					goto resume;
90 				yerror("Expected keyword begin after declarations, before statements");
91 				unyylex(&Y);
92 				yychar = YBEGIN;
93 				yylval = nullsem(YBEGIN);
94 				goto quiet;
95 			case YTHEN:
96 			case YELSE:
97 			case YDO:
98 				if (kind == PSTAT) {
99 					yychar = yylex();
100 					goto resume;
101 				}
102 				if (kind == PEXPR)
103 					goto resume;
104 				continue;
105 			case ')':
106 			case ']':
107 				if (kind != PEXPR)
108 					continue;
109 				if (brlev == 0)
110 					goto resume;
111 				if (brlev > 0)
112 					brlev--;
113 				continue;
114 			case '(':
115 			case '[':
116 				brlev++;
117 				continue;
118 			case ',':
119 				if (brlev != 0)
120 					continue;
121 			case YOF:
122 			case YTO:
123 			case YDOWNTO:
124 				if (kind == PEXPR)
125 					goto resume;
126 				continue;
127 #ifdef PI
128 			/*
129 			 * A rough approximation for now
130 			 * Should be much more lenient on suppressing
131 			 * warnings.
132 			 */
133 			case YID:
134 				syneflg = TRUE;
135 				continue;
136 #endif
137 		}
138 resume:
139 	if (yyOshifts >= 2) {
140 		if (yychar != -1)
141 			unyylex(&Y);
142 		copy((char *) (&Y), (char *) (&oldpos), sizeof Y);
143 		yerror(cp);
144 		yychar = yylex();
145 	}
146 quiet:
147 	if (yyshifts - ishifts > 2 && opt('r')) {
148 		setpfx('r');
149 		yerror("Parsing resumes");
150 	}
151 	/*
152 	 * If we paniced in the statement part,
153 	 * and didn't stop at a ';', then we insert
154 	 * a ';' to prevent the recovery from immediately
155 	 * inserting one and complaining about it.
156 	 */
157 	if (kind == PSTAT && yychar != ';') {
158 		unyylex(&Y);
159 		yyshifts--;
160 		yytshifts--;
161 		yychar = ';';
162 		yylval = nullsem(';');
163 	}
164 }
165