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