1984-10-08 14:14:53 +00:00
|
|
|
/*
|
|
|
|
* Some grammar independent code.
|
|
|
|
* This file is copied into Lpars.c.
|
|
|
|
*/
|
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
# ifndef lint
|
1984-10-08 14:14:53 +00:00
|
|
|
static char *rcsid = "$Header$";
|
1984-10-09 10:16:33 +00:00
|
|
|
# endif
|
1984-10-08 14:14:53 +00:00
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
# ifdef LL_DEBUG
|
|
|
|
# include <stdio.h>
|
|
|
|
# endif
|
|
|
|
|
1984-10-08 14:14:53 +00:00
|
|
|
int LLsymb;
|
1985-11-25 15:50:19 +00:00
|
|
|
unsigned int LLtcnt[LL_NTERMINALS];
|
|
|
|
unsigned int LLscnt[LL_NSETS];
|
|
|
|
int LLcsymb, LLsymb;
|
1984-10-08 14:14:53 +00:00
|
|
|
static int LLlevel;
|
|
|
|
|
|
|
|
/* In this file are defined: */
|
1985-11-25 15:50:19 +00:00
|
|
|
extern LLread();
|
|
|
|
extern int LLskip();
|
|
|
|
extern int LLnext();
|
1984-10-08 14:14:53 +00:00
|
|
|
extern LLscan();
|
1985-11-25 15:50:19 +00:00
|
|
|
extern LLerror();
|
|
|
|
# ifndef LLNOFIRSTS
|
|
|
|
extern int LLfirst();
|
|
|
|
# endif
|
1984-10-08 14:14:53 +00:00
|
|
|
extern LLnewlevel();
|
|
|
|
extern LLoldlevel();
|
|
|
|
|
|
|
|
LLscan(t) {
|
|
|
|
/*
|
|
|
|
* Check if the next symbol is equal to the parameter
|
|
|
|
*/
|
1985-11-25 15:50:19 +00:00
|
|
|
if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE;
|
|
|
|
if (LLsymb == t) {
|
|
|
|
return;
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* If we come here, an error has been detected
|
|
|
|
*/
|
1985-11-25 15:50:19 +00:00
|
|
|
LLerror(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLread() {
|
|
|
|
for (;;) {
|
1984-10-08 14:14:53 +00:00
|
|
|
if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE;
|
1985-11-25 15:50:19 +00:00
|
|
|
if ((LLcsymb = LLindex[LLsymb]) >= 0) return;
|
|
|
|
LLmessage(0);
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
1985-11-25 15:50:19 +00:00
|
|
|
/* NOTREACHED */
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
LLerror(t) {
|
|
|
|
register int i;
|
1984-10-08 14:14:53 +00:00
|
|
|
|
1986-11-03 10:28:21 +00:00
|
|
|
#ifdef LL_NEWMESS
|
1986-10-29 11:30:50 +00:00
|
|
|
if (t == EOFILE) {
|
|
|
|
LLmessage(-1);
|
1986-11-05 21:31:23 +00:00
|
|
|
while ((LLsymb = LL_LEXI()) > 0) /* nothing */ ;
|
1986-10-29 11:30:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
1987-02-16 21:36:05 +00:00
|
|
|
#ifdef LL_USERHOOK
|
|
|
|
LL_USERHOOK(t);
|
|
|
|
LLread();
|
|
|
|
#endif LL_USERHOOK
|
1985-11-25 15:50:19 +00:00
|
|
|
if ((LLcsymb = LLindex[LLsymb]) < 0) {
|
|
|
|
LLmessage(0);
|
|
|
|
LLread();
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
1985-11-25 15:50:19 +00:00
|
|
|
i = LLindex[t];
|
|
|
|
LLtcnt[i]++;
|
1987-02-16 21:36:05 +00:00
|
|
|
if (LLdoskip()) /* nothing */;
|
1985-11-25 15:50:19 +00:00
|
|
|
LLtcnt[i]--;
|
|
|
|
if (LLsymb != t) LLmessage(t);
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
# ifndef LLNOFIRSTS
|
|
|
|
LLfirst(x, d) {
|
|
|
|
register int i;
|
1984-10-08 14:14:53 +00:00
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
return (i = LLindex[x]) >= 0 &&
|
|
|
|
(LLsets[d + (i >> 3)] & (1 << (i & 07)));
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
1985-11-25 15:50:19 +00:00
|
|
|
# endif
|
1984-10-08 14:14:53 +00:00
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
LLnext(n) {
|
1984-10-08 14:14:53 +00:00
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
if (LLskip()) /* nothing */;
|
|
|
|
if (n <= 0) return (LLsets[(LLcsymb >> 3) - n] & (1 << (LLcsymb & 07)));
|
|
|
|
return LLsymb == n;
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
LLskip() {
|
1987-02-16 21:36:05 +00:00
|
|
|
#ifdef LL_USERHOOK
|
|
|
|
LL_USERHOOK(0);
|
|
|
|
LLread();
|
|
|
|
#endif LL_USERHOOK
|
|
|
|
return LLdoskip();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLdoskip()
|
|
|
|
{
|
1985-11-25 15:50:19 +00:00
|
|
|
register int i;
|
|
|
|
int retval;
|
|
|
|
int LLi, LLb;
|
1984-10-08 14:14:53 +00:00
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
retval = 0;
|
|
|
|
for (;;) {
|
|
|
|
if (LLtcnt[LLcsymb] != 0) 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) return retval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
retval = 1;
|
|
|
|
LLmessage(0);
|
|
|
|
LLread();
|
|
|
|
}
|
|
|
|
/* NOTREACHED */
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
LLnewlevel(LLsinfo) unsigned int *LLsinfo; {
|
|
|
|
register int i;
|
1984-10-08 14:14:53 +00:00
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
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;
|
|
|
|
}
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
1985-11-25 15:50:19 +00:00
|
|
|
LLtincr(0);
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
LLoldlevel(LLsinfo) unsigned int *LLsinfo; {
|
|
|
|
register int i;
|
1984-10-08 14:14:53 +00:00
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
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
|
1984-10-08 14:14:53 +00:00
|
|
|
if (--LLlevel) {
|
1985-11-25 15:50:19 +00:00
|
|
|
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];
|
1984-10-08 14:14:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1985-11-25 15:50:19 +00:00
|
|
|
# ifdef LL_DEBUG
|
|
|
|
LL_badassertion(asstr,file,line) char *asstr, *file; {
|
|
|
|
|
|
|
|
fprintf(stderr,"Assertion \"%s\" failed %s(%d)\n",asstr,file,line);
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
# endif
|