217 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
/* 
 | 
						|
 * 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;
 | 
						|
	}
 | 
						|
}
 | 
						|
 |