xref: /csrg-svn/usr.bin/pascal/src/yypanic.c (revision 6359)
1790Speter /* Copyright (c) 1979 Regents of the University of California */
2790Speter 
3*6359Speter static	char sccsid[] = "@(#)yypanic.c 1.3 03/29/82";
4790Speter 
5790Speter #include "whoami.h"
6790Speter #include "0.h"
7790Speter #include "yy.h"
8790Speter 
9790Speter struct yytok oldpos;
10790Speter /*
11790Speter  * The routine yyPerror coordinates the panic when
12790Speter  * the correction routines fail. Three types of panics
13790Speter  * are possible - those in a declaration part, those
14790Speter  * in a statement part, and those in an expression.
15790Speter  *
16790Speter  * Declaration part panics consider insertion of "begin",
17790Speter  * expression part panics will stop on more symbols.
18790Speter  * The panics are otherwise the same.
19790Speter  *
20790Speter  * ERROR MESSAGE SUPPRESSION STRATEGY: August 11, 1977
21790Speter  *
22790Speter  * If the parser has not made at least 2 moves since the last point of
23790Speter  * error then we want to suppress the supplied error message.
24790Speter  * Otherwise we print it.
25790Speter  * We then skip input up to the next solid symbol.
26790Speter  */
27790Speter yyPerror(cp, kind)
28790Speter 	char *cp;
29790Speter 	register int kind;
30790Speter {
31790Speter 	register int ishifts, brlev;
32790Speter 
33790Speter 	copy(&oldpos, &Y, sizeof oldpos);
34790Speter 	brlev = 0;
35790Speter 	if (yychar < 0)
36790Speter 		yychar = yylex();
37790Speter 	for (ishifts = yyshifts; ; yychar = yylex(), yyshifts++)
38790Speter 		switch (yychar) {
39790Speter 			case YILLCH:
40790Speter 				yerror("Illegal character");
41790Speter 				if (ishifts == yyshifts)
42790Speter 					yyOshifts = 0;
43790Speter 				continue;
44790Speter 			case YEOF:
45*6359Speter 				if (kind == PDECL) {
46*6359Speter 					/*
47*6359Speter 					 * we have paniced to end of file
48*6359Speter 					 * during declarations. Separately
49*6359Speter 					 * compiled segments can syntactically
50*6359Speter 					 * exit without any error message, so
51*6359Speter 					 * we force one here.
52*6359Speter 					 */
53*6359Speter 					yerror(cp);
54*6359Speter 					continuation();
55*6359Speter 					yyunexeof();
56*6359Speter 				}
57790Speter 				goto quiet;
58790Speter 			case ';':
59790Speter 				if (kind == PPROG)
60790Speter 					continue;
61790Speter 				if (kind == PDECL)
62790Speter 					yychar = yylex();
63790Speter 				goto resume;
64790Speter 			case YEND:
65790Speter 				if (kind == PPROG)
66790Speter 					continue;
67790Speter 			case YPROCEDURE:
68790Speter 			case YFUNCTION:
69790Speter 				goto resume;
70790Speter 			case YLABEL:
71790Speter 			case YTYPE:
72790Speter 			case YCONST:
73790Speter 			case YVAR:
74790Speter 				if (kind == PSTAT) {
75790Speter 					yerror("Declaration found when statement expected");
76790Speter 					goto quiet;
77790Speter 				}
78790Speter 			case YBEGIN:
79790Speter 				goto resume;
80790Speter 			case YFOR:
81790Speter 			case YREPEAT:
82790Speter 			case YWHILE:
83790Speter 			case YGOTO:
84790Speter 			case YIF:
85790Speter 				if (kind != PDECL)
86790Speter 					goto resume;
87790Speter 				yerror("Expected keyword begin after declarations, before statements");
88790Speter 				unyylex(&Y);
89790Speter 				yychar = YBEGIN;
90790Speter 				yylval = nullsem(YBEGIN);
91790Speter 				goto quiet;
92790Speter 			case YTHEN:
93790Speter 			case YELSE:
94790Speter 			case YDO:
95790Speter 				if (kind == PSTAT) {
96790Speter 					yychar = yylex();
97790Speter 					goto resume;
98790Speter 				}
99790Speter 				if (kind == PEXPR)
100790Speter 					goto resume;
101790Speter 				continue;
102790Speter 			case ')':
103790Speter 			case ']':
104790Speter 				if (kind != PEXPR)
105790Speter 					continue;
106790Speter 				if (brlev == 0)
107790Speter 					goto resume;
108790Speter 				if (brlev > 0)
109790Speter 					brlev--;
110790Speter 				continue;
111790Speter 			case '(':
112790Speter 			case '[':
113790Speter 				brlev++;
114790Speter 				continue;
115790Speter 			case ',':
116790Speter 				if (brlev != 0)
117790Speter 					continue;
118790Speter 			case YOF:
119790Speter 			case YTO:
120790Speter 			case YDOWNTO:
121790Speter 				if (kind == PEXPR)
122790Speter 					goto resume;
123790Speter 				continue;
124790Speter #ifdef PI
125790Speter 			/*
126790Speter 			 * A rough approximation for now
127790Speter 			 * Should be much more lenient on suppressing
128790Speter 			 * warnings.
129790Speter 			 */
130790Speter 			case YID:
1313086Smckusic 				syneflg = TRUE;
132790Speter 				continue;
133790Speter #endif
134790Speter 		}
135790Speter resume:
136790Speter 	if (yyOshifts >= 2) {
137790Speter 		if (yychar != -1)
138790Speter 			unyylex(&Y);
139790Speter 		copy(&Y, &oldpos, sizeof Y);
140790Speter 		yerror(cp);
141790Speter 		yychar = yylex();
142790Speter 	}
143790Speter quiet:
144790Speter 	if (yyshifts - ishifts > 2 && opt('r')) {
145790Speter 		setpfx('r');
146790Speter 		yerror("Parsing resumes");
147790Speter 	}
148790Speter 	/*
149790Speter 	 * If we paniced in the statement part,
150790Speter 	 * and didn't stop at a ';', then we insert
151790Speter 	 * a ';' to prevent the recovery from immediately
152790Speter 	 * inserting one and complaining about it.
153790Speter 	 */
154790Speter 	if (kind == PSTAT && yychar != ';') {
155790Speter 		unyylex(&Y);
156790Speter 		yyshifts--;
157790Speter 		yytshifts--;
158790Speter 		yychar = ';';
159790Speter 		yylval = nullsem(';');
160790Speter 	}
161790Speter }
162