New version, much faster
This commit is contained in:
parent
42d0e056fb
commit
70a5d416d1
|
@ -3,215 +3,149 @@
|
||||||
* This file is copied into Lpars.c.
|
* This file is copied into Lpars.c.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# ifndef NORCSID
|
# ifndef lint
|
||||||
static char *rcsid = "$Header$";
|
static char *rcsid = "$Header$";
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#define LLSTSIZ 1024
|
# ifdef LL_DEBUG
|
||||||
static short LLstack[LLSTSIZ]; /* Recovery stack */
|
# include <stdio.h>
|
||||||
short * LLptr; /* ptr in it */
|
# endif
|
||||||
#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 LLsymb;
|
||||||
int LLs_i, LLs_b, LLs_s, LLs_c, LLs_t;
|
unsigned int LLtcnt[LL_NTERMINALS];
|
||||||
short *LLs_p, *LLs_x;
|
unsigned int LLscnt[LL_NSETS];
|
||||||
} LLsaved[LL_MAX];
|
int LLcsymb, LLsymb;
|
||||||
|
static int LLlevel;
|
||||||
|
|
||||||
/* In this file are defined: */
|
/* In this file are defined: */
|
||||||
extern LLcheck();
|
extern LLread();
|
||||||
|
extern int LLskip();
|
||||||
|
extern int LLnext();
|
||||||
extern LLscan();
|
extern LLscan();
|
||||||
extern LLpush();
|
extern LLerror();
|
||||||
extern LLlpush();
|
# ifndef LLNOFIRSTS
|
||||||
extern int LLpop();
|
extern int LLfirst();
|
||||||
extern int LLsskip();
|
# endif
|
||||||
static LLerror();
|
|
||||||
extern LLnewlevel();
|
extern LLnewlevel();
|
||||||
extern LLoldlevel();
|
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) {
|
LLscan(t) {
|
||||||
/*
|
/*
|
||||||
* Check if the next symbol is equal to the parameter
|
* Check if the next symbol is equal to the parameter
|
||||||
*/
|
*/
|
||||||
if (!LLscd) {
|
if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE;
|
||||||
if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE;
|
if (LLsymb == t) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else LLscd = 0;
|
|
||||||
if (LLsymb == t) return;
|
|
||||||
/*
|
/*
|
||||||
* If we come here, an error has been detected
|
* If we come here, an error has been detected
|
||||||
*/
|
*/
|
||||||
LLpush(t);
|
LLerror(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) {
|
LLread() {
|
||||||
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 (;;) {
|
for (;;) {
|
||||||
if (!LLscd) {
|
if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE;
|
||||||
lab:
|
if ((LLcsymb = LLindex[LLsymb]) >= 0) return;
|
||||||
if ((i = LL_LEXI()) <= 0) i = EOFILE;
|
LLmessage(0);
|
||||||
LLsymb = i;
|
}
|
||||||
if ((i = LLindex[i]) < 0) {
|
/* NOTREACHED */
|
||||||
LLerror(0);
|
}
|
||||||
goto lab;
|
|
||||||
/*
|
LLerror(t) {
|
||||||
* Ugly, but we want speed
|
register int i;
|
||||||
* on possibly correct symbols !!
|
|
||||||
* So, no breaks out of "for (;;)"
|
if ((LLcsymb = LLindex[LLsymb]) < 0) {
|
||||||
*/
|
LLmessage(0);
|
||||||
|
LLread();
|
||||||
|
}
|
||||||
|
i = LLindex[t];
|
||||||
|
LLtcnt[i]++;
|
||||||
|
if (LLskip()) /* nothing */;
|
||||||
|
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) {
|
||||||
|
|
||||||
|
if (LLskip()) /* nothing */;
|
||||||
|
if (n <= 0) return (LLsets[(LLcsymb >> 3) - n] & (1 << (LLcsymb & 07)));
|
||||||
|
return LLsymb == n;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLskip() {
|
||||||
|
register int i;
|
||||||
|
int retval;
|
||||||
|
int LLi, LLb;
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
LLcsymb = i;
|
|
||||||
LLb = LLbyte[i];
|
|
||||||
LLi = (i>>3);
|
|
||||||
LLscd = 1;
|
|
||||||
}
|
}
|
||||||
t = LLptr-1;
|
retval = 1;
|
||||||
i = *t;
|
LLmessage(0);
|
||||||
if (!((i<=0 && LLsets[LLi-i]&LLb)||i==LLsymb)) {
|
LLread();
|
||||||
while (--t >= LLbase) {
|
}
|
||||||
/*
|
/* NOTREACHED */
|
||||||
* If the element on the stack is negative,
|
}
|
||||||
* its opposite is an index in the setarray,
|
|
||||||
* otherwise it is a terminal symbol
|
LLnewlevel(LLsinfo) unsigned int *LLsinfo; {
|
||||||
*/
|
register int i;
|
||||||
i = *t;
|
|
||||||
if ((i<=0&&LLsets[LLi-i]&LLb)||i==LLsymb){
|
if (LLlevel++) {
|
||||||
break;
|
LLsinfo[LL_NSETS+LL_NTERMINALS] = (unsigned) LLsymb;
|
||||||
}
|
LLsinfo[LL_NSETS+LL_NTERMINALS+1] = (unsigned) LLcsymb;
|
||||||
}
|
for (i = LL_NTERMINALS - 1; i >= 0; i--) {
|
||||||
if (t >= LLbase) break;
|
LLsinfo[i] = LLtcnt[i];
|
||||||
LLerror(0);
|
LLtcnt[i] = 0;
|
||||||
LLscd = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
for (i = LL_NSETS - 1; i >= 0; i--) {
|
||||||
return 1;
|
LLsinfo[LL_NTERMINALS+i] = LLscnt[i];
|
||||||
|
LLscnt[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return t == LLptr - 1;
|
LLtincr(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLpop() {
|
LLoldlevel(LLsinfo) unsigned int *LLsinfo; {
|
||||||
register i;
|
register int i;
|
||||||
|
|
||||||
i = LLsskip();
|
LLtdecr(0);
|
||||||
LLptr--;
|
# ifdef LL_DEBUG
|
||||||
return i;
|
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
|
||||||
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) {
|
if (--LLlevel) {
|
||||||
p = &LLsaved[LLlevel-1];
|
for (i = LL_NSETS - 1; i >= 0; i--) {
|
||||||
LLptr = p->LLs_p;
|
LLscnt[i] = LLsinfo[LL_NTERMINALS+i];
|
||||||
LLi = p->LLs_i;
|
}
|
||||||
LLb = p->LLs_b;
|
for (i = LL_NTERMINALS - 1; i >= 0; i--) {
|
||||||
LLsymb = p->LLs_s;
|
LLtcnt[i] = LLsinfo[i];
|
||||||
LLcsymb = p->LLs_t;
|
}
|
||||||
LLbase = p->LLs_x;
|
LLsymb = (int) LLsinfo[LL_NSETS+LL_NTERMINALS];
|
||||||
LLscd = p->LLs_c;
|
LLcsymb = (int) LLsinfo[LL_NSETS+LL_NTERMINALS+1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef LL_DEBUG
|
||||||
|
LL_badassertion(asstr,file,line) char *asstr, *file; {
|
||||||
|
|
||||||
|
fprintf(stderr,"Assertion \"%s\" failed %s(%d)\n",asstr,file,line);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
Loading…
Reference in a new issue