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