aboutsummaryrefslogtreecommitdiff
path: root/unix/boot/xyacc/y1.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/boot/xyacc/y1.c')
-rw-r--r--unix/boot/xyacc/y1.c1307
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;
+}