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