diff options
Diffstat (limited to 'unix/boot/xyacc/y4.c')
-rw-r--r-- | unix/boot/xyacc/y4.c | 528 |
1 files changed, 528 insertions, 0 deletions
diff --git a/unix/boot/xyacc/y4.c b/unix/boot/xyacc/y4.c new file mode 100644 index 00000000..2badc0e5 --- /dev/null +++ b/unix/boot/xyacc/y4.c @@ -0,0 +1,528 @@ +/* + * 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 <wctype.h> +#define NOMORE -1000 + +static void gin (int); +static void stin (int); +static void osummary (void); +static void aoutput (void); +static void arout (char *, int *, int); +static int nxti (void); +static int gtnm (void); + +static int *ggreed; +static int *pgo; +static int *yypgo; + +static int maxspr = 0; /* maximum spread of any entry */ +static int maxoff = 0; /* maximum offset into an array */ +int *optimmem; +static int *maxa; + +static int nxdb = 0; +static int adb = 0; + + /* 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 */ + + +void +callopt () +{ + int i, *p, j, k, *q; + + ggreed = (int *) malloc (sizeof (int) * size); + pgo = (int *) malloc (sizeof (int) * size); + yypgo = &nontrst[0].tvalue; + + /* read the arrays from tempfile and set parameters */ + + if ((finput = fopen (TEMPNAME, "r")) == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * tempfile can be translated as temporary file. + */ + error ("optimizer cannot open tempfile"); + + optimmem = tracemem; + pgo[0] = 0; + temp1[0] = 0; + nstate = 0; + nnonter = 0; + for (;;) { + switch (gtnm ()) { + + case '\n': + temp1[++nstate] = (--optimmem) - tracemem; + /* FALLTHRU */ + + case ',': + continue; + + case '$': + break; + + default: + error ("bad tempfile"); + } + break; + } + + temp1[nstate] = yypgo[0] = (--optimmem) - tracemem; + + for (;;) { + switch (gtnm ()) { + + case '\n': + yypgo[++nnonter] = optimmem - tracemem; + /* FALLTHRU */ + case ',': + continue; + + case EOF: + break; + + default: +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * tempfile can be translated as 'temporary file'. + */ + error ("bad tempfile"); + } + break; + } + + yypgo[nnonter--] = (--optimmem) - tracemem; + + for (i = 0; i < nstate; ++i) { + k = 32000; + j = 0; + q = tracemem + temp1[i + 1]; + for (p = tracemem + temp1[i]; p < q; p += 2) { + if (*p > j) + j = *p; + if (*p < k) + k = *p; + } + if (k <= j) { + /* + * nontrivial situation + * temporarily, kill this for compatibility + */ + /* j -= k; j is now the range */ + if (k > maxoff) + maxoff = k; + } + tystate[i] = (temp1[i + 1] - temp1[i]) + 2 * j; + if (j > maxspr) + maxspr = j; + } + + /* initialize ggreed table */ + for (i = 1; i <= nnonter; ++i) { + ggreed[i] = 1; + j = 0; + /* minimum entry index is always 0 */ + q = tracemem + yypgo[i + 1] - 1; + for (p = tracemem + yypgo[i]; p < q; p += 2) { + ggreed[i] += 2; + if (*p > j) + j = *p; + } + ggreed[i] = ggreed[i] + 2 * j; + if (j > maxoff) + maxoff = j; + } + + /* now, prepare to put the shift actions into the amem array */ + for (i = 0; i < new_actsize; ++i) + amem[i] = 0; + maxa = amem; + + for (i = 0; i < nstate; ++i) { + if (tystate[i] == 0 && adb > 1) + (void) fprintf (ftable, "State %d: null\n", i); + indgo[i] = YYFLAG1; + } + + while ((i = nxti ()) != NOMORE) { + if (i >= 0) + stin (i); + else + gin (-i); + } + + if (adb > 2) { /* print a array */ + for (p = amem; p <= maxa; p += 10) { + (void) fprintf (ftable, "%4" PRIdPTR " ", p - amem); + for (i = 0; i < 10; ++i) + (void) fprintf (ftable, "%4d ", p[i]); + (void) fprintf (ftable, "\n"); + } + } + + + /* write out the output appropriate to the language */ + aoutput (); + osummary (); + ZAPFILE (TEMPNAME); +} + +static void +gin (int i) +{ + int *r, *s, *q1, *q2; + int *p; + + /* enter gotos on nonterminal i into array amem */ + ggreed[i] = 0; + + q2 = tracemem + yypgo[i + 1] - 1; + q1 = tracemem + yypgo[i]; + + /* now, find a place for it */ + + /* for( p=amem; p < &amem[new_actsize]; ++p ){ */ + p = amem; + for (;;) { + while (p >= &amem[new_actsize]) + exp_act (&p); + if (*p) + goto nextgp; + for (r = q1; r < q2; r += 2) { + s = p + *r + 1; + /* + * Check if action table needs to + * be expanded or not. If so, + * expand it. + */ + while (s >= &amem[new_actsize]) { + exp_act (&p); + s = p + *r + 1; + } + if (*s) + goto nextgp; + if (s > maxa) { + while ((maxa = s) >= &amem[new_actsize]) + /* error( "amem array overflow" ); */ + exp_act (&p); + } + } + /* we have found a spot */ + *p = *q2; + if (p > maxa) { + while ((maxa = p) >= &amem[new_actsize]) + /* error("amem array overflow"); */ + exp_act (&p); + } + for (r = q1; r < q2; r += 2) { + s = p + *r + 1; + /* + * Check if action table needs to + * be expanded or not. If so, + * expand it. + */ + while (s >= &amem[new_actsize]) { + exp_act (&p); + s = p + *r + 1; + } + *s = r[1]; + } + + pgo[i] = p - amem; + if (adb > 1) + (void) fprintf (ftable, + "Nonterminal %d, entry at %d\n", i, pgo[i]); + goto nextgi; + + nextgp: + ++p; + } + /* error( "cannot place goto %d\n", i ); */ + nextgi:; +} + +static void +stin (int i) +{ + int *r, n, nn, flag, j, *q1, *q2; + int *s; + + tystate[i] = 0; + + /* Enter state i into the amem array */ + + q2 = tracemem + temp1[i + 1]; + q1 = tracemem + temp1[i]; + /* Find an acceptable place */ + + nn = -maxoff; + more: + for (n = nn; n < new_actsize; ++n) { + flag = 0; + for (r = q1; r < q2; r += 2) { + s = *r + n + amem; + if (s < amem) + goto nextn; + /* + * Check if action table needs to + * be expanded or not. If so, + * expand it. + */ + while (s >= &amem[new_actsize]) { + exp_act ((int **) NULL); + s = *r + n + amem; + } + if (*s == 0) + ++flag; + else if (*s != r[1]) + goto nextn; + } + + /* + * check that the position equals another + * only if the states are identical + */ + for (j = 0; j < nstate; ++j) { + if (indgo[j] == n) { + if (flag) + /* + * we have some disagreement. + */ + goto nextn; + if (temp1[j + 1] + temp1[i] == temp1[j] + temp1[i + 1]) { + /* states are equal */ + indgo[i] = n; + if (adb > 1) + (void) fprintf (ftable, + "State %d: entry at" + " %d equals state %d\n", i, n, j); + return; + } + goto nextn; /* we have some disagreement */ + } + } + + for (r = q1; r < q2; r += 2) { + while ((s = *r + n + amem) >= &amem[new_actsize]) { + /* + * error( "out of space"); + */ + exp_act ((int **) NULL); + } + if (s > maxa) + maxa = s; + if (*s != 0 && *s != r[1]) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * Leave this untrasnlated. Yacc internal error. + */ + error ("clobber of amem array, pos'n %d, by %d", + s - amem, r[1]); + *s = r[1]; + } + indgo[i] = n; + if (adb > 1) + (void) fprintf (ftable, "State %d: entry at %d\n", i, indgo[i]); + return; + nextn:; + } + + /* error( "Error; failure to place state %d\n", i ); */ + exp_act ((int **) NULL); + nn = new_actsize - ACTSIZE; + goto more; + /* NOTREACHED */ +} + +static int +nxti () +{ + /* finds the next i */ + int i, max, maxi; + max = 0; + maxi = 0; + + for (i = 1; i <= nnonter; ++i) + if (ggreed[i] >= max) { + max = ggreed[i]; + maxi = -i; + } + + for (i = 0; i < nstate; ++i) + if (tystate[i] >= max) { + max = tystate[i]; + maxi = i; + } + if (nxdb) + (void) fprintf (ftable, "nxti = %d, max = %d\n", maxi, max); + if (max == 0) + return (NOMORE); + else + return (maxi); +} + +static void +osummary () +{ + /* write summary */ + int i, *p; + + if (foutput == NULL) + return; + i = 0; + for (p = maxa; p >= amem; --p) { + if (*p == 0) + ++i; + } + + (void) fprintf (foutput, + "Optimizer space used: input %" PRIdPTR + "/%d, output %" PRIdPTR "/%d\n", + optimmem - tracemem + 1, new_memsize, maxa - amem + 1, + new_actsize); + (void) fprintf (foutput, "%" PRIdPTR " table entries, %d zero\n", + (maxa - amem) + 1, i); + (void) fprintf (foutput, "maximum spread: %d, maximum offset: %d\n", + maxspr, maxoff); + +} + + +/* AOUTPUT -- This version is for SPP. + */ +static void +aoutput () +{ + /* write out the optimized parser */ + + fprintf (fsppout, "define\tYYLAST\t\t%d\n", (int) (maxa - amem + 1)); + + arout ("yyact", amem, (maxa - amem) + 1); + arout ("yypact", indgo, nstate); + arout ("yypgo", pgo, nnonter + 1); +} + + +/* AROUT -- Output SPP declarations and initializations for a Yacc table. + */ +# define NDP_PERLINE 8 + +static void +arout (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]); + } + } +} + +static int +gtnm () +{ + int s, val, c; + + /* read and convert an integer from the standard input */ + /* return the terminating character */ + /* blanks, tabs, and newlines are ignored */ + + s = 1; + val = 0; + + while ((c = getc (finput)) != EOF) { + if (iswdigit (c)) + val = val * 10 + c - '0'; + else if (c == '-') + s = -1; + else + break; + } + *optimmem++ = s * val; + if (optimmem >= &tracemem[new_memsize]) + exp_mem (0); + return (c); +} + +void +exp_act (ptr) + int **ptr; +{ + static int *actbase; + int i; + new_actsize += ACTSIZE; + + actbase = amem; + amem = (int *) realloc ((char *) amem, sizeof (int) * new_actsize); + if (amem == NULL) +/* + * TRANSLATION_NOTE -- This is a message from yacc. + * This message is passed to error() function. + * + * You may just translate this as: + * 'Could not allocate internally used memory.' + */ + error ("couldn't expand action table"); + + for (i = new_actsize - ACTSIZE; i < new_actsize; ++i) + amem[i] = 0; + if (ptr != NULL) + *ptr = *ptr - actbase + amem; + if (memp >= amem) + memp = memp - actbase + amem; + if (maxa >= amem) + maxa = maxa - actbase + amem; +} |