17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*1dd08564Sab196087 * Common Development and Distribution License (the "License").
6*1dd08564Sab196087 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*1dd08564Sab196087 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */
277c478bd9Sstevel@tonic-gate /* All Rights Reserved */
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
307c478bd9Sstevel@tonic-gate
31e29394bdSmike_s #include "dextern.h"
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate static void go2gen(int);
347c478bd9Sstevel@tonic-gate static void precftn(int, int, int);
357c478bd9Sstevel@tonic-gate static void wract(int);
367c478bd9Sstevel@tonic-gate static void wrstate(int);
377c478bd9Sstevel@tonic-gate static void wdef(wchar_t *, int);
387c478bd9Sstevel@tonic-gate static void wrmbchars(void);
397c478bd9Sstevel@tonic-gate /* important local variables */
407c478bd9Sstevel@tonic-gate static int lastred; /* number of the last reduction of a state */
417c478bd9Sstevel@tonic-gate int *defact;
427c478bd9Sstevel@tonic-gate extern int *toklev;
437c478bd9Sstevel@tonic-gate extern int cwp;
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate /* print the output for the states */
467c478bd9Sstevel@tonic-gate void
output()477c478bd9Sstevel@tonic-gate output()
487c478bd9Sstevel@tonic-gate {
497c478bd9Sstevel@tonic-gate int i, k, c;
507c478bd9Sstevel@tonic-gate register WSET *u, *v;
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate (void) fprintf(ftable, "static YYCONST yytabelem yyexca[] ={\n");
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate SLOOP(i) { /* output the stuff for state i */
557c478bd9Sstevel@tonic-gate nolook = !(tystate[i] == MUSTLOOKAHEAD);
567c478bd9Sstevel@tonic-gate closure(i);
577c478bd9Sstevel@tonic-gate /* output actions */
587c478bd9Sstevel@tonic-gate nolook = 1;
597c478bd9Sstevel@tonic-gate aryfil(temp1, ntoksz+nnontersz+1, 0);
607c478bd9Sstevel@tonic-gate WSLOOP(wsets, u) {
617c478bd9Sstevel@tonic-gate c = *(u->pitem);
627c478bd9Sstevel@tonic-gate if (c > 1 && c < NTBASE && temp1[c] == 0) {
637c478bd9Sstevel@tonic-gate WSLOOP(u, v) {
647c478bd9Sstevel@tonic-gate if (c == *(v->pitem))
657c478bd9Sstevel@tonic-gate putitem(v->pitem + 1,
667c478bd9Sstevel@tonic-gate (LOOKSETS *)0);
677c478bd9Sstevel@tonic-gate }
687c478bd9Sstevel@tonic-gate temp1[c] = state(c);
697c478bd9Sstevel@tonic-gate } else if (c > NTBASE &&
707c478bd9Sstevel@tonic-gate temp1[(c -= NTBASE) + ntokens] == 0) {
717c478bd9Sstevel@tonic-gate temp1[c + ntokens] = amem[indgo[i] + c];
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate }
747c478bd9Sstevel@tonic-gate if (i == 1)
757c478bd9Sstevel@tonic-gate temp1[1] = ACCEPTCODE;
767c478bd9Sstevel@tonic-gate /* now, we have the shifts; look at the reductions */
777c478bd9Sstevel@tonic-gate lastred = 0;
787c478bd9Sstevel@tonic-gate WSLOOP(wsets, u) {
797c478bd9Sstevel@tonic-gate c = *(u->pitem);
807c478bd9Sstevel@tonic-gate if (c <= 0) { /* reduction */
817c478bd9Sstevel@tonic-gate lastred = -c;
827c478bd9Sstevel@tonic-gate TLOOP(k) {
837c478bd9Sstevel@tonic-gate if (BIT(u->ws.lset, k)) {
847c478bd9Sstevel@tonic-gate if (temp1[k] == 0)
857c478bd9Sstevel@tonic-gate temp1[k] = c;
867c478bd9Sstevel@tonic-gate else if (temp1[k] < 0) {
877c478bd9Sstevel@tonic-gate /*
887c478bd9Sstevel@tonic-gate * reduce/reduce
897c478bd9Sstevel@tonic-gate * conflict
907c478bd9Sstevel@tonic-gate */
91*1dd08564Sab196087 /* BEGIN CSTYLED */
927c478bd9Sstevel@tonic-gate if (foutput != NULL)
937c478bd9Sstevel@tonic-gate (void) fprintf(foutput,
94*1dd08564Sab196087 WSFMT("\n%d: reduce/reduce conflict"
95*1dd08564Sab196087 " (red'ns %d and %d ) on %ws"),
967c478bd9Sstevel@tonic-gate i, -temp1[k],
977c478bd9Sstevel@tonic-gate lastred, symnam(k));
987c478bd9Sstevel@tonic-gate if (-temp1[k] > lastred)
997c478bd9Sstevel@tonic-gate temp1[k] = -lastred;
1007c478bd9Sstevel@tonic-gate ++zzrrconf;
101*1dd08564Sab196087 /* END CSTYLED */
1027c478bd9Sstevel@tonic-gate } else
1037c478bd9Sstevel@tonic-gate /*
1047c478bd9Sstevel@tonic-gate * potentia
1057c478bd9Sstevel@tonic-gate * shift/reduce
1067c478bd9Sstevel@tonic-gate * conflict.
1077c478bd9Sstevel@tonic-gate */
1087c478bd9Sstevel@tonic-gate precftn(lastred, k, i);
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate wract(i);
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate (void) fprintf(ftable, "\t};\n");
1177c478bd9Sstevel@tonic-gate wdef(L"YYNPROD", nprod);
1187c478bd9Sstevel@tonic-gate if (nmbchars > 0) {
1197c478bd9Sstevel@tonic-gate wrmbchars();
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate static int pkdebug = 0;
124e29394bdSmike_s int
apack(p,n)1257c478bd9Sstevel@tonic-gate apack(p, n)
1267c478bd9Sstevel@tonic-gate int *p;
127e29394bdSmike_s int n;
1287c478bd9Sstevel@tonic-gate {
1297c478bd9Sstevel@tonic-gate /* pack state i from temp1 into amem */
1307c478bd9Sstevel@tonic-gate int off;
131e29394bdSmike_s int *pp, *qq;
132e29394bdSmike_s int *q, *rr;
1337c478bd9Sstevel@tonic-gate int diff;
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate * we don't need to worry about checking because we
1377c478bd9Sstevel@tonic-gate * we will only look up entries known to be there...
1387c478bd9Sstevel@tonic-gate */
1397c478bd9Sstevel@tonic-gate
1407c478bd9Sstevel@tonic-gate /* eliminate leading and trailing 0's */
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate q = p + n;
1437c478bd9Sstevel@tonic-gate for (pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)
144e29394bdSmike_s /* NULL */;
1457c478bd9Sstevel@tonic-gate if (pp > q)
1467c478bd9Sstevel@tonic-gate return (0); /* no actions */
1477c478bd9Sstevel@tonic-gate p = pp;
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate /* now, find a place for the elements from p to q, inclusive */
1507c478bd9Sstevel@tonic-gate /* for( rr=amem; rr<=r; ++rr,++off ){ */ /* try rr */
1517c478bd9Sstevel@tonic-gate rr = amem;
1527c478bd9Sstevel@tonic-gate for (; ; ++rr, ++off) {
1537c478bd9Sstevel@tonic-gate while (rr >= &amem[new_actsize-1])
1547c478bd9Sstevel@tonic-gate exp_act(&rr);
1557c478bd9Sstevel@tonic-gate qq = rr;
1567c478bd9Sstevel@tonic-gate for (pp = p; pp <= q; ++pp, ++qq) {
1577c478bd9Sstevel@tonic-gate if (*pp) {
1587c478bd9Sstevel@tonic-gate diff = qq - rr;
1597c478bd9Sstevel@tonic-gate while (qq >= &amem[new_actsize-1]) {
1607c478bd9Sstevel@tonic-gate exp_act(&rr);
1617c478bd9Sstevel@tonic-gate qq = diff + rr;
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate if (*pp != *qq && *qq != 0)
1647c478bd9Sstevel@tonic-gate goto nextk;
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate /* we have found an acceptable k */
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate if (pkdebug && foutput != NULL)
1717c478bd9Sstevel@tonic-gate (void) fprintf(foutput,
172e29394bdSmike_s "off = %d, k = %" PRIdPTR "\n", off, rr-amem);
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate qq = rr;
1757c478bd9Sstevel@tonic-gate for (pp = p; pp <= q; ++pp, ++qq) {
1767c478bd9Sstevel@tonic-gate if (*pp) {
1777c478bd9Sstevel@tonic-gate diff = qq - rr;
1787c478bd9Sstevel@tonic-gate while (qq >= &amem[new_actsize-1]) {
1797c478bd9Sstevel@tonic-gate exp_act(&rr);
1807c478bd9Sstevel@tonic-gate qq = diff + rr;
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate if (qq > memp)
1837c478bd9Sstevel@tonic-gate memp = qq;
1847c478bd9Sstevel@tonic-gate *qq = *pp;
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate if (pkdebug && foutput != NULL) {
1887c478bd9Sstevel@tonic-gate for (pp = amem; pp <= memp; pp += 10) {
1897c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "\t");
1907c478bd9Sstevel@tonic-gate for (qq = pp; qq <= pp + 9; ++qq)
1917c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "%d ", *qq);
1927c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "\n");
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate }
1957c478bd9Sstevel@tonic-gate return (off);
1967c478bd9Sstevel@tonic-gate nextk:;
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate /* error("no space in action table" ); */
1997c478bd9Sstevel@tonic-gate /* NOTREACHED */
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate void
go2out()2037c478bd9Sstevel@tonic-gate go2out()
2047c478bd9Sstevel@tonic-gate {
2057c478bd9Sstevel@tonic-gate /* output the gotos for the nontermninals */
2067c478bd9Sstevel@tonic-gate int i, j, k, best, count, cbest, times;
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate (void) fprintf(ftemp, "$\n"); /* mark begining of gotos */
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate for (i = 1; i <= nnonter; ++i) {
2117c478bd9Sstevel@tonic-gate go2gen(i);
2127c478bd9Sstevel@tonic-gate /* find the best one to make default */
2137c478bd9Sstevel@tonic-gate best = -1;
2147c478bd9Sstevel@tonic-gate times = 0;
2157c478bd9Sstevel@tonic-gate for (j = 0; j < nstate; ++j) { /* is j the most frequent */
2167c478bd9Sstevel@tonic-gate if (tystate[j] == 0)
2177c478bd9Sstevel@tonic-gate continue;
2187c478bd9Sstevel@tonic-gate if (tystate[j] == best)
2197c478bd9Sstevel@tonic-gate continue;
2207c478bd9Sstevel@tonic-gate /* is tystate[j] the most frequent */
2217c478bd9Sstevel@tonic-gate count = 0;
2227c478bd9Sstevel@tonic-gate cbest = tystate[j];
2237c478bd9Sstevel@tonic-gate for (k = j; k < nstate; ++k)
2247c478bd9Sstevel@tonic-gate if (tystate[k] == cbest)
2257c478bd9Sstevel@tonic-gate ++count;
2267c478bd9Sstevel@tonic-gate if (count > times) {
2277c478bd9Sstevel@tonic-gate best = cbest;
2287c478bd9Sstevel@tonic-gate times = count;
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate }
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate /* best is now the default entry */
2337c478bd9Sstevel@tonic-gate zzgobest += (times-1);
2347c478bd9Sstevel@tonic-gate for (j = 0; j < nstate; ++j) {
2357c478bd9Sstevel@tonic-gate if (tystate[j] != 0 && tystate[j] != best) {
2367c478bd9Sstevel@tonic-gate (void) fprintf(ftemp, "%d,%d,", j, tystate[j]);
2377c478bd9Sstevel@tonic-gate zzgoent += 1;
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate /* now, the default */
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate zzgoent += 1;
2447c478bd9Sstevel@tonic-gate (void) fprintf(ftemp, "%d\n", best);
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate static int g2debug = 0;
go2gen(int c)250e29394bdSmike_s static void go2gen(int c)
2517c478bd9Sstevel@tonic-gate {
2527c478bd9Sstevel@tonic-gate /* output the gotos for nonterminal c */
2537c478bd9Sstevel@tonic-gate int i, work, cc;
2547c478bd9Sstevel@tonic-gate ITEM *p, *q;
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate /* first, find nonterminals with gotos on c */
2577c478bd9Sstevel@tonic-gate aryfil(temp1, nnonter + 1, 0);
2587c478bd9Sstevel@tonic-gate temp1[c] = 1;
2597c478bd9Sstevel@tonic-gate
2607c478bd9Sstevel@tonic-gate work = 1;
2617c478bd9Sstevel@tonic-gate while (work) {
2627c478bd9Sstevel@tonic-gate work = 0;
2637c478bd9Sstevel@tonic-gate PLOOP(0, i) {
2647c478bd9Sstevel@tonic-gate if ((cc = prdptr[i][1] - NTBASE) >= 0) {
2657c478bd9Sstevel@tonic-gate /* cc is a nonterminal */
2667c478bd9Sstevel@tonic-gate if (temp1[cc] != 0) {
2677c478bd9Sstevel@tonic-gate /*
2687c478bd9Sstevel@tonic-gate * cc has a goto on c
2697c478bd9Sstevel@tonic-gate * thus, the left side of
2707c478bd9Sstevel@tonic-gate * production i does too.
2717c478bd9Sstevel@tonic-gate */
2727c478bd9Sstevel@tonic-gate cc = *prdptr[i] - NTBASE;
2737c478bd9Sstevel@tonic-gate if (temp1[cc] == 0) {
2747c478bd9Sstevel@tonic-gate work = 1;
2757c478bd9Sstevel@tonic-gate temp1[cc] = 1;
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate if (g2debug && foutput != NULL) {
285*1dd08564Sab196087 (void) fprintf(foutput, WSFMT("%ws: gotos on "),
286*1dd08564Sab196087 nontrst[c].name);
2877c478bd9Sstevel@tonic-gate NTLOOP(i) if (temp1[i])
288*1dd08564Sab196087 (void) fprintf(foutput, WSFMT("%ws "), nontrst[i].name);
2897c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "\n");
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate /* now, go through and put gotos into tystate */
2937c478bd9Sstevel@tonic-gate aryfil(tystate, nstate, 0);
2947c478bd9Sstevel@tonic-gate SLOOP(i) {
2957c478bd9Sstevel@tonic-gate ITMLOOP(i, p, q) {
2967c478bd9Sstevel@tonic-gate if ((cc = *p->pitem) >= NTBASE) {
2977c478bd9Sstevel@tonic-gate if (temp1[cc -= NTBASE]) {
2987c478bd9Sstevel@tonic-gate /* goto on c is possible */
2997c478bd9Sstevel@tonic-gate tystate[i] = amem[indgo[i] + c];
3007c478bd9Sstevel@tonic-gate break;
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate }
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate
3077c478bd9Sstevel@tonic-gate /* decide a shift/reduce conflict by precedence. */
3087c478bd9Sstevel@tonic-gate static void
precftn(int r,int t,int s)309e29394bdSmike_s precftn(int r, int t, int s)
3107c478bd9Sstevel@tonic-gate {
3117c478bd9Sstevel@tonic-gate
3127c478bd9Sstevel@tonic-gate /*
3137c478bd9Sstevel@tonic-gate * r is a rule number, t a token number
3147c478bd9Sstevel@tonic-gate * the conflict is in state s
3157c478bd9Sstevel@tonic-gate * temp1[t] is changed to reflect the action
3167c478bd9Sstevel@tonic-gate */
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate int lp, lt, action;
3197c478bd9Sstevel@tonic-gate
3207c478bd9Sstevel@tonic-gate lp = levprd[r];
3217c478bd9Sstevel@tonic-gate lt = toklev[t];
3227c478bd9Sstevel@tonic-gate if (PLEVEL(lt) == 0 || PLEVEL(lp) == 0) {
3237c478bd9Sstevel@tonic-gate /* conflict */
3247c478bd9Sstevel@tonic-gate if (foutput != NULL)
3257c478bd9Sstevel@tonic-gate (void) fprintf(foutput,
326*1dd08564Sab196087 WSFMT("\n%d: shift/reduce conflict"
327*1dd08564Sab196087 " (shift %d, red'n %d) on %ws"),
3287c478bd9Sstevel@tonic-gate s, temp1[t], r, symnam(t));
3297c478bd9Sstevel@tonic-gate ++zzsrconf;
3307c478bd9Sstevel@tonic-gate return;
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate if (PLEVEL(lt) == PLEVEL(lp))
3337c478bd9Sstevel@tonic-gate action = ASSOC(lt) & ~04;
3347c478bd9Sstevel@tonic-gate else if (PLEVEL(lt) > PLEVEL(lp))
3357c478bd9Sstevel@tonic-gate action = RASC; /* shift */
3367c478bd9Sstevel@tonic-gate else
3377c478bd9Sstevel@tonic-gate action = LASC; /* reduce */
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate switch (action) {
3407c478bd9Sstevel@tonic-gate case BASC: /* error action */
3417c478bd9Sstevel@tonic-gate temp1[t] = ERRCODE;
3427c478bd9Sstevel@tonic-gate return;
3437c478bd9Sstevel@tonic-gate case LASC: /* reduce */
3447c478bd9Sstevel@tonic-gate temp1[t] = -r;
3457c478bd9Sstevel@tonic-gate return;
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate static void
wract(int i)350e29394bdSmike_s wract(int i)
3517c478bd9Sstevel@tonic-gate {
3527c478bd9Sstevel@tonic-gate /* output state i */
3537c478bd9Sstevel@tonic-gate /* temp1 has the actions, lastred the default */
3547c478bd9Sstevel@tonic-gate int p, p0, p1;
3557c478bd9Sstevel@tonic-gate int ntimes, tred, count, j;
3567c478bd9Sstevel@tonic-gate int flag;
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate /* find the best choice for lastred */
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate lastred = 0;
3617c478bd9Sstevel@tonic-gate ntimes = 0;
3627c478bd9Sstevel@tonic-gate TLOOP(j) {
3637c478bd9Sstevel@tonic-gate if (temp1[j] >= 0)
3647c478bd9Sstevel@tonic-gate continue;
3657c478bd9Sstevel@tonic-gate if (temp1[j] + lastred == 0)
3667c478bd9Sstevel@tonic-gate continue;
3677c478bd9Sstevel@tonic-gate /* count the number of appearances of temp1[j] */
3687c478bd9Sstevel@tonic-gate count = 0;
3697c478bd9Sstevel@tonic-gate tred = -temp1[j];
3707c478bd9Sstevel@tonic-gate levprd[tred] |= REDFLAG;
3717c478bd9Sstevel@tonic-gate TLOOP(p) {
3727c478bd9Sstevel@tonic-gate if (temp1[p] + tred == 0)
3737c478bd9Sstevel@tonic-gate ++count;
3747c478bd9Sstevel@tonic-gate }
3757c478bd9Sstevel@tonic-gate if (count > ntimes) {
3767c478bd9Sstevel@tonic-gate lastred = tred;
3777c478bd9Sstevel@tonic-gate ntimes = count;
3787c478bd9Sstevel@tonic-gate }
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate
3817c478bd9Sstevel@tonic-gate /*
3827c478bd9Sstevel@tonic-gate * for error recovery, arrange that, if there is a shift on the
3837c478bd9Sstevel@tonic-gate * error recovery token, `error', that the default be the error action
3847c478bd9Sstevel@tonic-gate */
3857c478bd9Sstevel@tonic-gate if (temp1[2] > 0)
3867c478bd9Sstevel@tonic-gate lastred = 0;
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate /* clear out entries in temp1 which equal lastred */
3897c478bd9Sstevel@tonic-gate TLOOP(p) {
3907c478bd9Sstevel@tonic-gate if (temp1[p] + lastred == 0)
3917c478bd9Sstevel@tonic-gate temp1[p] = 0;
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate wrstate(i);
3957c478bd9Sstevel@tonic-gate defact[i] = lastred;
3967c478bd9Sstevel@tonic-gate
3977c478bd9Sstevel@tonic-gate flag = 0;
3987c478bd9Sstevel@tonic-gate TLOOP(p0) {
3997c478bd9Sstevel@tonic-gate if ((p1 = temp1[p0]) != 0) {
4007c478bd9Sstevel@tonic-gate if (p1 < 0) {
4017c478bd9Sstevel@tonic-gate p1 = -p1;
4027c478bd9Sstevel@tonic-gate goto exc;
4037c478bd9Sstevel@tonic-gate } else if (p1 == ACCEPTCODE) {
4047c478bd9Sstevel@tonic-gate p1 = -1;
4057c478bd9Sstevel@tonic-gate goto exc;
4067c478bd9Sstevel@tonic-gate } else if (p1 == ERRCODE) {
4077c478bd9Sstevel@tonic-gate p1 = 0;
4087c478bd9Sstevel@tonic-gate goto exc;
4097c478bd9Sstevel@tonic-gate exc:
4107c478bd9Sstevel@tonic-gate if (flag++ == 0)
4117c478bd9Sstevel@tonic-gate (void) fprintf(ftable, "-1, %d,\n", i);
4127c478bd9Sstevel@tonic-gate (void) fprintf(ftable,
4137c478bd9Sstevel@tonic-gate "\t%d, %d,\n", tokset[p0].value, p1);
4147c478bd9Sstevel@tonic-gate ++zzexcp;
4157c478bd9Sstevel@tonic-gate } else {
4167c478bd9Sstevel@tonic-gate (void) fprintf(ftemp,
4177c478bd9Sstevel@tonic-gate "%d,%d,", tokset[p0].value, p1);
4187c478bd9Sstevel@tonic-gate ++zzacent;
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate }
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate if (flag) {
4237c478bd9Sstevel@tonic-gate defact[i] = -2;
4247c478bd9Sstevel@tonic-gate (void) fprintf(ftable, "\t-2, %d,\n", lastred);
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate (void) fprintf(ftemp, "\n");
4277c478bd9Sstevel@tonic-gate }
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate static void
wrstate(int i)430e29394bdSmike_s wrstate(int i)
4317c478bd9Sstevel@tonic-gate {
4327c478bd9Sstevel@tonic-gate /* writes state i */
433e29394bdSmike_s int j0, j1;
4347c478bd9Sstevel@tonic-gate register ITEM *pp, *qq;
4357c478bd9Sstevel@tonic-gate register WSET *u;
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate if (foutput == NULL)
4387c478bd9Sstevel@tonic-gate return;
4397c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "\nstate %d\n", i);
4407c478bd9Sstevel@tonic-gate ITMLOOP(i, pp, qq) {
441*1dd08564Sab196087 (void) fprintf(foutput, WSFMT("\t%ws\n"), writem(pp->pitem));
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate if (tystate[i] == MUSTLOOKAHEAD) {
4447c478bd9Sstevel@tonic-gate /* print out empty productions in closure */
4457c478bd9Sstevel@tonic-gate WSLOOP(wsets + (pstate[i + 1] - pstate[i]), u) {
4467c478bd9Sstevel@tonic-gate if (*(u->pitem) < 0)
4477c478bd9Sstevel@tonic-gate (void) fprintf(foutput,
448*1dd08564Sab196087 WSFMT("\t%ws\n"), writem(u->pitem));
4497c478bd9Sstevel@tonic-gate }
4507c478bd9Sstevel@tonic-gate }
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate /* check for state equal to another */
4537c478bd9Sstevel@tonic-gate TLOOP(j0) if ((j1 = temp1[j0]) != 0) {
454*1dd08564Sab196087 (void) fprintf(foutput, WSFMT("\n\t%ws "), symnam(j0));
4557c478bd9Sstevel@tonic-gate if (j1 > 0) { /* shift, error, or accept */
4567c478bd9Sstevel@tonic-gate if (j1 == ACCEPTCODE)
4577c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "accept");
4587c478bd9Sstevel@tonic-gate else if (j1 == ERRCODE)
4597c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "error");
4607c478bd9Sstevel@tonic-gate else
4617c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "shift %d", j1);
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate else
4647c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "reduce %d", -j1);
4657c478bd9Sstevel@tonic-gate }
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate /* output the final production */
4687c478bd9Sstevel@tonic-gate if (lastred)
4697c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "\n\t. reduce %d\n\n", lastred);
4707c478bd9Sstevel@tonic-gate else
4717c478bd9Sstevel@tonic-gate (void) fprintf(foutput, "\n\t. error\n\n");
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate /* now, output nonterminal actions */
4747c478bd9Sstevel@tonic-gate j1 = ntokens;
4757c478bd9Sstevel@tonic-gate for (j0 = 1; j0 <= nnonter; ++j0) {
4767c478bd9Sstevel@tonic-gate if (temp1[++j1])
4777c478bd9Sstevel@tonic-gate (void) fprintf(foutput,
478*1dd08564Sab196087 WSFMT("\t%ws goto %d\n"),
4797c478bd9Sstevel@tonic-gate symnam(j0 + NTBASE), temp1[j1]);
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate }
4827c478bd9Sstevel@tonic-gate
4837c478bd9Sstevel@tonic-gate static void
wdef(wchar_t * s,int n)484e29394bdSmike_s wdef(wchar_t *s, int n)
4857c478bd9Sstevel@tonic-gate {
4867c478bd9Sstevel@tonic-gate /* output a definition of s to the value n */
487*1dd08564Sab196087 (void) fprintf(ftable, WSFMT("# define %ws %d\n"), s, n);
4887c478bd9Sstevel@tonic-gate }
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate void
warray(s,v,n)4917c478bd9Sstevel@tonic-gate warray(s, v, n)
4927c478bd9Sstevel@tonic-gate wchar_t *s;
4937c478bd9Sstevel@tonic-gate int *v, n;
4947c478bd9Sstevel@tonic-gate {
495e29394bdSmike_s int i;
496*1dd08564Sab196087 (void) fprintf(ftable, WSFMT("static YYCONST yytabelem %ws[]={\n"), s);
4977c478bd9Sstevel@tonic-gate for (i = 0; i < n; ) {
4987c478bd9Sstevel@tonic-gate if (i % 10 == 0)
4997c478bd9Sstevel@tonic-gate (void) fprintf(ftable, "\n");
5007c478bd9Sstevel@tonic-gate (void) fprintf(ftable, "%6d", v[i]);
5017c478bd9Sstevel@tonic-gate if (++i == n)
5027c478bd9Sstevel@tonic-gate (void) fprintf(ftable, " };\n");
5037c478bd9Sstevel@tonic-gate else
5047c478bd9Sstevel@tonic-gate (void) fprintf(ftable, ",");
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate }
5077c478bd9Sstevel@tonic-gate
5087c478bd9Sstevel@tonic-gate void
hideprod()5097c478bd9Sstevel@tonic-gate hideprod()
5107c478bd9Sstevel@tonic-gate {
5117c478bd9Sstevel@tonic-gate /*
5127c478bd9Sstevel@tonic-gate * in order to free up the mem and amem arrays for the optimizer,
5137c478bd9Sstevel@tonic-gate * and still be able to output yyr1, etc., after the sizes of
5147c478bd9Sstevel@tonic-gate * the action array is known, we hide the nonterminals
5157c478bd9Sstevel@tonic-gate * derived by productions in levprd.
5167c478bd9Sstevel@tonic-gate */
5177c478bd9Sstevel@tonic-gate
518e29394bdSmike_s int i, j;
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate j = 0;
5217c478bd9Sstevel@tonic-gate levprd[0] = 0;
5227c478bd9Sstevel@tonic-gate PLOOP(1, i) {
5237c478bd9Sstevel@tonic-gate if (!(levprd[i] & REDFLAG)) {
5247c478bd9Sstevel@tonic-gate ++j;
5257c478bd9Sstevel@tonic-gate if (foutput != NULL) {
5267c478bd9Sstevel@tonic-gate (void) fprintf(foutput,
527*1dd08564Sab196087 WSFMT("Rule not reduced: %ws\n"),
5287c478bd9Sstevel@tonic-gate writem(prdptr[i]));
5297c478bd9Sstevel@tonic-gate }
5307c478bd9Sstevel@tonic-gate }
5317c478bd9Sstevel@tonic-gate levprd[i] = *prdptr[i] - NTBASE;
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate if (j)
5347c478bd9Sstevel@tonic-gate /*
5357c478bd9Sstevel@tonic-gate * TRANSLATION_NOTE -- This is a message from yacc.
5367c478bd9Sstevel@tonic-gate * Check how 'reduced' is translated in yacc man page/document.
5377c478bd9Sstevel@tonic-gate */
538*1dd08564Sab196087 (void) fprintf(stderr,
539*1dd08564Sab196087 gettext("%d rules never reduced\n"),
5407c478bd9Sstevel@tonic-gate j);
5417c478bd9Sstevel@tonic-gate }
5427c478bd9Sstevel@tonic-gate
5437c478bd9Sstevel@tonic-gate
5447c478bd9Sstevel@tonic-gate static int
cmpmbchars(p,q)5457c478bd9Sstevel@tonic-gate cmpmbchars(p, q)
5467c478bd9Sstevel@tonic-gate MBCLIT *p, *q;
5477c478bd9Sstevel@tonic-gate {
5487c478bd9Sstevel@tonic-gate /* Compare two MBLITs. */
5497c478bd9Sstevel@tonic-gate return ((p->character) - (q->character));
5507c478bd9Sstevel@tonic-gate }
5517c478bd9Sstevel@tonic-gate
5527c478bd9Sstevel@tonic-gate static void
wrmbchars()5537c478bd9Sstevel@tonic-gate wrmbchars()
5547c478bd9Sstevel@tonic-gate {
5557c478bd9Sstevel@tonic-gate int i;
5567c478bd9Sstevel@tonic-gate wdef(L"YYNMBCHARS", nmbchars);
5577c478bd9Sstevel@tonic-gate qsort(mbchars, nmbchars, sizeof (*mbchars),
5587c478bd9Sstevel@tonic-gate (int (*)(const void *, const void *))cmpmbchars);
5597c478bd9Sstevel@tonic-gate (void) fprintf(ftable,
5607c478bd9Sstevel@tonic-gate "static struct{\n\twchar_t character;"
5617c478bd9Sstevel@tonic-gate "\n\tint tvalue;\n}yymbchars[YYNMBCHARS]={\n");
5627c478bd9Sstevel@tonic-gate for (i = 0; i < nmbchars; ++i) {
5637c478bd9Sstevel@tonic-gate (void) fprintf(ftable, "\t{%#x,%d}",
564e29394bdSmike_s (int)mbchars[i].character, mbchars[i].tvalue);
5657c478bd9Sstevel@tonic-gate if (i < nmbchars - 1) {
5667c478bd9Sstevel@tonic-gate /* Not the last. */
5677c478bd9Sstevel@tonic-gate (void) fprintf(ftable, ",\n");
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate }
5707c478bd9Sstevel@tonic-gate (void) fprintf(ftable, "\n};\n");
5717c478bd9Sstevel@tonic-gate }
572