/* * Some grammar independent code. * This file is copied into Lpars.c. */ # ifndef NORCSID static char *rcsid = "$Header$"; # endif #define LLSTSIZ 1024 static short LLstack[LLSTSIZ]; /* Recovery stack */ short * LLptr; /* ptr in it */ #define LLmax (&LLstack[LLSTSIZ-1]) /* if beyond this, overflow */ int LLscd; /* lookahead done or not? */ int LLb,LLi; int LLsymb; int LLcsymb; static int LLlevel; static short * LLbase; static struct LLsaved { int LLs_i, LLs_b, LLs_s, LLs_c, LLs_t; short *LLs_p, *LLs_x; } LLsaved[LL_MAX]; /* In this file are defined: */ extern LLcheck(); extern LLscan(); extern LLpush(); extern LLlpush(); extern int LLpop(); extern int LLsskip(); static LLerror(); extern LLnewlevel(); extern LLoldlevel(); LLcheck() { register c; /* * The symbol to be checked is on the stack. */ if (!LLscd) { if ((c = LL_LEXI()) <= 0) c = EOFILE; LLsymb = c; } else LLscd = 0; if (LLsymb == *--LLptr) return; /* * If we come here, an error has been detected. * LLpop will try and recover */ LLptr++; while (LLindex[LLsymb] < 0) { LLerror(0); if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE; } LLcsymb = LLindex[LLsymb]; LLb = LLbyte[LLcsymb]; LLi = LLcsymb>>3; LLscd = 1; if (!LLpop()) LLerror(*LLptr); LLscd = 0; } LLscan(t) { /* * Check if the next symbol is equal to the parameter */ if (!LLscd) { if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE; } else LLscd = 0; if (LLsymb == t) return; /* * If we come here, an error has been detected */ LLpush(t); LLscd = 1; while (LLindex[LLsymb] < 0) { LLerror(0); if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE; } LLcsymb = LLindex[LLsymb]; LLb = LLbyte[LLcsymb]; LLi = LLcsymb>>3; if (!LLpop()) LLerror(t); LLscd = 0; } LLpush(t) { if (LLptr == LLmax) { LLerror(-1); } *LLptr++ = t; } LLlpush(d) { register i; register short *p; p = &LLlists[d]; i = *p++; while(i--) { if (LLptr == LLmax) { LLerror(-1); } *LLptr++ = *p++; } } LLsskip() { /* * Error recovery, and not only that! * Skip symbols until one is found that is on the stack. * Return 1 if it is on top of the stack */ register short *t; register i; for (;;) { if (!LLscd) { lab: if ((i = LL_LEXI()) <= 0) i = EOFILE; LLsymb = i; if ((i = LLindex[i]) < 0) { LLerror(0); goto lab; /* * Ugly, but we want speed * on possibly correct symbols !! * So, no breaks out of "for (;;)" */ } LLcsymb = i; LLb = LLbyte[i]; LLi = (i>>3); LLscd = 1; } t = LLptr-1; i = *t; if (!((i<=0 && LLsets[LLi-i]&LLb)||i==LLsymb)) { while (--t >= LLbase) { /* * If the element on the stack is negative, * its opposite is an index in the setarray, * otherwise it is a terminal symbol */ i = *t; if ((i<=0&&LLsets[LLi-i]&LLb)||i==LLsymb){ break; } } if (t >= LLbase) break; LLerror(0); LLscd = 0; } else { return 1; } } return t == LLptr - 1; } LLpop() { register i; i = LLsskip(); LLptr--; return i; } static LLerror(d) { LLmessage(d); if (d < 0) exit(1); } LLnewlevel() { register struct LLsaved *p; if (!LLlevel++) { LLptr = LLstack; LLbase = LLstack; LLpush(EOFILE); } else { if (LLlevel > LL_MAX) LLerror(-1); p = &LLsaved[LLlevel - 2]; p->LLs_p = LLptr; p->LLs_i = LLi; p->LLs_b = LLb; p->LLs_s = LLsymb; p->LLs_t = LLcsymb; p->LLs_c = LLscd; p->LLs_x = LLbase; LLbase = LLptr; LLpush(EOFILE); } } LLoldlevel() { register struct LLsaved *p; LLcheck(); if (--LLlevel) { p = &LLsaved[LLlevel-1]; LLptr = p->LLs_p; LLi = p->LLs_i; LLb = p->LLs_b; LLsymb = p->LLs_s; LLcsymb = p->LLs_t; LLbase = p->LLs_x; LLscd = p->LLs_c; } }