/* * Some grammar independent code. * This file is copied into Lpars.c. */ # ifndef lint static char *rcsid = "$Header$"; # endif unsigned int LLtcnt[LL_NTERMINALS]; unsigned int LLscnt[LL_NSETS]; int LLcsymb, LLsymb; static int LLlevel; /* In this file are defined: */ extern LLread(); extern int LLskip(); extern int LLnext(); #ifndef LL_FASTER extern LLscan(); #endif extern LLerror(); # ifndef LLNOFIRSTS extern int LLfirst(); # endif extern LLnewlevel(); extern LLoldlevel(); #ifdef LL_USERHOOK static LLdoskip(); static int LLuserhook(); #endif #ifndef LL_FASTER LLscan(t) int t; { /* * Check if the next symbol is equal to the parameter */ if ((LLsymb = LL_LEXI()) == t) { return; } /* * If we come here, an error has been detected */ LLerror(t); } #endif LLread() { for (;;) { if ((LLcsymb = LLindex[(LLsymb = LL_LEXI())]) >= 0) return; LLmessage(0); } /* NOTREACHED */ } LLerror(t) int t; { register int i; if (t == EOFILE && LLsymb <= 0) return; #ifdef LL_NEWMESS if (t == EOFILE) { #ifdef LL_USERHOOK static int lst[] = { EOFILE, 0 }; if (LLuserhook(EOFILE, lst)) /* nothing */; #endif LL_USERHOOK if (LLsymb != EOFILE && LLsymb > 0) { LLmessage(-1); while ((LLsymb = LL_LEXI()) > 0 && LLsymb != EOFILE) /* nothing */ ; } return; } #endif if ((LLcsymb = LLindex[LLsymb]) < 0) { LLmessage(0); LLread(); } i = LLindex[t]; LLtcnt[i]++; #ifdef LL_USERHOOK if (LLdoskip(t)) /* nothing */; #else if (LLskip()) /* nothing */; #endif LLtcnt[i]--; if (LLsymb != t) LLmessage(t); } # ifndef LLNOFIRSTS LLfirst(x, d) { register int i; return (i = LLindex[x]) >= 0 && (LLsets[d + (i >> 3)] & (1 << (i & 07))); } # endif LLnext(n) int n; { /* returns: 0 if the current symbol is'nt skipped, and it is'nt a member of "n", 1 if we have a new symbol, but it is'nt a member, 2 if the current symbol is a member, and 3 if we have a new symbol and it is a member. So, the low order bit indicates wether we have a new symbol, and the next bit indicates wether it is a member of "n". */ int retval = 0; if (LLskip()) retval = 1; if (n <= 0 && LLsets[(LLcsymb >> 3) - n] & (1 << (LLcsymb & 07))) { retval |= 2; } else if (n > 0 && LLcsymb == LLindex[n]) retval |= 2; return retval; } LLskip() { /* returns 0 if the current symbol is'nt skipped, and 1 if it is, t.i., we have a new symbol */ #ifdef LL_USERHOOK return LLdoskip(0); } static int LLuserhook(exp, list) int exp; int *list; { int old = LLsymb; LL_USERHOOK(exp, list); LLread(); return LLsymb != old; } static LLmklist(list) register int *list; { char Xset[LL_SSIZE]; register char *p; register int i; for (p = &Xset[0]; p < &Xset[LL_SSIZE]; ) *p++ = 0; for (i = 0; i < LL_NTERMINALS; i++) { if (LLtcnt[i] != 0) Xset[i >> 3] |= (1 << (i & 07)); } for (i = LL_NSETS - 1; i >= 0; i--) if (LLscnt[i] != 0) { register char *q = &LLsets[LL_SSIZE * i]; p = &Xset[0]; while (p < &Xset[LL_SSIZE]) *p++ |= *q++; } for (i = 0; i < LL_NTERMINALS; i++) { if (Xset[i >> 3] & (1 << (i & 07))) { *list++ = LLtok[i]; } } *list = 0; } static LLdoskip(exp) int exp; { int LLx; int list[LL_NTERMINALS+1]; #endif LL_USERHOOK register int i; int retval; int LLi, LLb; retval = 0; #ifdef LL_USERHOOK LLmklist(list); LLx = LLuserhook(exp, list); if (LLx) retval = 1; #endif LL_USERHOOK for (;;) { if (LLtcnt[LLcsymb] != 0) { #ifdef LL_USERHOOK if (!exp || !LLx || LLcsymb == LLindex[exp]) #endif return retval; } LLi = LLcsymb >> 3; LLb = 1 << (LLcsymb & 07); for (i = LL_NSETS - 1; i >= 0; i--) { if (LLscnt[i] != 0) { if (LLsets[LL_SSIZE*i+LLi] & LLb) { #ifdef LL_USERHOOK if (!exp || !LLx || LLcsymb == LLindex[exp]) #endif return retval; } } } #ifdef LL_USERHOOK if (LLx) { LLx = LLuserhook(exp, list); continue; } #endif LL_USERHOOK LLmessage(0); retval = 1; LLread(); } /* NOTREACHED */ } LLnewlevel(LLsinfo) unsigned int *LLsinfo; { register int i; if (LLlevel++) { LLsinfo[LL_NSETS+LL_NTERMINALS] = (unsigned) LLsymb; LLsinfo[LL_NSETS+LL_NTERMINALS+1] = (unsigned) LLcsymb; for (i = LL_NTERMINALS - 1; i >= 0; i--) { LLsinfo[i] = LLtcnt[i]; LLtcnt[i] = 0; } for (i = LL_NSETS - 1; i >= 0; i--) { LLsinfo[LL_NTERMINALS+i] = LLscnt[i]; LLscnt[i] = 0; } } LLtincr(0); } LLoldlevel(LLsinfo) unsigned int *LLsinfo; { register int i; LLtdecr(0); # ifdef LL_DEBUG for (i = 0; i < LL_NTERMINALS; i++) LL_assert(LLtcnt[i] == 0); for (i = 0; i < LL_NSETS; i++) LL_assert(LLscnt[i] == 0); # endif if (--LLlevel) { for (i = LL_NSETS - 1; i >= 0; i--) { LLscnt[i] = LLsinfo[LL_NTERMINALS+i]; } for (i = LL_NTERMINALS - 1; i >= 0; i--) { LLtcnt[i] = LLsinfo[i]; } LLsymb = (int) LLsinfo[LL_NSETS+LL_NTERMINALS]; LLcsymb = (int) LLsinfo[LL_NSETS+LL_NTERMINALS+1]; } }