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