2 * Some grammar independent code.
3 * This file is copied into Lpars.c.
7 static char *rcsid = "$Id: rec,v 2.24 1998/11/10 14:26:06 ceriel Exp $";
10 unsigned int LLtcnt[LL_NTERMINALS];
11 unsigned int LLscnt[LL_NSETS];
17 static int fake_eof = 0;
21 #define LL_VOIDCST (void)
28 static int LLdoskip(int);
29 static int LLuserhook(int, int*);
31 static int LLdoskip();
32 static int LLuserhook();
45 * Check if the next symbol is equal to the parameter
49 /* See if the error recovery has eaten an eof */
60 if ((LLsymb = LL_LEXI()) == t) {
64 /* Check if a previous parser has 'crashed', in that
65 * case continue with non-correcting parser
67 if (err_seen && !nc_done) {
70 /* Remember that the error recovery has eaten an eof */
82 * If we come here, an error has been detected
95 /* Again, check if another parser has crashed,
96 * in that case intercept and go to the
97 * non-correcting parser
100 if (err_seen && !nc_done) {
103 /* Pretend we read end of file */
105 LLcsymb = LLindex[EOFILE];
112 LLcsymb = LLindex[EOFILE];
119 if ((LLcsymb = LLindex[(LLsymb = LL_LEXI())]) >= 0) return;
134 if (t == EOFILE && LLsymb <= 0) return;
138 static int lst[] = { EOFILE, 0 };
139 LL_VOIDCST LLuserhook(EOFILE, lst);
140 #endif /* LL_USERHOOK */
141 if (LLsymb != EOFILE && LLsymb > 0) {
143 while ((LLsymb = LL_LEXI()) > 0 && LLsymb != EOFILE)
151 if ((!nc_done) && (LLsymb > 0) && (LLsymb != EOFILE)) {
159 if ((LLcsymb = LLindex[LLsymb]) < 0) {
166 LL_VOIDCST LLdoskip(t);
173 /* A little kludge here; when using non-correcting recovery
174 * it can happen that a program is correct but incomplete.
175 * Here, we test this, and make sure the appropriate
176 * message is generated
184 /* Not really, but to prevent more than 1 error message */
193 void LLsafeerror(int t)
199 if (t == EOFILE && LLsymb <= 0) return;
203 static int lst[] = { EOFILE, 0 };
204 LL_VOIDCST LLuserhook(EOFILE, lst);
205 #endif /* LL_USERHOOK */
206 if (LLsymb != EOFILE && LLsymb > 0) {
208 while ((LLsymb = LL_LEXI()) > 0 && LLsymb != EOFILE)
215 if ((!nc_done) && (LLsymb > 0) && (LLsymb != EOFILE)) {
221 /* A little kludge here; when using non-correcting recovery
222 * it can happen that a program is correct but incomplete.
223 * Here, we test this, and make sure the appropriate
224 * message is generated
232 /* Not really, but to prevent more than 1 error message */
241 int LLfirst(int x, int d) {
247 return (i = LLindex[x]) >= 0 &&
248 (LLsets[d + (i >> 3)] & (1 << (i & 07)));
259 /* returns: 0 if the current symbol is'nt skipped, and it
260 is'nt a member of "n",
261 1 if we have a new symbol, but it is'nt a member,
262 2 if the current symbol is a member,
263 and 3 if we have a new symbol and it is a member.
264 So, the low order bit indicates wether we have a new symbol,
265 and the next bit indicates wether it is a member of "n".
270 if (LLskip()) retval = 1;
271 if (n <= 0 && LLsets[(LLcsymb >> 3) - n] & (1 << (LLcsymb & 07))) {
274 else if (n > 0 && LLcsymb == LLindex[n]) retval |= 2;
283 /* returns 0 if the current symbol is'nt skipped, and
284 1 if it is, t.i., we have a new symbol
291 extern void LL_USERHOOK(int, int *);
292 static int LLuserhook(int e, int *list)
294 static int LLuserhook(e, list)
300 LL_USERHOOK(e, list);
302 return LLsymb != old;
306 static void LLmklist(register int *list)
308 static LLmklist(list)
316 for (p = &Xset[0]; p < &Xset[LL_SSIZE]; ) *p++ = 0;
317 for (i = 0; i < LL_NTERMINALS; i++) {
318 if (LLtcnt[i] != 0) Xset[i >> 3] |= (1 << (i & 07));
320 for (i = LL_NSETS - 1; i >= 0; i--) if (LLscnt[i] != 0) {
321 register char *q = &LLsets[LL_SSIZE * i];
324 while (p < &Xset[LL_SSIZE]) *p++ |= *q++;
326 for (i = 0; i < LL_NTERMINALS; i++) {
327 if (Xset[i >> 3] & (1 << (i & 07))) {
335 static int LLdoskip(int e)
337 static int LLdoskip(e)
342 int list[LL_NTERMINALS+1];
343 #endif /* LL_USERHOOK */
351 LLx = LLuserhook(e, list);
353 #endif /* LL_USERHOOK */
355 if (LLtcnt[LLcsymb] != 0) {
357 if (!e || !LLx || LLcsymb == LLindex[e])
362 LLb = 1 << (LLcsymb & 07);
363 for (i = LL_NSETS - 1; i >= 0; i--) {
364 if (LLscnt[i] != 0) {
365 if (LLsets[LL_SSIZE*i+LLi] & LLb) {
367 if (!e || !LLx || LLcsymb == LLindex[e])
375 LLx = LLuserhook(e, list);
378 #endif /* LL_USERHOOK */
380 if ((!nc_done) && (LLsymb > 0)) {
399 void LLnewlevel(unsigned int *LLsinfo) {
401 LLnewlevel(LLsinfo) unsigned int *LLsinfo; {
406 LLsinfo[LL_NSETS+LL_NTERMINALS] = (unsigned) LLsymb;
407 LLsinfo[LL_NSETS+LL_NTERMINALS+1] = (unsigned) LLcsymb;
408 for (i = LL_NTERMINALS - 1; i >= 0; i--) {
409 LLsinfo[i] = LLtcnt[i];
412 for (i = LL_NSETS - 1; i >= 0; i--) {
413 LLsinfo[LL_NTERMINALS+i] = LLscnt[i];
421 void LLoldlevel(unsigned int *LLsinfo) {
423 LLoldlevel(LLsinfo) unsigned int *LLsinfo; {
429 for (i = 0; i < LL_NTERMINALS; i++) LL_assert(LLtcnt[i] == 0);
430 for (i = 0; i < LL_NSETS; i++) LL_assert(LLscnt[i] == 0);
433 for (i = LL_NSETS - 1; i >= 0; i--) {
434 LLscnt[i] = LLsinfo[LL_NTERMINALS+i];
436 for (i = LL_NTERMINALS - 1; i >= 0; i--) {
437 LLtcnt[i] = LLsinfo[i];
439 LLsymb = (int) LLsinfo[LL_NSETS+LL_NTERMINALS];
440 LLcsymb = (int) LLsinfo[LL_NSETS+LL_NTERMINALS+1];