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