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