diff options
Diffstat (limited to 'unix/boot/xyacc/y1.c')
-rw-r--r-- | unix/boot/xyacc/y1.c | 1307 |
1 files changed, 1307 insertions, 0 deletions
diff --git a/unix/boot/xyacc/y1.c b/unix/boot/xyacc/y1.c new file mode 100644 index 00000000..58f2f945 --- /dev/null +++ b/unix/boot/xyacc/y1.c @@ -0,0 +1,1307 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1988 AT&T */ +/* All Rights Reserved */ + +//#pragma ident "%Z%%M% %I% %E% SMI" + +#include "dextern.h" +#include <sys/param.h> +#include <sys/errno.h> +#include <unistd.h> +#include <locale.h> +#include <stdarg.h> /* For error() */ + +static void mktbls (void); +static void others (void); +static void summary (void); +static char *chcopy (char *, char *); +static int setunion (int *, int *); +static void prlook (LOOKSETS *); +static void cpres (void); +static void cpfir (void); +static void cempty (void); +static void stagen (void); +static LOOKSETS *flset (LOOKSETS *); +static void exp_lkst (void); +static void exp_wsets (void); +static void exp_states (void); +static void exp_psmem (void); + + /* lookahead computations */ + +int TBITSET; +static int tbitset; /* size of lookahead sets */ +LOOKSETS *lkst; +static int lsetsize; + +static int nlset = 0; /* next lookahead set index */ +int nolook = 0; /* flag to suppress lookahead computations */ +static LOOKSETS clset; /* temporary storage for lookahead computations */ + +static ITEM *psmem, *zzmemsz; +static int new_pstsize = PSTSIZE; + + /* I/O descriptors */ + +extern FILE *finput; /* input file */ +extern FILE *faction; /* file for saving actions */ +extern FILE *fdefine; /* file for #defines */ +extern FILE *fudecl; /* file for user declarations */ +extern FILE *ftable; /* parser tables file */ +extern FILE *fsppout; /* SPP output file */ +extern FILE *ftemp; /* tempfile to pass 2 */ +extern FILE *foutput; /* y.output file */ + + /* working set computations */ + +WSET *wsets; +int cwp; +static int wsetsz = 0; /* number of WSET items in wsets block */ + + /* state information */ + +int nstate = 0; /* number of states */ +static int nstatesz = NSTATES; /* number of state space allocated */ +ITEM **pstate; /* ptr to descriptions of the states */ +int *tystate; /* contains type info about the states */ +int *indgo; /* index to the stored goto table */ +static int *tmp_lset; +static int *tstates; /* states generated by terminal gotos */ +static int *ntstates; /* states generated by non-term gotos */ +static int *mstates; /* chain of overflows of term/nonterm */ + /* generation lists */ + + /* storage for the actions in the parser */ + +int *amem, *memp; /* next free action table position */ +int new_actsize = ACTSIZE; + + /* other storage areas */ + +int *temp1; /* temp storate, indexed by terms+ntokens or states */ +int lineno = 0; /* current input line number */ +int size; +static int fatfl = 1; /* if on, error is fatal */ +static int nerrors = 0; /* number of errors */ + + /* storage for information about the nonterminals */ + +static int ***pres; /* vector of pointers to productions */ + /* yielding each nonterminal */ +static LOOKSETS **pfirst; /* vector of pointers to first sets for */ + /* each nonterminal */ +static int *pempty; /* vector of nonterminals nontrivially */ + /* deriving e */ +extern int nprodsz; + +int +main (int argc, char *argv[]) +{ + (void) setlocale (LC_ALL, ""); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ +#endif + /* + (void) textdomain (TEXT_DOMAIN); + */ + + setup (argc, argv); /* initialize and read productions */ + TBITSET = NWORDS (ntoksz * LKFACTOR); + tbitset = NWORDS (ntokens * LKFACTOR); + mktbls (); + cpres (); /* make table of which productions yield a */ + /* given nonterminal */ + cempty (); /* make a table of which nonterminals can match */ + /* the empty string */ + cpfir (); /* make a table of firsts of nonterminals */ + stagen (); /* generate the states */ + output (); /* write the states and the tables */ + go2out (); + hideprod (); + summary (); + callopt (); + others (); + return (0); +} + + +static void +mktbls () +{ + int i; + + size = ntoksz + nnontersz + 1; + if (size < nstatesz) + size = nstatesz; + if (size < new_memsize) + size = new_memsize; + + amem = (int *) malloc (sizeof (int) * new_actsize); + psmem = (ITEM *) malloc (sizeof (ITEM) * new_pstsize); + if ((psmem == NULL) || (amem == NULL)) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * This error happens when yacc could not allocate + * initial memory to be used for internal tables. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("couldn't allocate initial table"); + zzmemsz = psmem; + memp = amem; + + /* + * For lkst + */ +#define INIT_LSIZE nnontersz*LKFACTOR + tmp_lset = (int *) + calloc ((size_t) (TBITSET * (INIT_LSIZE + 1)), sizeof (int)); + if (tmp_lset == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Yacc could not allocate memory for table named lookset. + * Do not translate 'lookset'. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("could not allocate lookset array"); + lkst = (LOOKSETS *) malloc (sizeof (LOOKSETS) * (INIT_LSIZE + 1)); + for (i = 0; i <= INIT_LSIZE; ++i) + lkst[i].lset = tmp_lset + TBITSET * i; + tmp_lset = NULL; + + /* + * For wsets + */ + tmp_lset = (int *) + calloc ((size_t) (TBITSET * (nnontersz + 1)), sizeof (int)); + if (tmp_lset == NULL) + error ("could not allocate lookset array"); + wsets = (WSET *) malloc (sizeof (WSET) * (nnontersz + 1)); + for (i = 0; i <= nnontersz; ++i) + wsets[i].ws.lset = tmp_lset + TBITSET * i; + tmp_lset = NULL; + + clset.lset = (int *) malloc (sizeof (int) * TBITSET); + tstates = (int *) malloc (sizeof (int) * (ntoksz + 1)); + ntstates = (int *) malloc (sizeof (int) * (nnontersz + 1)); + temp1 = (int *) malloc (sizeof (int) * size); + pres = (int ***) malloc (sizeof (int **) * (nnontersz + 2)); + pfirst = (LOOKSETS **) malloc (sizeof (LOOKSETS *) * (nnontersz + 2)); + pempty = (int *) malloc (sizeof (int) * (nnontersz + 1)); + + pstate = (ITEM **) malloc (sizeof (ITEM *) * (nstatesz + 2)); + tystate = (int *) malloc (sizeof (int) * nstatesz); + indgo = (int *) malloc (sizeof (int) * nstatesz); + mstates = (int *) malloc (sizeof (int) * nstatesz); + defact = (int *) malloc (sizeof (int) * nstatesz); + + if ((lkst == NULL) || (wsets == NULL) || (tstates == NULL) || + (ntstates == NULL) || (temp1 == NULL) || (pres == NULL) || + (pfirst == NULL) || (pempty == NULL) || (pstate == NULL) || + (tystate == NULL) || (indgo == NULL) || (mstates == NULL) || + (defact == NULL) || (clset.lset == NULL)) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Do not translate mktbls(). It is a function name. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("cannot allocate tables in mktbls()"); + + aryfil (ntstates, nnontersz + 1, 0); + aryfil (tstates, ntoksz + 1, 0); + wsetsz = nnontersz + 1; + lsetsize = INIT_LSIZE + 1; +} + +/* put out other arrays, copy the parsers */ +static void +others () +{ + extern int gen_lines; + int c, i, j; + int tmpline; + + finput = fopen (parser, "r"); + if (finput == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * This error message is issued when yacc can not find + * the parser to be copied. + */ + error ("cannot find parser %s", parser); + + warray ("yyr1", levprd, nprod); + + aryfil (temp1, nprod, 0); + /* had_act[i] is either 1 or 0 */ +/* original + PLOOP(1, i) + temp1[i] = ((prdptr[i+1] - prdptr[i]-2) << 1) | had_act[i]; +*/ + PLOOP (1, i) temp1[i] = prdptr[i + 1] - prdptr[i] - 2; + + warray ("yyr2", temp1, nprod); + + aryfil (temp1, nstate, -1000); + TLOOP (i) for (j = tstates[i]; j != 0; j = mstates[j]) + temp1[j] = tokset[i].value; + NTLOOP (i) for (j = ntstates[i]; j != 0; j = mstates[j]) + temp1[j] = -i; + warray ("yychk", temp1, nstate); + warray ("yydef", defact, nstate); + + fclose (ftable); + fclose (fudecl); + + if ((fdebug = fopen (DEBUGNAME, "r")) == NULL) + error ("cannot open yacc.debug"); + while ((c = getc (fdebug)) != EOF) + (void) putc (c, fsppout); + (void) fclose (fdebug); + ZAPFILE (DEBUGNAME); + + if (gen_lines) + (void) fprintf (fsppout, "# line\t1 \"%s\"\n", parser); + tmpline = 1; + /* copy parser text */ + while ((c = getc (finput)) != EOF) { + if (c == '\n') + tmpline++; + if (c == '$') { + if ((c = getc (finput)) == 'A') { + /* Replace $A macro by the user declarations. + */ + fudecl = fopen (UDFILE, "r"); + if (fudecl == NULL) + error ("cannot reopen user declarations tempfile"); + while ((c = getc (fudecl)) != EOF) + putc (c, fsppout); + fclose (fudecl); + ZAPFILE (UDFILE); + /* Skip remainder of line following macro. + */ + while ((c = getc (finput)) != '\n' && c != EOF); + + } else if (c == 'B') { + /* Replace $B macro by the parser tables. + */ + ftable = fopen (TABFILE, "r"); + if (ftable == NULL) + error ("cannot reopen parser tables tempfile"); + while ((c = getc (ftable)) != EOF) + putc (c, fsppout); + fclose (ftable); + ZAPFILE (TABFILE); + /* Skip remainder of line following macro. + */ + while ((c = getc (finput)) != '\n' && c != EOF); + + } else if (c == 'C') { + /* Replace $C macro by user-supplied actions. + */ + faction = fopen (ACTNAME, "r"); + if (faction == NULL) + error ("cannot reopen action tempfile"); + while ((c = getc (faction)) != EOF) + putc (c, fsppout); + fclose (faction); + ZAPFILE (ACTNAME); + /* Skip remainder of line following macro. + */ + while ((c = getc (finput)) != '\n' && c != EOF); + + } else { + putc ('$', fsppout); + putc (c, fsppout); + } + + } else + putc (c, fsppout); + } + + fclose (fsppout); +} + + +/* copies string q into p, returning next free char ptr */ +static char * +chcopy (p, q) + char *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; +{ + int i, *p; + static int isize = ISIZE; + static char *sarr = NULL; + char *q; + + if (sarr == NULL) { + sarr = (char *) malloc (sizeof (char) * isize); + if (sarr == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * This error is issued when yacc could not allocate + * memory for internally used array. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("could not allocate output string array"); + for (i = 0; i < isize; ++i) + sarr[i] = ' '; + } + for (p = pp; *p > 0; ++p) /* NULL */ + ; + p = prdptr[-*p]; + q = chcopy (sarr, nontrst[*p - NTBASE].name); + q = chcopy (q, " : "); + + for (;;) { + *q++ = ++p == pp ? '_' : ' '; + *q = 0; + if ((i = *p) <= 0) + break; + q = chcopy (q, symnam (i)); + while (q > &sarr[isize - 30]) { + static char *sarrbase; + + sarrbase = sarr; + isize += ISIZE; + sarr = (char *) + realloc ((char *) sarr, sizeof (*sarr) * isize); + if (sarr == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * This error is issued when yacc could not allocate + * memory for internally used array. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("cannot expand sarr arrays"); + q = q - sarrbase + sarr; + } + } + + /* an item calling for a reduction */ + if ((i = *pp) < 0) { + q = chcopy (q, " ("); + (void) sprintf (q, "%d)", -i); + } + return (sarr); +} + +/* return a pointer to the name of symbol i */ +char * +symnam (int i) +{ + char *cp; + + cp = (i >= NTBASE) ? nontrst[i - NTBASE].name : tokset[i].name; + if (*cp == ' ') + ++cp; + return (cp); +} + +static int zzcwp = 0; +static int zzclose = 0; +int zzgoent = 0; +int zzgobest = 0; +int zzacent = 0; +int zzexcp = 0; +int zzsrconf = 0; +int zzrrconf = 0; + +/* output the summary on the tty */ +static void +summary () +{ + if (foutput != NULL) { + (void) fprintf (foutput, + "\n%d/%d terminals, %d/%d nonterminals\n", + ntokens, ntoksz, nnonter, nnontersz); + (void) fprintf (foutput, + "%d/%d grammar rules, %d/%d states\n", + nprod, nprodsz, nstate, nstatesz); + (void) fprintf (foutput, + "%d shift/reduce, %d reduce/reduce conflicts reported\n", + zzsrconf, zzrrconf); + (void) fprintf (foutput, "%d/%d working sets used\n", zzcwp, wsetsz); + (void) fprintf (foutput, + "memory: states,etc. %" PRIdPTR + "/%d, parser %" PRIdPTR "/%d\n", + mem - tracemem, new_memsize, + memp - amem, new_actsize); + (void) fprintf (foutput, + "%d/%d distinct lookahead sets\n", nlset, lsetsize); + (void) fprintf (foutput, "%d extra closures\n", zzclose - 2 * nstate); + (void) fprintf (foutput, + "%d shift entries, %d exceptions\n", zzacent, zzexcp); + (void) fprintf (foutput, "%d goto entries\n", zzgoent); + (void) fprintf (foutput, + "%d entries saved by goto default\n", zzgobest); + } + if (zzsrconf != 0 || zzrrconf != 0) { +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * You may just leave this message un-translated. + * This message only makes sense to those who knows + * how yacc works, and the person should know what + * this message means in English. + */ + (void) fprintf (stderr, "\nconflicts: "); + if (zzsrconf) + (void) fprintf (stderr, "%d shift/reduce", zzsrconf); + if (zzsrconf && zzrrconf) + (void) fprintf (stderr, ", "); + if (zzrrconf) + (void) fprintf (stderr, "%d reduce/reduce", zzrrconf); + (void) fprintf (stderr, "\n"); + } + + if (ftemp != NULL) + (void) fclose (ftemp); + if (fdefine != NULL) + (void) fclose (fdefine); +} + +/* write out error comment */ +/*PRINTFLIKE1*/ +void +error (char *s, ...) +{ + extern char *infile; + va_list ap; + + va_start (ap, s); + + ++nerrors; + if (!lineno) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is a prefix to the error messages + * passed to error() function. + */ + (void) fprintf (stderr, "command line: fatal: "); + else { + (void) fprintf (stderr, "\"%s\", ", infile); +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is a prefix to the error messages + * passed to error() function. + */ + (void) fprintf (stderr, "line %d: fatal: ", lineno); + } + (void) vfprintf (stderr, s, ap); + (void) fprintf (stderr, "\n"); + va_end (ap); + if (!fatfl) + return; + summary (); + exit (1); +} + +/* + * Print out a warning message. + */ +/*PRINTFLIKE2*/ +void +warning (int flag, char *s, ...) +{ + extern char *infile; + va_list ap; + va_start (ap, s); + + (void) fprintf (stderr, "\"%s\", ", infile); + /* + * If flag, print lineno as well. + */ + if (flag == 0) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is a prefix to the warning messages + * passed to warning() function. + */ + (void) fprintf (stderr, "warning: "); + else +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is a prefix to the warning messages + * passed to warning() function. + */ + (void) fprintf (stderr, "line %d: warning: ", lineno); + (void) vfprintf (stderr, s, ap); + (void) fprintf (stderr, "\n"); + va_end (ap); +} + +/* set elements 0 through n-1 to c */ +void +aryfil (v, n, c) + int *v, n, c; +{ + int i; + for (i = 0; i < n; ++i) + v[i] = c; +} + +/* set a to the union of a and b */ +/* return 1 if b is not a subset of a, 0 otherwise */ +static int +setunion (a, b) + int *a, *b; +{ + int i, x, sub; + + sub = 0; + SETLOOP (i) { + *a = (x = *a) | *b++; + if (*a++ != x) + sub = 1; + } + return (sub); +} + +static void +prlook (p) + LOOKSETS *p; +{ + int j, *pp; + pp = p->lset; + if (pp == 0) + (void) fprintf (foutput, "\tNULL"); + else { + (void) fprintf (foutput, " { "); + TLOOP (j) { + if (BIT (pp, j)) + (void) fprintf (foutput, WSFMT ("%s "), symnam (j)); + } + (void) fprintf (foutput, "}"); + } +} + +/* + * 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 + */ +static void +cpres () +{ + int **ptrpy; + int **pyield; + int c, j, i; + + /* + * 2/29/88 - + * nprodsz is the size of the tables describing the productions. + * Normally this will be NPROD unless the production tables have + * been expanded, in which case the tables will be NPROD * N(where + * N is the number of times the tables had to be expanded.) + */ + if ((pyield = (int **) malloc (sizeof (int *) * nprodsz)) == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * This error is issued when yacc could not allocate + * memory for internally used array. + * + * pyield is name of an array. You should not try to translate + * this word. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("cannot allocate space for pyield array"); + + ptrpy = pyield; + + NTLOOP (i) { + c = i + NTBASE; + pres[i] = ptrpy; + fatfl = 0; /* make undefined symbols nonfatal */ + PLOOP (0, j) { + if (*prdptr[j] == c) /* linear search for all c's */ + *ptrpy++ = prdptr[j] + 1; + } + if (pres[i] == ptrpy) { /* c not found */ +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Ask somebody who knows yacc how to translate nonterminal or + * look at translated yacc document. + */ + error ("undefined nonterminal: %s", nontrst[i].name); + } + } + pres[i] = ptrpy; + fatfl = 1; + if (nerrors) { + summary (); + exit (1); + } + if (ptrpy != &pyield[nprod]) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * This is an internal error message. + * Very little use to user. You may leave it + * un-translated. + * + * pyied is name of an array. Do not translate it. + */ + error ("internal Yacc error: pyield %d", ptrpy - &pyield[nprod]); +} + +static int indebug = 0; +/* compute an array with the first of nonterminals */ +static void +cpfir () +{ + int *p, **s, i, **t, ch, changes; + + zzcwp = nnonter; + NTLOOP (i) { + aryfil (wsets[i].ws.lset, tbitset, 0); + t = pres[i + 1]; + /* initially fill the sets */ + for (s = pres[i]; s < t; ++s) { + /* check if ch is non-terminal */ + for (p = *s; (ch = *p) > 0; ++p) { + if (ch < NTBASE) { /* should be token */ + SETBIT (wsets[i].ws.lset, ch); + break; + } else if (!pempty[ch - NTBASE]) + break; + } + } + } + + /* now, reflect transitivity */ + + changes = 1; + while (changes) { + changes = 0; + NTLOOP (i) { + t = pres[i + 1]; + for (s = pres[i]; s < t; ++s) { + for (p = *s; (ch = (*p - NTBASE)) >= 0; ++p) { + changes |= setunion (wsets[i].ws.lset, wsets[ch].ws.lset); + if (!pempty[ch]) + break; + } + } + } + } + + NTLOOP (i) pfirst[i] = flset (&wsets[i].ws); + if (!indebug) + return; + if ((foutput != NULL)) { + NTLOOP (i) { + (void) fprintf (foutput, WSFMT ("\n%s: "), nontrst[i].name); + prlook (pfirst[i]); + (void) fprintf (foutput, " %d\n", pempty[i]); + } + } +} + +/* sorts last state,and sees if it equals earlier ones. returns state number */ +int +state (int c) +{ + int size1, size2; + int i; + 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 (l = k - 1; l >= p1; --l) + if (l->pitem > k->pitem) { + int *s; + LOOKSETS *ss; + s = k->pitem; + k->pitem = l->pitem; + l->pitem = s; + ss = k->look; + k->look = l->look; + l->look = ss; + } + } + size1 = p2 - p1; /* size of state */ + + for (i = (c >= NTBASE) ? ntstates[c - NTBASE] : tstates[c]; + i != 0; i = mstates[i]) { + /* get ith state */ + q1 = pstate[i]; + q2 = pstate[i + 1]; + size2 = q2 - q1; + if (size1 != size2) + continue; + k = p1; + for (l = q1; l < q2; l++) { + if (l->pitem != k->pitem) + break; + ++k; + } + if (l != q2) + continue; + /* found it */ + pstate[nstate + 1] = pstate[nstate]; /* delete last state */ + /* fix up lookaheads */ + if (nolook) + return (i); + for (l = q1, k = p1; l < q2; ++l, ++k) { + int s; + SETLOOP (s) clset.lset[s] = l->look->lset[s]; + if (setunion (clset.lset, k->look->lset)) { + tystate[i] = MUSTDO; + /* register the new set */ + l->look = flset (&clset); + } + } + return (i); + } + /* state is new */ + if (nolook) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * You may leave this untranslated. Leave + * state/nolook un-translated. + */ + error ("yacc state/nolook error"); + pstate[nstate + 2] = p2; + if (nstate + 1 >= nstatesz) + exp_states (); + if (c >= NTBASE) { + mstates[nstate] = ntstates[c - NTBASE]; + ntstates[c - NTBASE] = nstate; + } else { + mstates[nstate] = tstates[c]; + tstates[c] = nstate; + } + tystate[nstate] = MUSTDO; + return (nstate++); +} + +static int pidebug = 0; + +void +putitem (ptr, lptr) + int *ptr; + LOOKSETS *lptr; +{ + register ITEM *j; + + if (pidebug && (foutput != NULL)) + (void) fprintf (foutput, + WSFMT ("putitem(%s), state %d\n"), writem (ptr), + nstate); + j = pstate[nstate + 1]; + j->pitem = ptr; + if (!nolook) + j->look = flset (lptr); + pstate[nstate + 1] = ++j; + if (j > zzmemsz) { + zzmemsz = j; + if (zzmemsz >= &psmem[new_pstsize]) + exp_psmem (); + /* error("out of state space"); */ + } +} + +/* + * mark nonterminals which derive the empty string + * also, look for nonterminals which don't derive any token strings + */ +static void +cempty () +{ +#define EMPTY 1 +#define WHOKNOWS 0 +#define OK 1 + int i, *p; + + /* + * first, use the array pempty to detect productions + * that can never be reduced + */ + + /* set pempty to WHONOWS */ + aryfil (pempty, nnonter + 1, WHOKNOWS); + + /* + * now, look at productions, marking nonterminals which + * derive something + */ + more: + PLOOP (0, i) { + if (pempty[*prdptr[i] - NTBASE]) + continue; + for (p = prdptr[i] + 1; *p >= 0; ++p) + if (*p >= NTBASE && pempty[*p - NTBASE] == WHOKNOWS) + break; + if (*p < 0) { /* production can be derived */ + pempty[*prdptr[i] - NTBASE] = OK; + goto more; + } + } + + /* now, look at the nonterminals, to see if they are all OK */ + + NTLOOP (i) { + /* + * the added production rises or falls as the + * start symbol ... + */ + if (i == 0) + continue; + if (pempty[i] != OK) { + fatfl = 0; +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Ask somebody who knows yacc how to translate nonterminal or + * look at translated yacc document. Check how 'derive' is + * translated in these documents also. + */ + error ("nonterminal %s never derives any token string", + nontrst[i].name); + } + } + + if (nerrors) { + summary (); + exit (1); + } + + /* + * now, compute the pempty array, to see which nonterminals + * derive the empty string + */ + + /* set pempty to WHOKNOWS */ + + aryfil (pempty, nnonter + 1, WHOKNOWS); + + /* loop as long as we keep finding empty nonterminals */ + + again: + PLOOP (1, i) { + /* not known to be empty */ + if (pempty[*prdptr[i] - NTBASE] == WHOKNOWS) { + for (p = prdptr[i] + 1; + *p >= NTBASE && pempty[*p - NTBASE] == EMPTY; ++p); + /* we have a nontrivially empty nonterminal */ + if (*p < 0) { + pempty[*prdptr[i] - NTBASE] = EMPTY; + goto again; /* got one ... try for another */ + } + } + } +} + +/* generate the states */ +static int gsdebug = 0; +static void +stagen () +{ + int i, j; + int c; + register WSET *p, *q; + + /* initialize */ + + nstate = 0; + + pstate[0] = pstate[1] = psmem; + aryfil (clset.lset, tbitset, 0); + putitem (prdptr[0] + 1, &clset); + tystate[0] = MUSTDO; + nstate = 1; + pstate[2] = pstate[1]; + + aryfil (amem, new_actsize, 0); + + /* now, the main state generation loop */ + + more: + SLOOP (i) { + if (tystate[i] != MUSTDO) + continue; + tystate[i] = DONE; + aryfil (temp1, nnonter + 1, 0); + /* take state i, close it, and do gotos */ + closure (i); + WSLOOP (wsets, p) { /* generate goto's */ + if (p->flag) + continue; + p->flag = 1; + c = *(p->pitem); + if (c <= 1) { + if (pstate[i + 1] - pstate[i] <= p - wsets) + tystate[i] = MUSTLOOKAHEAD; + continue; + } + /* do a goto on c */ + WSLOOP (p, q) { + /* this item contributes to the goto */ + if (c == *(q->pitem)) { + putitem (q->pitem + 1, &q->ws); + q->flag = 1; + } + } + if (c < NTBASE) + (void) state (c); /* register new state */ + else + temp1[c - NTBASE] = state (c); + } + if (gsdebug && (foutput != NULL)) { + (void) fprintf (foutput, "%d: ", i); + NTLOOP (j) { + if (temp1[j]) + (void) fprintf (foutput, + WSFMT ("%s %d, "), nontrst[j].name, + temp1[j]); + } + (void) fprintf (foutput, "\n"); + } + indgo[i] = apack (&temp1[1], nnonter - 1) - 1; + goto more; /* we have done one goto; do some more */ + } + /* no more to do... stop */ +} + +/* generate the closure of state i */ +static int cldebug = 0; /* debugging flag for closure */ + +void +closure (int i) +{ + int c, ch, work, k; + register WSET *u, *v; + int *pi; + int **s, **t; + ITEM *q; + register ITEM *p; + int idx1 = 0; + + ++zzclose; + + /* first, copy kernel of state i to wsets */ + cwp = 0; + ITMLOOP (i, p, q) { + wsets[cwp].pitem = p->pitem; + wsets[cwp].flag = 1; /* this item must get closed */ + SETLOOP (k) wsets[cwp].ws.lset[k] = p->look->lset[k]; + WSBUMP (cwp); + } + + /* now, go through the loop, closing each item */ + + work = 1; + while (work) { + work = 0; + /* + * WSLOOP(wsets, u) { + */ + for (idx1 = 0; idx1 < cwp; idx1++) { + u = &wsets[idx1]; + if (u->flag == 0) + continue; + c = *(u->pitem); /* dot is before c */ + if (c < NTBASE) { + u->flag = 0; + /* + * only interesting case is where . is + * before nonterminal + */ + continue; + } + + /* compute the lookahead */ + aryfil (clset.lset, tbitset, 0); + + /* find items involving c */ + + WSLOOP (u, v) { + if (v->flag == 1 && *(pi = v->pitem) == c) { + v->flag = 0; + if (nolook) + continue; + while ((ch = *++pi) > 0) { + /* terminal symbol */ + if (ch < NTBASE) { + SETBIT (clset.lset, ch); + break; + } + /* nonterminal symbol */ + (void) setunion (clset.lset, + pfirst[ch - NTBASE]->lset); + if (!pempty[ch - NTBASE]) + break; + } + if (ch <= 0) + (void) setunion (clset.lset, v->ws.lset); + } + } + + /* now loop over productions derived from c */ + + c -= NTBASE; /* c is now nonterminal number */ + + t = pres[c + 1]; + for (s = pres[c]; s < t; ++s) { + /* put these items into the closure */ + WSLOOP (wsets, v) { /* is the item there */ + /* yes, it is there */ + if (v->pitem == *s) { + if (nolook) + goto nexts; + if (setunion (v->ws.lset, clset.lset)) + v->flag = work = 1; + goto nexts; + } + } + + /* not there; make a new entry */ + if (cwp + 1 >= wsetsz) + exp_wsets (); + + wsets[cwp].pitem = *s; + wsets[cwp].flag = 1; + if (!nolook) { + work = 1; + SETLOOP (k) wsets[cwp].ws.lset[k] = clset.lset[k]; + } + WSBUMP (cwp); + nexts:; + } + } + } + + /* have computed closure; flags are reset; return */ + + if (&wsets[cwp] > &wsets[zzcwp]) + zzcwp = cwp; + if (cldebug && (foutput != NULL)) { + (void) fprintf (foutput, "\nState %d, nolook = %d\n", i, nolook); + WSLOOP (wsets, u) { + if (u->flag) + (void) fprintf (foutput, "flag set!\n"); + u->flag = 0; + (void) fprintf (foutput, WSFMT ("\t%s"), writem (u->pitem)); + prlook (&u->ws); + (void) fprintf (foutput, "\n"); + } + } +} + +static LOOKSETS * +flset (p) + LOOKSETS *p; +{ + /* decide if the lookahead set pointed to by p is known */ + /* return pointer to a perminent location for the set */ + + int j, *w; + int *u, *v; + register LOOKSETS *q; + + for (q = &lkst[nlset]; q-- > lkst;) { + u = p->lset; + v = q->lset; + w = &v[tbitset]; + while (v < w) + if (*u++ != *v++) + goto more; + /* we have matched */ + return (q); + more:; + } + /* add a new one */ + q = &lkst[nlset++]; + if (nlset >= lsetsize) { + exp_lkst (); + q = &lkst[nlset++]; + } + SETLOOP (j) q->lset[j] = p->lset[j]; + return (q); +} + +static void +exp_lkst () +{ + int i, j; + static LOOKSETS *lookbase; + + lookbase = lkst; + lsetsize += LSETSIZE; + tmp_lset = (int *) + calloc ((size_t) (TBITSET * (lsetsize - LSETSIZE)), sizeof (int)); + if (tmp_lset == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Memory allocation error. Do not translate lookset. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("could not expand lookset array"); + lkst = (LOOKSETS *) realloc ((char *) lkst, sizeof (LOOKSETS) * lsetsize); + for (i = lsetsize - LSETSIZE, j = 0; i < lsetsize; ++i, ++j) + lkst[i].lset = tmp_lset + TBITSET * j; + tmp_lset = NULL; + if (lkst == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Memory allocation error. Do not translate lookset. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("could not expand lookahead sets"); + for (i = 0; i <= nnonter; ++i) + pfirst[i] = pfirst[i] - lookbase + lkst; + for (i = 0; i <= nstate + 1; ++i) { + if (psmem[i].look) + psmem[i].look = psmem[i].look - lookbase + lkst; + if (pstate[i]->look) + pstate[i]->look = pstate[i]->look - lookbase + lkst; + } +} + +static void +exp_wsets () +{ + int i, j; + + wsetsz += WSETSIZE; + tmp_lset = (int *) + calloc ((size_t) (TBITSET * (wsetsz - WSETSIZE)), sizeof (int)); + if (tmp_lset == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Memory allocation error. Do not translate lookset. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("could not expand lookset array"); + wsets = (WSET *) realloc ((char *) wsets, sizeof (WSET) * wsetsz); + for (i = wsetsz - WSETSIZE, j = 0; i < wsetsz; ++i, ++j) + wsets[i].ws.lset = tmp_lset + TBITSET * j; + tmp_lset = NULL; + if (wsets == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Memory allocation error. You may just transltate + * this as 'Could not allocate internally used memory.' + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("could not expand working sets"); +} + +static void +exp_states () +{ + nstatesz += NSTATES; + + pstate = (ITEM **) + realloc ((char *) pstate, sizeof (ITEM *) * (nstatesz + 2)); + mstates = (int *) realloc ((char *) mstates, sizeof (int) * nstatesz); + defact = (int *) realloc ((char *) defact, sizeof (int) * nstatesz); + tystate = (int *) realloc ((char *) tystate, sizeof (int) * nstatesz); + indgo = (int *) realloc ((char *) indgo, sizeof (int) * nstatesz); + + if ((*pstate == NULL) || (tystate == NULL) || (defact == NULL) || + (indgo == NULL) || (mstates == NULL)) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Memory allocation error. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("cannot expand table of states"); +} + +static void +exp_psmem () +{ + int i; + + new_pstsize += PSTSIZE; + psmem = (ITEM *) realloc ((char *) psmem, sizeof (ITEM) * new_pstsize); + if (psmem == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Memory allocation error. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("cannot expand pstate memory"); + + zzmemsz = zzmemsz - pstate[0] + psmem; + for (i = 1; i <= nstate + 1; ++i) + pstate[i] = pstate[i] - pstate[0] + psmem; + pstate[0] = psmem; +} |