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