xref: /original-bsd/usr.bin/pascal/src/yyparse.c (revision 2301fdfb)
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[] = "@(#)yyparse.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 /*
17  * Parser for 'yacc' output.
18  * Specifially Modified for Berkeley Pascal
19  */
20 
21 int	yystate;	/* Current parser state */
22 union semstack *yypv;
23 unsigned yytshifts = 1;	/* Number of "true" shifts */
24 
25 /*
26  * Parse Tables
27  */
28 int	yygo[];
29 int	yypgo[];
30 int	yyr1[];
31 int	yyr2[];
32 int	yyact[];
33 int	yypact[];
34 
35 /*
36  * Parse and parallel semantic stack
37  */
38 union semstack	yyv[MAXDEPTH];
39 int	yys[MAXDEPTH];
40 
41 /*
42  * This routine parses the input stream, and
43  * returns if it accepts, or if an unrecoverable syntax
44  * error is encountered.
45  */
46 yyparse()
47 {
48 	register int *ps, n, *p;
49 	int paniced, *panicps, idfail;
50 
51 #ifdef lint
52 	panicps = (int *) 0;
53 #endif
54 	yystate = 0;
55 	yychar = yylex();
56 	OY.Yychar = -1;
57 	yyshifts = 3;
58 	paniced = 0;
59 	ps = &yys[0]-1;
60 	yypv = &yyv[0]-1;
61 #ifdef PXP
62 	yypw = &yyw[0]-1;
63 #endif
64 
65 stack:
66 	/*
67 	 * Push new state and value.
68 	 */
69 	if (yypv >= &yyv[MAXDEPTH-1]) {
70 		yerror("Parse stack overflow");
71 		pexit(DIED);
72 	}
73 	*++ps = yystate;
74 	*++yypv = yyval;
75 #ifdef PXP
76 	yypw++;
77 #endif
78 newstate:
79 	/*
80 	 * Locate parsing actions for the
81 	 * new parser state.
82 	 */
83 	p = &yyact[ yypact[yystate+1] ];
84 	/*
85 	 * Search the parse actions table
86 	 * for something useful to do.
87 	 * While n is non-positive, it is the negation
88 	 * of the token we are testing for.
89 	 */
90 #ifdef PI
91 	if ((n = *p++) <= 0) {
92 		if (yychar < 0)
93 			yychar = yylex();
94 		do
95 			if ((n += yychar) != 0)
96 				p++;
97 		while ((n = *p++) <= 0);
98 	}
99 #else
100 	while ((n = *p++) <= 0)
101 		if ((n += yychar) != 0)
102 			p++;
103 #endif
104 	switch (n >> 12) {
105 
106 		/*
107 		 * Shift.
108 		 */
109 		case 2:
110 #ifdef PXP
111 			yypw[1].Wseqid = yyseqid;
112 			yypw[1].Wcol = yycol;
113 #endif
114 			OYcopy();
115 			yystate = n & 07777;
116 			yyval.i_entry = yylval;
117 #ifdef PI
118 			yychar = -1;
119 #else
120 			yychar = yylex();
121 #endif
122 			yyshifts++;
123 			yytshifts++;
124 			goto stack;
125 
126 		/*
127 		 * Reduce.
128 		 */
129 		case 3:
130 			n &= 07777;
131 			N = yyr2[n];
132 			if (N == 1 && OY.Yychar == YID && !yyEactr(n,
133 							yypv[0].cptr)) {
134 				idfail = 1;
135 				goto errin;
136 			}
137 			OY.Yychar = -1;
138 			ps -= N;
139 			yypv -= N;
140 #ifdef PXP
141 			yypw -= N;
142 #endif
143 			yyval = yypv[1];
144 			yyactr(n);
145 			/*
146 			 * Use goto table to find next state.
147 			 */
148 			p = &yygo[yypgo[yyr1[n]]];
149 			while (*p != *ps && *p >= 0)
150 				p += 2;
151 			yystate = p[1];
152 			goto stack;
153 
154 		/*
155 		 * Accept.
156 		 */
157 		case 4:
158 			return;
159 
160 		/*
161 		 * Error.
162 		 */
163 		case 1:
164 			idfail = 0;
165 errin:
166 			if ((paniced || yyshifts != 0) && yyrecover(ps, idfail)) {
167 				paniced = 0;
168 				ps = Ps;
169 				yystate = *ps;
170 				goto newstate;
171 			}
172 			/*
173 			 * Find a state where 'error' is a
174 			 * legal shift action.
175 			 */
176 			if (paniced && yyshifts <= 0 && ps >= panicps) {
177 				yypv -= (ps - panicps) + 1;
178 #ifdef PXP
179 				yypw -= (ps - panicps) + 1;
180 #endif
181 				ps = panicps - 1;
182 			}
183 			while (ps >= yys) {
184 				for (p = &yyact[ yypact[*ps+1] ] ; *p <= 0; p += 2)
185 					if (*p == -256) {
186 						panicps = ps;
187 						yystate= p[1] & 07777;
188 						yyOshifts = yyshifts;
189 						yyshifts = 0;
190 						paniced = 1;
191 						goto stack;
192 					}
193 				--ps;
194 				--yypv;
195 #ifdef PXP
196 				--yypw;
197 #endif
198 #ifdef PI
199 				if (OY.Yychar != YID)
200 					syneflg = TRUE;
201 #endif
202 				OY.Yychar = -1;
203 			}
204 			if (yychar == YEOF)
205 				yyunexeof();
206 			if (yystate == 1)
207 				yyexeof();
208 			yerror("Unrecoverable syntax error - QUIT");
209 			return;
210 	}
211 	panic("yyparse");
212 }
213