aboutsummaryrefslogtreecommitdiff
path: root/unix/boot/xyacc/y3.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/boot/xyacc/y3.c')
-rw-r--r--unix/boot/xyacc/y3.c606
1 files changed, 606 insertions, 0 deletions
diff --git a/unix/boot/xyacc/y3.c b/unix/boot/xyacc/y3.c
new file mode 100644
index 00000000..1b6ac149
--- /dev/null
+++ b/unix/boot/xyacc/y3.c
@@ -0,0 +1,606 @@
+/*
+ * 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"
+
+static void go2gen (int);
+static void precftn (int, int, int);
+static void wract (int);
+static void wrstate (int);
+static void wdef (char *, int);
+static void wrmbchars (void);
+ /* important local variables */
+static int lastred; /* number of the last reduction of a state */
+int *defact;
+extern int *toklev;
+extern int cwp;
+
+int exca[NSTATES * 2]; /* buffer states for printing with warray */
+int nexca;
+
+
+ /* 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 */
+
+
+
+
+/* print the output for the states */
+void
+output ()
+{
+ int i, k, c;
+ register WSET *u, *v;
+
+ /*
+ (void) fprintf(fsppout, "static YYCONST yytabelem yyexca[] ={\n");
+ */
+
+ SLOOP (i) { /* output the stuff for state i */
+ nolook = !(tystate[i] == MUSTLOOKAHEAD);
+ closure (i);
+ /* output actions */
+ nolook = 1;
+ aryfil (temp1, ntoksz + nnontersz + 1, 0);
+ WSLOOP (wsets, u) {
+ c = *(u->pitem);
+ if (c > 1 && c < NTBASE && temp1[c] == 0) {
+ WSLOOP (u, v) {
+ if (c == *(v->pitem))
+ putitem (v->pitem + 1, (LOOKSETS *) 0);
+ }
+ temp1[c] = state (c);
+ } else if (c > NTBASE && temp1[(c -= NTBASE) + ntokens] == 0) {
+ temp1[c + ntokens] = amem[indgo[i] + c];
+ }
+ }
+ if (i == 1)
+ temp1[1] = ACCEPTCODE;
+ /* now, we have the shifts; look at the reductions */
+ lastred = 0;
+ WSLOOP (wsets, u) {
+ c = *(u->pitem);
+ if (c <= 0) { /* reduction */
+ lastred = -c;
+ TLOOP (k) {
+ if (BIT (u->ws.lset, k)) {
+ if (temp1[k] == 0)
+ temp1[k] = c;
+ else if (temp1[k] < 0) {
+ /*
+ * reduce/reduce
+ * conflict
+ */
+ /* BEGIN CSTYLED */
+ if (foutput != NULL)
+ (void) fprintf (foutput,
+ WSFMT
+ ("\n%d: reduce/reduce conflict"
+ " (red'ns %d and %d ) on %s"),
+ i, -temp1[k], lastred,
+ symnam (k));
+ if (-temp1[k] > lastred)
+ temp1[k] = -lastred;
+ ++zzrrconf;
+ /* END CSTYLED */
+ } else
+ /*
+ * potentia
+ * shift/reduce
+ * conflict.
+ */
+ precftn (lastred, k, i);
+ }
+ }
+ }
+ }
+ wract (i);
+ }
+
+ /*
+ (void) fprintf(fsppout, "\t};\n");
+ */
+ warray ("yyexca", exca, nexca);
+ wdef ("YYNPROD", nprod);
+ if (nmbchars > 0) {
+ wrmbchars ();
+ }
+}
+
+static int pkdebug = 0;
+int
+apack (p, n)
+ int *p;
+ int n;
+{
+ /* pack state i from temp1 into amem */
+ int off;
+ int *pp, *qq;
+ int *q, *rr;
+ int diff;
+
+ /*
+ * we don't need to worry about checking because we
+ * we will only look up entries known to be there...
+ */
+
+ /* eliminate leading and trailing 0's */
+
+ q = p + n;
+ for (pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)
+ /* NULL */ ;
+ if (pp > q)
+ return (0); /* no actions */
+ p = pp;
+
+ /* now, find a place for the elements from p to q, inclusive */
+ /* for( rr=amem; rr<=r; ++rr,++off ){ *//* try rr */
+ rr = amem;
+ for (;; ++rr, ++off) {
+ while (rr >= &amem[new_actsize - 1])
+ exp_act (&rr);
+ qq = rr;
+ for (pp = p; pp <= q; ++pp, ++qq) {
+ if (*pp) {
+ diff = qq - rr;
+ while (qq >= &amem[new_actsize - 1]) {
+ exp_act (&rr);
+ qq = diff + rr;
+ }
+ if (*pp != *qq && *qq != 0)
+ goto nextk;
+ }
+ }
+
+ /* we have found an acceptable k */
+
+ if (pkdebug && foutput != NULL)
+ (void) fprintf (foutput,
+ "off = %d, k = %" PRIdPTR "\n", off, rr - amem);
+
+ qq = rr;
+ for (pp = p; pp <= q; ++pp, ++qq) {
+ if (*pp) {
+ diff = qq - rr;
+ while (qq >= &amem[new_actsize - 1]) {
+ exp_act (&rr);
+ qq = diff + rr;
+ }
+ if (qq > memp)
+ memp = qq;
+ *qq = *pp;
+ }
+ }
+ if (pkdebug && foutput != NULL) {
+ for (pp = amem; pp <= memp; pp += 10) {
+ (void) fprintf (foutput, "\t");
+ for (qq = pp; qq <= pp + 9; ++qq)
+ (void) fprintf (foutput, "%d ", *qq);
+ (void) fprintf (foutput, "\n");
+ }
+ }
+ return (off);
+ nextk:;
+ }
+ /* error("no space in action table" ); */
+ /* NOTREACHED */
+}
+
+void
+go2out ()
+{
+ /* output the gotos for the nontermninals */
+ int i, j, k, best, count, cbest, times;
+
+ (void) fprintf (ftemp, "$\n"); /* mark begining of gotos */
+
+ for (i = 1; i <= nnonter; ++i) {
+ go2gen (i);
+ /* find the best one to make default */
+ best = -1;
+ times = 0;
+ for (j = 0; j < nstate; ++j) { /* is j the most frequent */
+ if (tystate[j] == 0)
+ continue;
+ if (tystate[j] == best)
+ continue;
+ /* is tystate[j] the most frequent */
+ count = 0;
+ cbest = tystate[j];
+ for (k = j; k < nstate; ++k)
+ if (tystate[k] == cbest)
+ ++count;
+ if (count > times) {
+ best = cbest;
+ times = count;
+ }
+ }
+
+ /* best is now the default entry */
+ zzgobest += (times - 1);
+ for (j = 0; j < nstate; ++j) {
+ if (tystate[j] != 0 && tystate[j] != best) {
+ (void) fprintf (ftemp, "%d,%d,", j, tystate[j]);
+ zzgoent += 1;
+ }
+ }
+
+ /* now, the default */
+
+ zzgoent += 1;
+ (void) fprintf (ftemp, "%d\n", best);
+
+ }
+}
+
+static int g2debug = 0;
+static void
+go2gen (int c)
+{
+ /* output the gotos for nonterminal c */
+ int i, work, cc;
+ ITEM *p, *q;
+
+ /* first, find nonterminals with gotos on c */
+ aryfil (temp1, nnonter + 1, 0);
+ temp1[c] = 1;
+
+ work = 1;
+ while (work) {
+ work = 0;
+ PLOOP (0, i) {
+ if ((cc = prdptr[i][1] - NTBASE) >= 0) {
+ /* cc is a nonterminal */
+ if (temp1[cc] != 0) {
+ /*
+ * cc has a goto on c
+ * thus, the left side of
+ * production i does too.
+ */
+ cc = *prdptr[i] - NTBASE;
+ if (temp1[cc] == 0) {
+ work = 1;
+ temp1[cc] = 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
+
+ if (g2debug && foutput != NULL) {
+ (void) fprintf (foutput, WSFMT ("%s: gotos on "), nontrst[c].name);
+ NTLOOP (i) if (temp1[i])
+ (void) fprintf (foutput, WSFMT ("%s "), nontrst[i].name);
+ (void) fprintf (foutput, "\n");
+ }
+
+ /* now, go through and put gotos into tystate */
+ aryfil (tystate, nstate, 0);
+ SLOOP (i) {
+ ITMLOOP (i, p, q) {
+ if ((cc = *p->pitem) >= NTBASE) {
+ if (temp1[cc -= NTBASE]) {
+ /* goto on c is possible */
+ tystate[i] = amem[indgo[i] + c];
+ break;
+ }
+ }
+ }
+ }
+}
+
+/* decide a shift/reduce conflict by precedence. */
+static void
+precftn (int r, int t, int s)
+{
+
+ /*
+ * r is a rule number, t a token number
+ * the conflict is in state s
+ * temp1[t] is changed to reflect the action
+ */
+
+ int lp, lt, action;
+
+ lp = levprd[r];
+ lt = toklev[t];
+ if (PLEVEL (lt) == 0 || PLEVEL (lp) == 0) {
+ /* conflict */
+ if (foutput != NULL)
+ (void) fprintf (foutput,
+ WSFMT ("\n%d: shift/reduce conflict"
+ " (shift %d, red'n %d) on %s"),
+ s, temp1[t], r, symnam (t));
+ ++zzsrconf;
+ return;
+ }
+ if (PLEVEL (lt) == PLEVEL (lp))
+ action = ASSOC (lt) & ~04;
+ else if (PLEVEL (lt) > PLEVEL (lp))
+ action = RASC; /* shift */
+ else
+ action = LASC; /* reduce */
+
+ switch (action) {
+ case BASC: /* error action */
+ temp1[t] = ERRCODE;
+ return;
+ case LASC: /* reduce */
+ temp1[t] = -r;
+ return;
+ }
+}
+
+
+/* WRACT -- Output the state I. Modified to save state array in exca
+ * for later printing by warray.
+ */
+static void
+wract (int i)
+{
+ /* output state i */
+ /* temp1 has the actions, lastred the default */
+ int p, p0, p1;
+ int ntimes, tred, count, j;
+ int flag;
+
+ /* find the best choice for lastred */
+
+ lastred = 0;
+ ntimes = 0;
+ TLOOP (j) {
+ if (temp1[j] >= 0)
+ continue;
+ if (temp1[j] + lastred == 0)
+ continue;
+ /* count the number of appearances of temp1[j] */
+ count = 0;
+ tred = -temp1[j];
+ levprd[tred] |= REDFLAG;
+ TLOOP (p) {
+ if (temp1[p] + tred == 0)
+ ++count;
+ }
+ if (count > ntimes) {
+ lastred = tred;
+ ntimes = count;
+ }
+ }
+
+ /*
+ * for error recovery, arrange that, if there is a shift on the
+ * error recovery token, `error', that the default be the error action
+ if (temp1[2] > 0)
+ */
+ if (temp1[1] > 0)
+ lastred = 0;
+
+ /* clear out entries in temp1 which equal lastred */
+ TLOOP (p) {
+ if (temp1[p] + lastred == 0)
+ temp1[p] = 0;
+ }
+
+ wrstate (i);
+ defact[i] = lastred;
+
+ flag = 0;
+ TLOOP (p0) {
+ if ((p1 = temp1[p0]) != 0) {
+ if (p1 < 0) {
+ p1 = -p1;
+ goto exc;
+ } else if (p1 == ACCEPTCODE) {
+ p1 = -1;
+ goto exc;
+ } else if (p1 == ERRCODE) {
+ p1 = 0;
+ goto exc;
+ exc:
+ if (flag++ == 0) {
+ exca[nexca++] = -1;
+ exca[nexca++] = i;
+ }
+ exca[nexca++] = tokset[p0].value;
+ exca[nexca++] = p1;
+ ++zzexcp;
+ if (nexca >= NSTATES * 2) {
+ error ("state table overflow");
+ }
+ } else {
+ (void) fprintf (ftemp, "%d,%d,", tokset[p0].value, p1);
+ ++zzacent;
+ }
+ }
+ }
+ if (flag) {
+ defact[i] = -2;
+ exca[nexca++] = -2;
+ exca[nexca++] = lastred;
+ }
+ (void) fprintf (ftemp, "\n");
+}
+
+static void
+wrstate (int i)
+{
+ /* writes state i */
+ int j0, j1;
+ register ITEM *pp, *qq;
+ register WSET *u;
+
+ if (foutput == NULL)
+ return;
+ (void) fprintf (foutput, "\nstate %d\n", i);
+ ITMLOOP (i, pp, qq) {
+ (void) fprintf (foutput, WSFMT ("\t%s\n"), writem (pp->pitem));
+ }
+ if (tystate[i] == MUSTLOOKAHEAD) {
+ /* print out empty productions in closure */
+ WSLOOP (wsets + (pstate[i + 1] - pstate[i]), u) {
+ if (*(u->pitem) < 0)
+ (void) fprintf (foutput, WSFMT ("\t%s\n"), writem (u->pitem));
+ }
+ }
+
+ /* check for state equal to another */
+ TLOOP (j0) if ((j1 = temp1[j0]) != 0) {
+ (void) fprintf (foutput, WSFMT ("\n\t%s "), symnam (j0));
+ if (j1 > 0) { /* shift, error, or accept */
+ if (j1 == ACCEPTCODE)
+ (void) fprintf (foutput, "accept");
+ else if (j1 == ERRCODE)
+ (void) fprintf (foutput, "error");
+ else
+ (void) fprintf (foutput, "shift %d", j1);
+ } else
+ (void) fprintf (foutput, "reduce %d", -j1);
+ }
+
+ /* output the final production */
+ if (lastred)
+ (void) fprintf (foutput, "\n\t. reduce %d\n\n", lastred);
+ else
+ (void) fprintf (foutput, "\n\t. error\n\n");
+
+ /* now, output nonterminal actions */
+ j1 = ntokens;
+ for (j0 = 1; j0 <= nnonter; ++j0) {
+ if (temp1[++j1])
+ (void) fprintf (foutput,
+ WSFMT ("\t%s goto %d\n"),
+ symnam (j0 + NTBASE), temp1[j1]);
+ }
+}
+
+static void
+wdef (char *s, int n)
+{
+ /* output a definition of s to the value n */
+ (void) fprintf (fsppout, WSFMT ("define\t%s\t\t%d\n"), s, n);
+}
+
+# define NDP_PERLINE 8
+
+void
+warray (s, v, n)
+ char *s;
+ int *v, n;
+{
+ register int i, j;
+
+ fprintf (ftable, "short\t%s[%d]\n", s, n);
+
+ for (j = 0; j < n; j += NDP_PERLINE) {
+ fprintf (ftable, "data\t(%s(i),i=%3d,%3d)\t/",
+ s, j + 1, (j + NDP_PERLINE < n) ? j + NDP_PERLINE : n);
+
+ for (i = j; i < j + NDP_PERLINE && i < n; i++) {
+ if ((i == j + NDP_PERLINE - 1) || i >= n - 1)
+ fprintf (ftable, "%4d/\n", v[i]);
+ else
+ fprintf (ftable, "%4d,", v[i]);
+ }
+ }
+}
+
+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.
+ */
+
+ int i, j;
+
+ j = 0;
+ levprd[0] = 0;
+ PLOOP (1, i) {
+ if (!(levprd[i] & REDFLAG)) {
+ ++j;
+ if (foutput != NULL) {
+ (void) fprintf (foutput,
+ WSFMT ("Rule not reduced: %s\n"),
+ writem (prdptr[i]));
+ }
+ }
+ levprd[i] = *prdptr[i] - NTBASE;
+ }
+ if (j)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * Check how 'reduced' is translated in yacc man page/document.
+ */
+ (void) fprintf (stderr, "%d rules never reduced\n", j);
+}
+
+
+static int
+cmpmbchars (p, q)
+ MBCLIT *p, *q;
+{
+ /* Compare two MBLITs. */
+ return ((p->character) - (q->character));
+}
+
+static void
+wrmbchars ()
+{
+ int i;
+
+ return wdef ("YYNMBCHARS", nmbchars);
+ qsort (mbchars, nmbchars, sizeof (*mbchars),
+ (int (*)(const void *, const void *)) cmpmbchars);
+ (void) fprintf (ftable,
+ "static struct{\n\tchar character;"
+ "\n\tint tvalue;\n}yymbchars[YYNMBCHARS]={\n");
+ for (i = 0; i < nmbchars; ++i) {
+ (void) fprintf (ftable, "\t{%#x,%d}",
+ (int) mbchars[i].character, mbchars[i].tvalue);
+ if (i < nmbchars - 1) {
+ /* Not the last. */
+ (void) fprintf (ftable, ",\n");
+ }
+ }
+ (void) fprintf (ftable, "\n};\n");
+}