1 /*-
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)yypanic.c 8.1 (Berkeley) 06/06/93";
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 */
yyPerror(cp,kind)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