Initial revision
This commit is contained in:
12
util/LLgen/lib/incl
Normal file
12
util/LLgen/lib/incl
Normal file
@@ -0,0 +1,12 @@
|
||||
/* $Header$ */
|
||||
|
||||
#define LLin(x) (LLsets[(x)+LLi]&LLb)
|
||||
|
||||
extern short *LLptr;
|
||||
extern char LLsets[];
|
||||
extern int LLi, LLb;
|
||||
extern int LLsymb;
|
||||
extern int LLcsymb;
|
||||
extern int LLscd;
|
||||
|
||||
# include "Lpars.h"
|
||||
215
util/LLgen/lib/rec
Normal file
215
util/LLgen/lib/rec
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Some grammar independent code.
|
||||
* This file is copied into Lpars.c.
|
||||
*/
|
||||
|
||||
static char *rcsid = "$Header$";
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user