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