USG_PG3/usr/source/lil/par.c
#include "common"
#define ERROR 0
#define COMPARE 1
#define SHIFT 2
#define REDUCE 3
#define ACCEPT 4
#define STSIZE 40
struct token stack[STSIZE]; /* the parser stack */
int stused; /* space used in stack */
int sthigh; /* high water mark */
struct token *ps; /* ps[1] is leftmost token to reduce */
copy(p) struct at *p;
{ps[1].flags = p->flags;
ps[1].type = p->type;
ps[1].value = p->value;
ps[1].bias = p->bias;
ps[1].size = p->size;
ps[1].prev = p->prev;
ps[1].tbran = p->tbran;
ps[1].fbran = p->fbran; }
int shift; /* TRUE if next token ready */
char next()
{if (!shift) {e.type = lex(); shift = TRUE; }
if (e.type < KOND) return (e.type);
return (IDENT); }
char insert[] {-1, SCOLON, COMMA, IDENT, RPAREN, RBRAK, QUOTES,
LPAREN, WHILE, EOF, -1};
struct token f; /* error token */
/*
int profile[STSIZE];
*/
parse() {extern int yygo[], yypgo[], yyr1[], yyr2[], yyact[], yypact[];
extern char name[];
int eflag, n, state, type, *ap, *gp;
eflag = 0;
shift = FALSE;
stused = 0;
stack[0].state = 0;
ps = &stack[stused];
state = ps[0].state;
while (TRUE)
{ap = &yyact[yypact[state + 1]];
if (*ap >> 12 == COMPARE)
{type = eflag > 0 ? f.type : next();
do if (type != (*ap & 07777)) ap++;
while (*++ap >> 12 == COMPARE);
}
n = *ap & 07777;
switch (*ap >> 12) {
case ERROR: if ((f.type = insert[++eflag]) >= 0)
continue;
error("syntax: %s deleted", s(&e));
eflag = -1;
shift = FALSE;
continue;
case SHIFT: ps[1].start = elc->value;
ps[1].sbias = elc->bias;
state = n;
if (eflag)
{copy(&f);
error("syntax: %s added before %s",
s(&f), s(&e));
eflag = -1; }
else {
if (!skip && test(&e, DCLF))
{e.value = add(name, 0, MEM, 0, 2);
e.flags = 0; }
if (debug > 1) error("shift %s", s(&e));
copy(&e);
eflag = 0;
shift = FALSE;
}
break;
case REDUCE: if (debug > 1) error("reduce %d", n);
sthigh = stused;
stused =- yyr2[n]; ps = &stack[stused];
state = ps[0].state;
yyactr(n);
for (gp = &yygo[yypgo[yyr1[n]]];
*gp >= 0 && *gp != state; gp =+ 2) ;
state = *++gp; break;
case ACCEPT: return;
}
if (stused++ >= STSIZE)
{error("stack overflow");
exit(TRUE); }
/*
profile[stused]++;
*/
(++ps)[0].state = state;
}
}
main(argc, argv) int argc; char *argv[];
{struct symbol *p, *pt;
int bad, better, i, j;
extern int errors, hiwater, osize, shorter, longer;
if (argc != 4 || (fin = open(argv[1], 0)) < 0
|| (fsyms = creat(argv[2], 0666)) < 0
|| (fcode = creat(argv[3], 0666)) < 0)
{error("bad args");
exit(TRUE); }
init(); /* setup symbol table */
add(".abs", DEFF, MEM, 0, 2); /* first 4 entries are elcs */
(elc = add(".text", DEFF, MEM, 0, 2))->bias = 1;
add(".data", DEFF, MEM, 0, 2)->bias = 2;
add(".bss", DEFF, MEM, 0, 2)->bias = 3;
line = 1; /* set starting line no. */
spsave = sptop; /* start new local region */
settoelc(dot); /* set dot to elc */
parse(); /* compile */
endlocal(NULL); /* end new local region */
settoelc(tlist); /* dump pending jump targets */
pipe(-1); /* drain the pipe */
pt = &symtab[spused];
setvb(symtab, spused, 0);
do {
i = 0; bad = better = FALSE;
for (p = symtab; p != pt; p++)
{if (p->bias > 3)
{if ((j = symtab[i].bias) <= 3)
{p->value =+ symtab[j].value;
p->bias = symtab[j].bias;
better = TRUE; }
else if (p->bias != i) bad = TRUE; }
i++; }
} while (bad && better);
if (bad && !better) error("circular definitions");
for (p = symtab; p != pt; p++)
{write(fsyms, p->name, 8);
i = (test(p, PUBF) ? 040 : 0) |
(p->bias <= 3 ? p->bias + 1 : 040);
write(fsyms, &i, 2);
if (i == 040) write(fsyms, &(p->size), 2);
else write(fsyms, &(p->value), 2);
}
if (debug)
{select(1);
printf("%d lines, %d table entries\n", line, spused);
for (p = symtab; p != pt; p++)
printf("%c%c%c%c %s = %o + %o\n",
test(p, PUBF) ? 'g' : ' ',
test(p, DEFF) ? 'd' : ' ',
test(p, DCLF) ? 'l' : ' ',
test(p, BYTF) ? 'b' : ' ',
sn(p->name), p->value, p->bias);
/*
printf("stack profile -");
for (i = 0; i < STSIZE; i++) {
if (i % 10 == 0) putchar('\n');
printf(" %d", profile[i]); }
putchar('\n');
*/
printf("%d%s%d%s%d%s%d%s\n",
osize, "-word pipe, filled to ",
hiwater, " made ",
shorter, " shorter, left ",
longer, " longer");
flush(); }
exit(errors > 0); }
#define v0 &ps[0]
#define v1 &ps[1]
#define v2 &ps[2]
#define v3 &ps[3]
#define v4 &ps[4]
#include "tables"