Update yacc.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "files.h"
|
||||
|
||||
@@ -276,3 +277,16 @@ extern char *writem();
|
||||
#ifndef ZAPFILE
|
||||
#define ZAPFILE(x) unlink(x)
|
||||
#endif
|
||||
|
||||
void setup(int argc, char *argv[]);
|
||||
void output(void);
|
||||
void go2out(void);
|
||||
void hideprod(void);
|
||||
void callopt(void);
|
||||
void error(char *fmt, ...);
|
||||
void warray(char *s, int *v, int n);
|
||||
void aryfil(int *v, int n, int c);
|
||||
void closure(int i);
|
||||
int apack(int *p, int n);
|
||||
void putitem(int *ptr, struct looksets *lptr);
|
||||
int state(int c);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dextern.h"
|
||||
|
||||
@@ -45,6 +46,13 @@ int **pres[NNONTERM + 2]; /* vector of pointers to productions yielding each non
|
||||
struct looksets *pfirst[NNONTERM + 2]; /* vector of pointers to first sets for each nonterminal */
|
||||
int pempty[NNONTERM + 1]; /* vector of nonterminals nontrivially deriving e */
|
||||
|
||||
static void cpres(void);
|
||||
static void cempty(void);
|
||||
static void cpfir(void);
|
||||
static void stagen(void);
|
||||
static void summary(void);
|
||||
static void others(void);
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
@@ -64,9 +72,12 @@ char *argv[];
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* put out other arrays, copy the parsers
|
||||
*/
|
||||
void others()
|
||||
{ /* put out other arrays, copy the parsers */
|
||||
register c, i, j;
|
||||
{
|
||||
register int c, i, j;
|
||||
|
||||
finput = fopen(PARSER, "r");
|
||||
if (finput == NULL)
|
||||
@@ -101,7 +112,8 @@ void others()
|
||||
if (c == '$') {
|
||||
if ((c = getc(finput)) != 'A')
|
||||
putc('$', ftable);
|
||||
else { /* copy actions */
|
||||
else {
|
||||
/* copy actions */
|
||||
faction = fopen(ACTNAME, "r");
|
||||
if (faction == NULL)
|
||||
error("cannot reopen action tempfile");
|
||||
@@ -122,15 +134,19 @@ char *chcopy(p, q)
|
||||
register char *p, *q;
|
||||
{
|
||||
/* copies string q into p, returning next free char ptr */
|
||||
while (*p = *q++)
|
||||
while ((*p = *q++))
|
||||
++p;
|
||||
return (p);
|
||||
}
|
||||
|
||||
#define ISIZE 400
|
||||
|
||||
/*
|
||||
* creates output string for item pointed to by pp
|
||||
*/
|
||||
char *writem(pp)
|
||||
int *pp;
|
||||
{ /* creates output string for item pointed to by pp */
|
||||
{
|
||||
register int i, *p;
|
||||
static char sarr[ISIZE];
|
||||
register char *q;
|
||||
@@ -151,7 +167,8 @@ int *pp;
|
||||
error("item too big");
|
||||
}
|
||||
|
||||
if ((i = *pp) < 0) { /* an item calling for a reduction */
|
||||
if ((i = *pp) < 0) {
|
||||
/* an item calling for a reduction */
|
||||
q = chcopy(q, " (");
|
||||
sprintf(q, "%d)", -i);
|
||||
}
|
||||
@@ -159,8 +176,11 @@ int *pp;
|
||||
return (sarr);
|
||||
}
|
||||
|
||||
/*
|
||||
* return a pointer to the name of symbol i
|
||||
*/
|
||||
char *symnam(i)
|
||||
{ /* return a pointer to the name of symbol i */
|
||||
{
|
||||
register char *cp;
|
||||
|
||||
cp = (i >= NTBASE) ? nontrst[i - NTBASE].name : tokset[i].name;
|
||||
@@ -179,9 +199,11 @@ int zzsrconf = 0;
|
||||
int *zzmemsz = mem0;
|
||||
int zzrrconf = 0;
|
||||
|
||||
/*
|
||||
* output the summary on the tty
|
||||
*/
|
||||
void summary()
|
||||
{ /* output the summary on the tty */
|
||||
|
||||
{
|
||||
if (foutput != NULL) {
|
||||
fprintf(foutput, "\n%d/%d terminals, %d/%d nonterminals\n", ntokens, NTERMS, nnonter,
|
||||
NNONTERM);
|
||||
@@ -213,33 +235,44 @@ void summary()
|
||||
fclose(fdefine);
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
void error(s, a1) char *s;
|
||||
{ /* write out error comment */
|
||||
/*
|
||||
* write out error comment
|
||||
*/
|
||||
void error(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
++nerrors;
|
||||
fprintf(stderr, "\n fatal error: ");
|
||||
fprintf(stderr, s, a1);
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, ", line %d\n", lineno);
|
||||
if (!fatfl)
|
||||
return;
|
||||
|
||||
summary();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* set elements 0 through n-1 to c
|
||||
*/
|
||||
void aryfil(v, n, c) int *v, n, c;
|
||||
{ /* set elements 0 through n-1 to c */
|
||||
{
|
||||
register int i;
|
||||
for (i = 0; i < n; ++i)
|
||||
v[i] = c;
|
||||
}
|
||||
|
||||
int setunion(a, b)
|
||||
register *a, *b;
|
||||
register int *a, *b;
|
||||
{
|
||||
/* set a to the union of a and b */
|
||||
/* return 1 if b is not a subset of a, 0 otherwise */
|
||||
register i, x, sub;
|
||||
register int i, x, sub;
|
||||
|
||||
sub = 0;
|
||||
SETLOOP(i)
|
||||
@@ -253,7 +286,7 @@ register *a, *b;
|
||||
|
||||
void prlook(p) struct looksets *p;
|
||||
{
|
||||
register j, *pp;
|
||||
register int j, *pp;
|
||||
|
||||
pp = p->lset;
|
||||
if (pp == 0)
|
||||
@@ -269,12 +302,15 @@ void prlook(p) struct looksets *p;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* compute an array with the beginnings of productions yielding given nonterminals
|
||||
* The array pres points to these lists
|
||||
*/
|
||||
void cpres()
|
||||
{ /* compute an array with the beginnings of productions yielding given nonterminals
|
||||
The array pres points to these lists */
|
||||
{
|
||||
/* the array pyield has the lists: the total size is only NPROD+1 */
|
||||
int **pmem;
|
||||
register c, j, i;
|
||||
register int c, j, i;
|
||||
static int *pyield[NPROD];
|
||||
|
||||
pmem = pyield;
|
||||
@@ -308,14 +344,15 @@ int indebug = 0;
|
||||
void cpfir()
|
||||
{
|
||||
/* compute an array with the first of nonterminals */
|
||||
register *p, **s, i, **t, ch, changes;
|
||||
register int *p, **s, i, **t, ch, changes;
|
||||
|
||||
zzcwp = &wsets[nnonter];
|
||||
NTLOOP(i)
|
||||
{
|
||||
aryfil(wsets[i].ws.lset, tbitset, 0);
|
||||
t = pres[i + 1];
|
||||
for (s = pres[i]; s < t; ++s) { /* initially fill the sets */
|
||||
for (s = pres[i]; s < t; ++s) {
|
||||
/* initially fill the sets */
|
||||
for (p = *s; (ch = *p) > 0; ++p) {
|
||||
if (ch < NTBASE) {
|
||||
SETBIT(wsets[i].ws.lset, ch);
|
||||
@@ -357,17 +394,21 @@ void cpfir()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sorts last state,and sees if it equals earlier ones. returns state number
|
||||
*/
|
||||
int state(c)
|
||||
{ /* sorts last state,and sees if it equals earlier ones. returns state number */
|
||||
{
|
||||
int size1, size2;
|
||||
register i;
|
||||
register int i;
|
||||
struct item *p1, *p2, *k, *l, *q1, *q2;
|
||||
p1 = pstate[nstate];
|
||||
p2 = pstate[nstate + 1];
|
||||
if (p1 == p2)
|
||||
return (0); /* null state */
|
||||
/* sort the items */
|
||||
for (k = p2 - 1; k > p1; k--) { /* make k the biggest */
|
||||
for (k = p2 - 1; k > p1; k--) {
|
||||
/* make k the biggest */
|
||||
for (l = k - 1; l >= p1; --l)
|
||||
if (l->pitem > k->pitem) {
|
||||
int *s;
|
||||
@@ -452,15 +493,18 @@ struct looksets *lptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mark nonterminals which derive the empty string
|
||||
* also, look for nonterminals which don't derive any token strings
|
||||
*/
|
||||
void cempty()
|
||||
{ /* mark nonterminals which derive the empty string */
|
||||
/* also, look for nonterminals which don't derive any token strings */
|
||||
{
|
||||
|
||||
#define EMPTY 1
|
||||
#define WHOKNOWS 0
|
||||
#define OK 1
|
||||
|
||||
register i, *p;
|
||||
register int i, *p;
|
||||
|
||||
/* first, use the array pempty to detect productions that can never be reduced */
|
||||
/* set pempty to WHONOWS */
|
||||
@@ -477,7 +521,8 @@ more:
|
||||
if (*p >= NTBASE && pempty[*p - NTBASE] == WHOKNOWS)
|
||||
break;
|
||||
}
|
||||
if (*p < 0) { /* production can be derived */
|
||||
if (*p < 0) {
|
||||
/* production can be derived */
|
||||
pempty[*prdptr[i] - NTBASE] = OK;
|
||||
goto more;
|
||||
}
|
||||
@@ -512,10 +557,12 @@ more:
|
||||
again:
|
||||
PLOOP(1, i)
|
||||
{
|
||||
if (pempty[*prdptr[i] - NTBASE] == WHOKNOWS) { /* not known to be empty */
|
||||
if (pempty[*prdptr[i] - NTBASE] == WHOKNOWS) {
|
||||
/* not known to be empty */
|
||||
for (p = prdptr[i] + 1; *p >= NTBASE && pempty[*p - NTBASE] == EMPTY; ++p)
|
||||
;
|
||||
if (*p < 0) { /* we have a nontrivially empty nonterminal */
|
||||
if (*p < 0) {
|
||||
/* we have a nontrivially empty nonterminal */
|
||||
pempty[*prdptr[i] - NTBASE] = EMPTY;
|
||||
goto again; /* got one ... try for another */
|
||||
}
|
||||
@@ -525,11 +572,14 @@ again:
|
||||
|
||||
int gsdebug = 0;
|
||||
|
||||
/*
|
||||
* generate the states
|
||||
*/
|
||||
void stagen()
|
||||
{ /* generate the states */
|
||||
{
|
||||
|
||||
int i, j;
|
||||
register c;
|
||||
register int c;
|
||||
register struct wset *p, *q;
|
||||
|
||||
/* initialize */
|
||||
@@ -537,10 +587,10 @@ void stagen()
|
||||
nstate = 0;
|
||||
/* THIS IS FUNNY from the standpoint of portability */
|
||||
/* it represents the magic moment when the mem0 array, which has
|
||||
/* been holding the productions, starts to hold item pointers, of a
|
||||
/* different type... */
|
||||
* been holding the productions, starts to hold item pointers, of a
|
||||
* different type... */
|
||||
/* someday, alloc should be used to allocate all this stuff... for now, we
|
||||
/* accept that if pointers don't fit in integers, there is a problem... */
|
||||
* accept that if pointers don't fit in integers, there is a problem... */
|
||||
|
||||
pstate[0] = pstate[1] = (struct item *)mem;
|
||||
aryfil(clset.lset, tbitset, 0);
|
||||
@@ -562,8 +612,7 @@ more:
|
||||
aryfil(temp1, nnonter + 1, 0);
|
||||
/* take state i, close it, and do gotos */
|
||||
closure(i);
|
||||
WSLOOP(wsets, p)
|
||||
{ /* generate goto's */
|
||||
WSLOOP(wsets, p) { /* generate goto's */
|
||||
if (p->flag)
|
||||
continue;
|
||||
p->flag = 1;
|
||||
@@ -574,9 +623,9 @@ more:
|
||||
continue;
|
||||
}
|
||||
/* do a goto on c */
|
||||
WSLOOP(p, q)
|
||||
{
|
||||
if (c == *(q->pitem)) { /* this item contributes to the goto */
|
||||
WSLOOP(p, q) {
|
||||
if (c == *(q->pitem)) {
|
||||
/* this item contributes to the goto */
|
||||
putitem(q->pitem + 1, &q->ws);
|
||||
q->flag = 1;
|
||||
}
|
||||
@@ -604,9 +653,11 @@ more:
|
||||
|
||||
int cldebug = 0; /* debugging flag for closure */
|
||||
|
||||
/*
|
||||
* generate the closure of state i
|
||||
*/
|
||||
void closure(i)
|
||||
{ /* generate the closure of state i */
|
||||
|
||||
{
|
||||
int c, ch, work, k;
|
||||
register struct wset *u, *v;
|
||||
int *pi;
|
||||
@@ -632,8 +683,7 @@ void closure(i)
|
||||
work = 1;
|
||||
while (work) {
|
||||
work = 0;
|
||||
WSLOOP(wsets, u)
|
||||
{
|
||||
WSLOOP(wsets, u) {
|
||||
if (u->flag == 0)
|
||||
continue;
|
||||
c = *(u->pitem); /* dot is before c */
|
||||
@@ -648,14 +698,14 @@ void closure(i)
|
||||
|
||||
/* find items involving c */
|
||||
|
||||
WSLOOP(u, v)
|
||||
{
|
||||
WSLOOP(u, v) {
|
||||
if (v->flag == 1 && *(pi = v->pitem) == c) {
|
||||
v->flag = 0;
|
||||
if (nolook)
|
||||
continue;
|
||||
while ((ch = *++pi) > 0) {
|
||||
if (ch < NTBASE) { /* terminal symbol */
|
||||
if (ch < NTBASE) {
|
||||
/* terminal symbol */
|
||||
SETBIT(clset.lset, ch);
|
||||
break;
|
||||
}
|
||||
@@ -676,9 +726,10 @@ void closure(i)
|
||||
t = pres[c + 1];
|
||||
for (s = pres[c]; s < t; ++s) {
|
||||
/* put these items into the closure */
|
||||
WSLOOP(wsets, v)
|
||||
{ /* is the item there */
|
||||
if (v->pitem == *s) { /* yes, it is there */
|
||||
WSLOOP(wsets, v) {
|
||||
/* is the item there */
|
||||
if (v->pitem == *s) {
|
||||
/* yes, it is there */
|
||||
if (nolook)
|
||||
goto nexts;
|
||||
if (setunion(v->ws.lset, clset.lset))
|
||||
@@ -709,8 +760,7 @@ void closure(i)
|
||||
zzcwp = cwp;
|
||||
if (cldebug && (foutput != NULL)) {
|
||||
fprintf(foutput, "\nState %d, nolook = %d\n", i, nolook);
|
||||
WSLOOP(wsets, u)
|
||||
{
|
||||
WSLOOP(wsets, u) {
|
||||
if (u->flag)
|
||||
fprintf(foutput, "flag set!\n");
|
||||
u->flag = 0;
|
||||
@@ -729,7 +779,7 @@ struct looksets *p;
|
||||
|
||||
register struct looksets *q;
|
||||
int j, *w;
|
||||
register *u, *v;
|
||||
register int *u, *v;
|
||||
|
||||
for (q = &lkst[nlset]; q-- > lkst;) {
|
||||
u = p->lset;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "dextern.h"
|
||||
#include <string.h>
|
||||
|
||||
#define IDENTIFIER 257
|
||||
#define MARK 258
|
||||
@@ -62,7 +63,17 @@ int nprod = 1; /* number of productions */
|
||||
int *prdptr[NPROD]; /* pointers to descriptions of productions */
|
||||
int levprd[NPROD]; /* precedence levels for the productions */
|
||||
|
||||
setup(argc, argv) int argc;
|
||||
static int defin(int t, char *s);
|
||||
static int gettok(void);
|
||||
static int chfind(int t, char *s);
|
||||
static void cpyunion(void);
|
||||
static void defout(void);
|
||||
static void cpycode(void);
|
||||
static void cpyact(int offset);
|
||||
static void finact(void);
|
||||
static int skipcom(void);
|
||||
|
||||
void setup(argc, argv) int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i, lev, ty;
|
||||
@@ -195,7 +206,8 @@ char *argv[];
|
||||
/* get identifiers so defined */
|
||||
|
||||
t = gettok();
|
||||
if (t == TYPENAME) { /* there is a type defined */
|
||||
if (t == TYPENAME) {
|
||||
/* there is a type defined */
|
||||
ty = numbval;
|
||||
t = gettok();
|
||||
}
|
||||
@@ -370,7 +382,7 @@ char *argv[];
|
||||
|
||||
if (ntypes && !(levprd[nprod] & ACTFLAG) && nontrst[*prdptr[nprod] - NTBASE].tvalue) {
|
||||
/* no explicit action, LHS has value */
|
||||
register tempty;
|
||||
register int tempty;
|
||||
tempty = prdptr[nprod][1];
|
||||
if (tempty < 0)
|
||||
error("must return a value, since LHS has a type");
|
||||
@@ -400,7 +412,7 @@ char *argv[];
|
||||
fclose(finput);
|
||||
}
|
||||
|
||||
finact()
|
||||
void finact()
|
||||
{
|
||||
/* finish action routine */
|
||||
|
||||
@@ -409,12 +421,13 @@ finact()
|
||||
fprintf(ftable, "# define YYERRCODE %d\n", tokset[2].value);
|
||||
}
|
||||
|
||||
defin(t, s) register char *s;
|
||||
/*
|
||||
* define s to be a terminal if t=0
|
||||
* or a nonterminal if t=1
|
||||
*/
|
||||
int defin(t, s) register char *s;
|
||||
{
|
||||
/* define s to be a terminal if t=0
|
||||
or a nonterminal if t=1 */
|
||||
|
||||
register val;
|
||||
register int val;
|
||||
|
||||
if (t) {
|
||||
if (++nnonter >= NNONTERM)
|
||||
@@ -431,7 +444,8 @@ defin(t, s) register char *s;
|
||||
|
||||
if (s[0] == ' ' && s[2] == '\0') /* single character literal */
|
||||
val = s[1];
|
||||
else if (s[0] == ' ' && s[1] == '\\') { /* escape sequence */
|
||||
else if (s[0] == ' ' && s[1] == '\\') {
|
||||
/* escape sequence */
|
||||
if (s[3] == '\0') { /* single character escape sequence */
|
||||
switch (s[2]) {
|
||||
/* character which is escaped */
|
||||
@@ -462,7 +476,8 @@ defin(t, s) register char *s;
|
||||
default:
|
||||
error("invalid escape");
|
||||
}
|
||||
} else if (s[2] <= '7' && s[2] >= '0') { /* \nnn sequence */
|
||||
} else if (s[2] <= '7' && s[2] >= '0') {
|
||||
/* \nnn sequence */
|
||||
if (s[3] < '0' || s[3] > '7' || s[4] < '0' || s[4] > '7' || s[5] != '\0')
|
||||
error("illegal \\nnn construction");
|
||||
val = 64 * s[2] + 8 * s[3] + s[4] - 73 * '0';
|
||||
@@ -477,8 +492,11 @@ defin(t, s) register char *s;
|
||||
return (ntokens);
|
||||
}
|
||||
|
||||
defout()
|
||||
{ /* write out the defines (at the end of the declaration section) */
|
||||
/*
|
||||
* write out the defines (at the end of the declaration section)
|
||||
*/
|
||||
void defout()
|
||||
{
|
||||
|
||||
register int i, c;
|
||||
register char *cp;
|
||||
@@ -520,11 +538,11 @@ register char *s;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
gettok()
|
||||
int gettok()
|
||||
{
|
||||
register i, base;
|
||||
register int i, base;
|
||||
static int peekline; /* number of '\n' seen in lookahead */
|
||||
register c, match, reserve;
|
||||
register int c, match, reserve;
|
||||
|
||||
begin:
|
||||
reserve = 0;
|
||||
@@ -536,7 +554,8 @@ begin:
|
||||
++lineno;
|
||||
c = getc(finput);
|
||||
}
|
||||
if (c == '/') { /* skip comment */
|
||||
if (c == '/') {
|
||||
/* skip comment */
|
||||
lineno += skipcom();
|
||||
goto begin;
|
||||
}
|
||||
@@ -613,7 +632,8 @@ begin:
|
||||
|
||||
default:
|
||||
|
||||
if (isdigit(c)) { /* number */
|
||||
if (isdigit(c)) {
|
||||
/* number */
|
||||
numbval = c - '0';
|
||||
base = (c == '0') ? 8 : 10;
|
||||
for (c = getc(finput); isdigit(c); c = getc(finput)) {
|
||||
@@ -639,7 +659,8 @@ begin:
|
||||
|
||||
tokname[i] = '\0';
|
||||
|
||||
if (reserve) { /* find a reserved word */
|
||||
if (reserve) {
|
||||
/* find a reserved word */
|
||||
if (!strcmp(tokname, "term"))
|
||||
return (TERM);
|
||||
if (!strcmp(tokname, "token"))
|
||||
@@ -669,7 +690,8 @@ begin:
|
||||
while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/') {
|
||||
if (c == '\n')
|
||||
++peekline;
|
||||
else if (c == '/') { /* look for comments */
|
||||
else if (c == '/') {
|
||||
/* look for comments */
|
||||
peekline += skipcom();
|
||||
}
|
||||
c = getc(finput);
|
||||
@@ -680,9 +702,12 @@ begin:
|
||||
return (IDENTIFIER);
|
||||
}
|
||||
|
||||
fdtype(t)
|
||||
{ /* determine the type of a symbol */
|
||||
register v;
|
||||
/*
|
||||
* determine the type of a symbol
|
||||
*/
|
||||
int fdtype(t)
|
||||
{
|
||||
register int v;
|
||||
|
||||
if (t >= NTBASE)
|
||||
v = nontrst[t - NTBASE].tvalue;
|
||||
@@ -694,7 +719,7 @@ fdtype(t)
|
||||
return (v);
|
||||
}
|
||||
|
||||
chfind(t, s) register char *s;
|
||||
int chfind(t, s) register char *s;
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -718,10 +743,11 @@ chfind(t, s) register char *s;
|
||||
return (defin(t, s));
|
||||
}
|
||||
|
||||
cpyunion()
|
||||
/*
|
||||
* copy the union declaration to the output, and the define file if present
|
||||
*/
|
||||
void cpyunion()
|
||||
{
|
||||
/* copy the union declaration to the output, and the define file if present */
|
||||
|
||||
int level, c;
|
||||
fprintf(ftable, "\n# line %d \"%s\"\n", lineno, infile);
|
||||
fprintf(ftable, "typedef union ");
|
||||
@@ -747,7 +773,8 @@ cpyunion()
|
||||
|
||||
case '}':
|
||||
--level;
|
||||
if (level == 0) { /* we are finished copying */
|
||||
if (level == 0) {
|
||||
/* we are finished copying */
|
||||
fprintf(ftable, " YYSTYPE;\n");
|
||||
if (fdefine)
|
||||
fprintf(fdefine, " YYSTYPE;\nextern YYSTYPE yylval;\n");
|
||||
@@ -757,8 +784,11 @@ cpyunion()
|
||||
}
|
||||
}
|
||||
|
||||
cpycode()
|
||||
{ /* copies code between \{ and \} */
|
||||
/*
|
||||
* copies code between \{ and \}
|
||||
*/
|
||||
void cpycode()
|
||||
{
|
||||
register int c;
|
||||
|
||||
c = getc(finput);
|
||||
@@ -768,16 +798,16 @@ cpycode()
|
||||
}
|
||||
fprintf(ftable, "\n# line %d \"%s\"\n", lineno, infile);
|
||||
while (c >= 0) {
|
||||
if (c == '\\')
|
||||
if (c == '\\') {
|
||||
if ((c = getc(finput)) == '}')
|
||||
return;
|
||||
else
|
||||
putc('\\', ftable);
|
||||
if (c == '%')
|
||||
}
|
||||
if (c == '%') {
|
||||
if ((c = getc(finput)) == '}')
|
||||
return;
|
||||
else
|
||||
putc('%', ftable);
|
||||
}
|
||||
putc(c, ftable);
|
||||
if (c == '\n')
|
||||
++lineno;
|
||||
@@ -786,30 +816,38 @@ cpycode()
|
||||
error("eof before %%}");
|
||||
}
|
||||
|
||||
skipcom()
|
||||
{ /* skip over comments */
|
||||
/*
|
||||
* skip over comments
|
||||
*/
|
||||
int skipcom()
|
||||
{
|
||||
register int c, i = 0; /* i is the number of lines skipped */
|
||||
|
||||
/* skipcom is called after reading a / */
|
||||
|
||||
if (getc(finput) != '*')
|
||||
error("illegal comment");
|
||||
|
||||
for (;;) {
|
||||
c = getc(finput);
|
||||
while (c != EOF) {
|
||||
if (c == EOF)
|
||||
error("EOF inside comment");
|
||||
|
||||
while (c == '*') {
|
||||
if ((c = getc(finput)) == '/')
|
||||
return (i);
|
||||
}
|
||||
if (c == '\n')
|
||||
++i;
|
||||
c = getc(finput);
|
||||
}
|
||||
error("EOF inside comment");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
cpyact(offset)
|
||||
{ /* copy C action to the next ; or closing } */
|
||||
/*
|
||||
* copy C action to the next ; or closing }
|
||||
*/
|
||||
void cpyact(offset)
|
||||
{
|
||||
register int c;
|
||||
int brac, match, j, s, tok;
|
||||
|
||||
@@ -836,7 +874,8 @@ swt:
|
||||
s = 1;
|
||||
tok = -1;
|
||||
c = getc(finput);
|
||||
if (c == '<') { /* type description */
|
||||
if (c == '<') {
|
||||
/* type description */
|
||||
ungetc(c, finput);
|
||||
if (gettok() != TYPENAME)
|
||||
error("bad syntax on $<ident> clause");
|
||||
@@ -845,7 +884,8 @@ swt:
|
||||
}
|
||||
if (c == '$') {
|
||||
fprintf(faction, "yyval");
|
||||
if (ntypes) { /* put out the proper tag... */
|
||||
if (ntypes) {
|
||||
/* put out the proper tag... */
|
||||
if (tok < 0)
|
||||
tok = fdtype(*prdptr[nprod]);
|
||||
fprintf(faction, ".%s", typeset[tok]);
|
||||
@@ -869,7 +909,8 @@ swt:
|
||||
}
|
||||
|
||||
fprintf(faction, "yypvt[-%d]", -j);
|
||||
if (ntypes) { /* put out the proper tag */
|
||||
if (ntypes) {
|
||||
/* put out the proper tag */
|
||||
if (j + offset <= 0 && tok < 0)
|
||||
error("must specify type of $%d", j + offset);
|
||||
if (tok < 0)
|
||||
@@ -922,7 +963,7 @@ swt:
|
||||
string:
|
||||
|
||||
putc(c, faction);
|
||||
while (c = getc(finput)) {
|
||||
while ((c = getc(finput))) {
|
||||
if (c == '\\') {
|
||||
putc(c, faction);
|
||||
c = getc(finput);
|
||||
|
||||
@@ -4,28 +4,34 @@
|
||||
int lastred; /* the number of the last reduction of a state */
|
||||
int defact[NSTATES]; /* the default actions of states */
|
||||
|
||||
output()
|
||||
{ /* print the output for the states */
|
||||
static void precftn(int r, int t, int s);
|
||||
static void wract(int i);
|
||||
static void wdef(char *s, int n);
|
||||
static void go2gen(int c);
|
||||
static void wrstate(int i);
|
||||
|
||||
/*
|
||||
* print the output for the states
|
||||
*/
|
||||
void output()
|
||||
{
|
||||
int i, k;
|
||||
register int c;
|
||||
register struct wset *u, *v;
|
||||
|
||||
fprintf(ftable, "short yyexca[] ={\n");
|
||||
|
||||
SLOOP(i)
|
||||
{ /* output the stuff for state i */
|
||||
SLOOP(i) {
|
||||
/* output the stuff for state i */
|
||||
nolook = !(tystate[i] == MUSTLOOKAHEAD);
|
||||
closure(i);
|
||||
/* output actions */
|
||||
nolook = 1;
|
||||
aryfil(temp1, ntokens + nnonter + 1, 0);
|
||||
WSLOOP(wsets, u)
|
||||
{
|
||||
WSLOOP(wsets, u) {
|
||||
c = *(u->pitem);
|
||||
if (c > 1 && c < NTBASE && temp1[c] == 0) {
|
||||
WSLOOP(u, v)
|
||||
{
|
||||
WSLOOP(u, v) {
|
||||
if (c == *(v->pitem))
|
||||
putitem(v->pitem + 1, (struct looksets *)0);
|
||||
}
|
||||
@@ -41,17 +47,17 @@ output()
|
||||
/* now, we have the shifts; look at the reductions */
|
||||
|
||||
lastred = 0;
|
||||
WSLOOP(wsets, u)
|
||||
{
|
||||
WSLOOP(wsets, u) {
|
||||
c = *(u->pitem);
|
||||
if (c <= 0) { /* reduction */
|
||||
if (c <= 0) {
|
||||
/* reduction */
|
||||
lastred = -c;
|
||||
TLOOP(k)
|
||||
{
|
||||
TLOOP(k) {
|
||||
if (BIT(u->ws.lset, k)) {
|
||||
if (temp1[k] == 0)
|
||||
temp1[k] = c;
|
||||
else if (temp1[k] < 0) { /* reduce/reduce conflict */
|
||||
else if (temp1[k] < 0) {
|
||||
/* reduce/reduce conflict */
|
||||
if (foutput != NULL)
|
||||
fprintf(foutput,
|
||||
"\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s", i,
|
||||
@@ -59,7 +65,8 @@ output()
|
||||
if (-temp1[k] > lastred)
|
||||
temp1[k] = -lastred;
|
||||
++zzrrconf;
|
||||
} else { /* potential shift/reduce conflict */
|
||||
} else {
|
||||
/* potential shift/reduce conflict */
|
||||
precftn(lastred, k, i);
|
||||
}
|
||||
}
|
||||
@@ -75,10 +82,14 @@ output()
|
||||
}
|
||||
|
||||
int pkdebug = 0;
|
||||
apack(p, n) int *p;
|
||||
{ /* pack state i from temp1 into amem */
|
||||
|
||||
/*
|
||||
* pack state i from temp1 into amem
|
||||
*/
|
||||
int apack(p, n) int *p;
|
||||
{
|
||||
int off;
|
||||
register *pp, *qq, *rr;
|
||||
register int *pp, *qq, *rr;
|
||||
int *q, *r;
|
||||
|
||||
/* we don't need to worry about checking because we
|
||||
@@ -96,7 +107,8 @@ apack(p, n) int *p;
|
||||
/* now, find a place for the elements from p to q, inclusive */
|
||||
|
||||
r = &amem[ACTSIZE - 1];
|
||||
for (rr = amem; rr <= r; ++rr, ++off) { /* try rr */
|
||||
for (rr = amem; rr <= r; ++rr, ++off) {
|
||||
/* try rr */
|
||||
for (qq = rr, pp = p; pp <= q; ++pp, ++qq) {
|
||||
if (*pp != 0) {
|
||||
if (*pp != *qq && *qq != 0)
|
||||
@@ -132,10 +144,14 @@ apack(p, n) int *p;
|
||||
}
|
||||
error("no space in action table");
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
go2out()
|
||||
{ /* output the gotos for the nontermninals */
|
||||
/*
|
||||
* output the gotos for the nontermninals
|
||||
*/
|
||||
void go2out()
|
||||
{
|
||||
register int i, j, k;
|
||||
int best, count, cbest, times;
|
||||
|
||||
@@ -149,7 +165,8 @@ go2out()
|
||||
best = -1;
|
||||
times = 0;
|
||||
|
||||
for (j = 0; j <= nstate; ++j) { /* is j the most frequent */
|
||||
for (j = 0; j <= nstate; ++j) {
|
||||
/* is j the most frequent */
|
||||
if (tystate[j] == 0)
|
||||
continue;
|
||||
if (tystate[j] == best)
|
||||
@@ -188,9 +205,12 @@ go2out()
|
||||
}
|
||||
|
||||
int g2debug = 0;
|
||||
go2gen(c)
|
||||
{ /* output the gotos for nonterminal c */
|
||||
|
||||
/*
|
||||
* output the gotos for nonterminal c
|
||||
*/
|
||||
void go2gen(c)
|
||||
{
|
||||
register int i, cc;
|
||||
int work;
|
||||
struct item *p, *q;
|
||||
@@ -203,9 +223,9 @@ go2gen(c)
|
||||
work = 1;
|
||||
while (work) {
|
||||
work = 0;
|
||||
PLOOP(0, i)
|
||||
{
|
||||
if ((cc = prdptr[i][1] - NTBASE) >= 0) { /* cc is a nonterminal */
|
||||
PLOOP(0, i) {
|
||||
if ((cc = prdptr[i][1] - NTBASE) >= 0) {
|
||||
/* cc is a nonterminal */
|
||||
if (temp1[cc] != 0) { /* cc has a goto on c */
|
||||
cc = *prdptr[i] - NTBASE; /* thus, the left side of production i does too */
|
||||
if (temp1[cc] == 0) {
|
||||
@@ -221,19 +241,21 @@ go2gen(c)
|
||||
|
||||
if (g2debug && foutput != NULL) {
|
||||
fprintf(foutput, "%s: gotos on ", nontrst[c].name);
|
||||
NTLOOP(i) if (temp1[i]) fprintf(foutput, "%s ", nontrst[i].name);
|
||||
NTLOOP(i) {
|
||||
if (temp1[i])
|
||||
fprintf(foutput, "%s ", nontrst[i].name);
|
||||
}
|
||||
fprintf(foutput, "\n");
|
||||
}
|
||||
|
||||
/* now, go through and put gotos into tystate */
|
||||
|
||||
aryfil(tystate, nstate, 0);
|
||||
SLOOP(i)
|
||||
{
|
||||
ITMLOOP(i, p, q)
|
||||
{
|
||||
SLOOP(i) {
|
||||
ITMLOOP(i, p, q) {
|
||||
if ((cc = *p->pitem) >= NTBASE) {
|
||||
if (temp1[cc -= NTBASE]) { /* goto on c is possible */
|
||||
if (temp1[cc -= NTBASE]) {
|
||||
/* goto on c is possible */
|
||||
tystate[i] = amem[indgo[i] + c];
|
||||
break;
|
||||
}
|
||||
@@ -242,12 +264,14 @@ go2gen(c)
|
||||
}
|
||||
}
|
||||
|
||||
precftn(r, t, s) register int t;
|
||||
{ /* decide a shift/reduce conflict by precedence.
|
||||
/* r is a rule number, t a token number */
|
||||
/* the conflict is in state s */
|
||||
/* temp1[t] is changed to reflect the action */
|
||||
|
||||
/*
|
||||
* decide a shift/reduce conflict by precedence.
|
||||
* r is a rule number, t a token number
|
||||
* the conflict is in state s
|
||||
* temp1[t] is changed to reflect the action
|
||||
*/
|
||||
void precftn(r, t, s) register int t;
|
||||
{
|
||||
int lp, lt, action;
|
||||
|
||||
lp = levprd[r];
|
||||
@@ -278,8 +302,11 @@ precftn(r, t, s) register int t;
|
||||
}
|
||||
}
|
||||
|
||||
wract(i) register int i;
|
||||
{ /* output state i */
|
||||
/*
|
||||
* output state i
|
||||
*/
|
||||
void wract(i) register int i;
|
||||
{
|
||||
/* temp1 has the actions, lastred the default */
|
||||
int p, p0, p1;
|
||||
int ntimes, tred, count;
|
||||
@@ -290,8 +317,7 @@ wract(i) register int i;
|
||||
|
||||
lastred = 0;
|
||||
ntimes = 0;
|
||||
TLOOP(j)
|
||||
{
|
||||
TLOOP(j) {
|
||||
if (temp1[j] >= 0)
|
||||
continue;
|
||||
if (temp1[j] + lastred == 0)
|
||||
@@ -300,8 +326,7 @@ wract(i) register int i;
|
||||
count = 0;
|
||||
tred = -temp1[j];
|
||||
levprd[tred] |= REDFLAG;
|
||||
TLOOP(p)
|
||||
{
|
||||
TLOOP(p) {
|
||||
if (temp1[p] + tred == 0)
|
||||
++count;
|
||||
}
|
||||
@@ -312,19 +337,21 @@ wract(i) register int i;
|
||||
}
|
||||
|
||||
/* for error recovery, arrange that, if there is a shift on the
|
||||
/* error recovery token, `error', that the default be the error action */
|
||||
* error recovery token, `error', that the default be the error action */
|
||||
if (temp1[1] > 0)
|
||||
lastred = 0;
|
||||
|
||||
/* clear out entries in temp1 which equal lastred */
|
||||
TLOOP(p) if (temp1[p] + lastred == 0) temp1[p] = 0;
|
||||
TLOOP(p) {
|
||||
if (temp1[p] + lastred == 0)
|
||||
temp1[p] = 0;
|
||||
}
|
||||
|
||||
wrstate(i);
|
||||
defact[i] = lastred;
|
||||
|
||||
flag = 0;
|
||||
TLOOP(p0)
|
||||
{
|
||||
TLOOP(p0) {
|
||||
if ((p1 = temp1[p0]) != 0) {
|
||||
if (p1 < 0) {
|
||||
p1 = -p1;
|
||||
@@ -354,20 +381,24 @@ wract(i) register int i;
|
||||
return;
|
||||
}
|
||||
|
||||
wrstate(i)
|
||||
{ /* writes state i */
|
||||
register j0, j1;
|
||||
/*
|
||||
* writes state i
|
||||
*/
|
||||
void wrstate(i)
|
||||
{
|
||||
register int j0, j1;
|
||||
register struct item *pp, *qq;
|
||||
register struct wset *u;
|
||||
|
||||
if (foutput == NULL)
|
||||
return;
|
||||
fprintf(foutput, "\nstate %d\n", i);
|
||||
ITMLOOP(i, pp, qq) fprintf(foutput, "\t%s\n", writem(pp->pitem));
|
||||
ITMLOOP(i, pp, qq) {
|
||||
fprintf(foutput, "\t%s\n", writem(pp->pitem));
|
||||
}
|
||||
if (tystate[i] == MUSTLOOKAHEAD) {
|
||||
/* print out empty productions in closure */
|
||||
WSLOOP(wsets + (pstate[i + 1] - pstate[i]), u)
|
||||
{
|
||||
WSLOOP(wsets + (pstate[i + 1] - pstate[i]), u) {
|
||||
if (*(u->pitem) < 0)
|
||||
fprintf(foutput, "\t%s\n", writem(u->pitem));
|
||||
}
|
||||
@@ -375,10 +406,11 @@ wrstate(i)
|
||||
|
||||
/* check for state equal to another */
|
||||
|
||||
TLOOP(j0) if ((j1 = temp1[j0]) != 0)
|
||||
{
|
||||
TLOOP(j0) {
|
||||
if ((j1 = temp1[j0]) != 0) {
|
||||
fprintf(foutput, "\n\t%s ", symnam(j0));
|
||||
if (j1 > 0) { /* shift, error, or accept */
|
||||
if (j1 > 0) {
|
||||
/* shift, error, or accept */
|
||||
if (j1 == ACCEPTCODE)
|
||||
fprintf(foutput, "accept");
|
||||
else if (j1 == ERRCODE)
|
||||
@@ -388,6 +420,7 @@ wrstate(i)
|
||||
} else
|
||||
fprintf(foutput, "reduce %d", -j1);
|
||||
}
|
||||
}
|
||||
|
||||
/* output the final production */
|
||||
|
||||
@@ -405,15 +438,19 @@ wrstate(i)
|
||||
}
|
||||
}
|
||||
|
||||
wdef(s, n) char *s;
|
||||
{ /* output a definition of s to the value n */
|
||||
/*
|
||||
* output a definition of s to the value n
|
||||
*/
|
||||
void wdef(s, n) char *s;
|
||||
{
|
||||
fprintf(ftable, "# define %s %d\n", s, n);
|
||||
}
|
||||
|
||||
warray(s, v, n) char *s;
|
||||
void warray(s, v, n)
|
||||
char *s;
|
||||
int *v, n;
|
||||
{
|
||||
register i;
|
||||
register int i;
|
||||
|
||||
fprintf(ftable, "short %s[]={\n", s);
|
||||
for (i = 0; i < n;) {
|
||||
@@ -427,20 +464,19 @@ int *v, n;
|
||||
}
|
||||
}
|
||||
|
||||
hideprod()
|
||||
void hideprod()
|
||||
{
|
||||
/* in order to free up the mem and amem arrays for the optimizer,
|
||||
/* and still be able to output yyr1, etc., after the sizes of
|
||||
/* the action array is known, we hide the nonterminals
|
||||
/* derived by productions in levprd.
|
||||
* and still be able to output yyr1, etc., after the sizes of
|
||||
* the action array is known, we hide the nonterminals
|
||||
* derived by productions in levprd.
|
||||
*/
|
||||
|
||||
register i, j;
|
||||
register int i, j;
|
||||
|
||||
j = 0;
|
||||
levprd[0] = 0;
|
||||
PLOOP(1, i)
|
||||
{
|
||||
PLOOP(1, i) {
|
||||
if (!(levprd[i] & REDFLAG)) {
|
||||
++j;
|
||||
if (foutput != NULL) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "dextern.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#define a amem
|
||||
#define mem mem0
|
||||
@@ -20,9 +21,17 @@ int *maxa;
|
||||
int nxdb = 0;
|
||||
int adb = 0;
|
||||
|
||||
callopt()
|
||||
static int gtnm(void);
|
||||
static int nxti(void);
|
||||
static void stin(int i);
|
||||
static void gin(int i);
|
||||
static void aoutput(void);
|
||||
static void osummary(void);
|
||||
static void arout(char *s, int *v, int n);
|
||||
|
||||
void callopt()
|
||||
{
|
||||
register i, *p, j, k, *q;
|
||||
register int i, *p, j, k, *q;
|
||||
|
||||
/* read the arrays from tempfile and set parameters */
|
||||
|
||||
@@ -79,9 +88,10 @@ callopt()
|
||||
if (*p < k)
|
||||
k = *p;
|
||||
}
|
||||
if (k <= j) { /* nontrivial situation */
|
||||
/* temporarily, kill this for compatibility
|
||||
j -= k; /* j is now the range */
|
||||
if (k <= j) {
|
||||
/* nontrivial situation */
|
||||
/* temporarily, kill this for compatibility */
|
||||
// j -= k; /* j is now the range */
|
||||
if (k > maxoff)
|
||||
maxoff = k;
|
||||
}
|
||||
@@ -126,7 +136,8 @@ callopt()
|
||||
gin(-i);
|
||||
}
|
||||
|
||||
if (adb > 2) { /* print a array */
|
||||
if (adb > 2) {
|
||||
/* print a array */
|
||||
for (p = a; p <= maxa; p += 10) {
|
||||
fprintf(ftable, "%4d ", p - a);
|
||||
for (i = 0; i < 10; ++i)
|
||||
@@ -142,9 +153,9 @@ callopt()
|
||||
ZAPFILE(TEMPNAME);
|
||||
}
|
||||
|
||||
gin(i)
|
||||
void gin(i)
|
||||
{
|
||||
register *p, *r, *s, *q1, *q2;
|
||||
register int *p, *r, *s, *q1, *q2;
|
||||
|
||||
/* enter gotos on nonterminal i into array a */
|
||||
|
||||
@@ -192,9 +203,9 @@ gin(i)
|
||||
nextgi:;
|
||||
}
|
||||
|
||||
stin(i)
|
||||
void stin(i)
|
||||
{
|
||||
register *r, *s, n, flag, j, *q1, *q2;
|
||||
register int *r, *s, n, flag, j, *q1, *q2;
|
||||
|
||||
greed[i] = 0;
|
||||
|
||||
@@ -252,9 +263,12 @@ stin(i)
|
||||
error("Error; failure to place state %d\n", i);
|
||||
}
|
||||
|
||||
nxti()
|
||||
{ /* finds the next i */
|
||||
register i, max, maxi;
|
||||
/*
|
||||
* finds the next i
|
||||
*/
|
||||
int nxti()
|
||||
{
|
||||
register int i, max, maxi;
|
||||
|
||||
max = 0;
|
||||
|
||||
@@ -278,11 +292,11 @@ nxti()
|
||||
return (maxi);
|
||||
}
|
||||
|
||||
osummary()
|
||||
void osummary()
|
||||
{
|
||||
/* write summary */
|
||||
|
||||
register i, *p;
|
||||
register int i, *p;
|
||||
|
||||
if (foutput == NULL)
|
||||
return;
|
||||
@@ -298,11 +312,12 @@ osummary()
|
||||
fprintf(foutput, "maximum spread: %d, maximum offset: %d\n", maxspr, maxoff);
|
||||
}
|
||||
|
||||
aoutput()
|
||||
{ /* this version is for C */
|
||||
|
||||
/* write out the optimized parser */
|
||||
|
||||
/*
|
||||
* this version is for C
|
||||
* write out the optimized parser
|
||||
*/
|
||||
void aoutput()
|
||||
{
|
||||
fprintf(ftable, "# define YYLAST %d\n", maxa - a + 1);
|
||||
|
||||
arout("yyact", a, (maxa - a) + 1);
|
||||
@@ -310,10 +325,10 @@ aoutput()
|
||||
arout("yypgo", pgo, nnonter + 1);
|
||||
}
|
||||
|
||||
arout(s, v, n) char *s;
|
||||
void arout(s, v, n) char *s;
|
||||
int *v, n;
|
||||
{
|
||||
register i;
|
||||
register int i;
|
||||
|
||||
fprintf(ftable, "short %s[]={\n", s);
|
||||
for (i = 0; i < n;) {
|
||||
@@ -327,9 +342,9 @@ int *v, n;
|
||||
}
|
||||
}
|
||||
|
||||
gtnm()
|
||||
int gtnm()
|
||||
{
|
||||
register s, val, c;
|
||||
register int s, val, c;
|
||||
|
||||
/* read and convert an integer from the standard input */
|
||||
/* return the terminating character */
|
||||
|
||||
Reference in New Issue
Block a user