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