10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*6951Sab196087 * Common Development and Distribution License (the "License").
6*6951Sab196087 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*6951Sab196087 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */
270Sstevel@tonic-gate /* All Rights Reserved */
280Sstevel@tonic-gate
290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
300Sstevel@tonic-gate
31100Smike_s #include "dextern.h"
320Sstevel@tonic-gate
330Sstevel@tonic-gate static void go2gen(int);
340Sstevel@tonic-gate static void precftn(int, int, int);
350Sstevel@tonic-gate static void wract(int);
360Sstevel@tonic-gate static void wrstate(int);
370Sstevel@tonic-gate static void wdef(wchar_t *, int);
380Sstevel@tonic-gate static void wrmbchars(void);
390Sstevel@tonic-gate /* important local variables */
400Sstevel@tonic-gate static int lastred; /* number of the last reduction of a state */
410Sstevel@tonic-gate int *defact;
420Sstevel@tonic-gate extern int *toklev;
430Sstevel@tonic-gate extern int cwp;
440Sstevel@tonic-gate
450Sstevel@tonic-gate /* print the output for the states */
460Sstevel@tonic-gate void
output()470Sstevel@tonic-gate output()
480Sstevel@tonic-gate {
490Sstevel@tonic-gate int i, k, c;
500Sstevel@tonic-gate register WSET *u, *v;
510Sstevel@tonic-gate
520Sstevel@tonic-gate (void) fprintf(ftable, "static YYCONST yytabelem yyexca[] ={\n");
530Sstevel@tonic-gate
540Sstevel@tonic-gate SLOOP(i) { /* output the stuff for state i */
550Sstevel@tonic-gate nolook = !(tystate[i] == MUSTLOOKAHEAD);
560Sstevel@tonic-gate closure(i);
570Sstevel@tonic-gate /* output actions */
580Sstevel@tonic-gate nolook = 1;
590Sstevel@tonic-gate aryfil(temp1, ntoksz+nnontersz+1, 0);
600Sstevel@tonic-gate WSLOOP(wsets, u) {
610Sstevel@tonic-gate c = *(u->pitem);
620Sstevel@tonic-gate if (c > 1 && c < NTBASE && temp1[c] == 0) {
630Sstevel@tonic-gate WSLOOP(u, v) {
640Sstevel@tonic-gate if (c == *(v->pitem))
650Sstevel@tonic-gate putitem(v->pitem + 1,
66*6951Sab196087 (LOOKSETS *)0);
670Sstevel@tonic-gate }
680Sstevel@tonic-gate temp1[c] = state(c);
690Sstevel@tonic-gate } else if (c > NTBASE &&
70*6951Sab196087 temp1[(c -= NTBASE) + ntokens] == 0) {
710Sstevel@tonic-gate temp1[c + ntokens] = amem[indgo[i] + c];
720Sstevel@tonic-gate }
730Sstevel@tonic-gate }
740Sstevel@tonic-gate if (i == 1)
750Sstevel@tonic-gate temp1[1] = ACCEPTCODE;
760Sstevel@tonic-gate /* now, we have the shifts; look at the reductions */
770Sstevel@tonic-gate lastred = 0;
780Sstevel@tonic-gate WSLOOP(wsets, u) {
790Sstevel@tonic-gate c = *(u->pitem);
800Sstevel@tonic-gate if (c <= 0) { /* reduction */
810Sstevel@tonic-gate lastred = -c;
820Sstevel@tonic-gate TLOOP(k) {
830Sstevel@tonic-gate if (BIT(u->ws.lset, k)) {
840Sstevel@tonic-gate if (temp1[k] == 0)
850Sstevel@tonic-gate temp1[k] = c;
860Sstevel@tonic-gate else if (temp1[k] < 0) {
870Sstevel@tonic-gate /*
880Sstevel@tonic-gate * reduce/reduce
890Sstevel@tonic-gate * conflict
900Sstevel@tonic-gate */
91*6951Sab196087 /* BEGIN CSTYLED */
920Sstevel@tonic-gate if (foutput != NULL)
930Sstevel@tonic-gate (void) fprintf(foutput,
94*6951Sab196087 WSFMT("\n%d: reduce/reduce conflict"
95*6951Sab196087 " (red'ns %d and %d ) on %ws"),
960Sstevel@tonic-gate i, -temp1[k],
970Sstevel@tonic-gate lastred, symnam(k));
980Sstevel@tonic-gate if (-temp1[k] > lastred)
990Sstevel@tonic-gate temp1[k] = -lastred;
1000Sstevel@tonic-gate ++zzrrconf;
101*6951Sab196087 /* END CSTYLED */
1020Sstevel@tonic-gate } else
1030Sstevel@tonic-gate /*
1040Sstevel@tonic-gate * potentia
1050Sstevel@tonic-gate * shift/reduce
1060Sstevel@tonic-gate * conflict.
1070Sstevel@tonic-gate */
1080Sstevel@tonic-gate precftn(lastred, k, i);
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate }
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate }
1130Sstevel@tonic-gate wract(i);
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate (void) fprintf(ftable, "\t};\n");
1170Sstevel@tonic-gate wdef(L"YYNPROD", nprod);
1180Sstevel@tonic-gate if (nmbchars > 0) {
1190Sstevel@tonic-gate wrmbchars();
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate static int pkdebug = 0;
124100Smike_s int
apack(p,n)1250Sstevel@tonic-gate apack(p, n)
1260Sstevel@tonic-gate int *p;
127100Smike_s int n;
1280Sstevel@tonic-gate {
1290Sstevel@tonic-gate /* pack state i from temp1 into amem */
1300Sstevel@tonic-gate int off;
131100Smike_s int *pp, *qq;
132100Smike_s int *q, *rr;
1330Sstevel@tonic-gate int diff;
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate /*
1360Sstevel@tonic-gate * we don't need to worry about checking because we
1370Sstevel@tonic-gate * we will only look up entries known to be there...
1380Sstevel@tonic-gate */
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate /* eliminate leading and trailing 0's */
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate q = p + n;
1430Sstevel@tonic-gate for (pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)
144100Smike_s /* NULL */;
1450Sstevel@tonic-gate if (pp > q)
1460Sstevel@tonic-gate return (0); /* no actions */
1470Sstevel@tonic-gate p = pp;
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate /* now, find a place for the elements from p to q, inclusive */
1500Sstevel@tonic-gate /* for( rr=amem; rr<=r; ++rr,++off ){ */ /* try rr */
1510Sstevel@tonic-gate rr = amem;
1520Sstevel@tonic-gate for (; ; ++rr, ++off) {
1530Sstevel@tonic-gate while (rr >= &amem[new_actsize-1])
1540Sstevel@tonic-gate exp_act(&rr);
1550Sstevel@tonic-gate qq = rr;
1560Sstevel@tonic-gate for (pp = p; pp <= q; ++pp, ++qq) {
1570Sstevel@tonic-gate if (*pp) {
1580Sstevel@tonic-gate diff = qq - rr;
1590Sstevel@tonic-gate while (qq >= &amem[new_actsize-1]) {
1600Sstevel@tonic-gate exp_act(&rr);
1610Sstevel@tonic-gate qq = diff + rr;
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate if (*pp != *qq && *qq != 0)
1640Sstevel@tonic-gate goto nextk;
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate /* we have found an acceptable k */
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate if (pkdebug && foutput != NULL)
1710Sstevel@tonic-gate (void) fprintf(foutput,
172100Smike_s "off = %d, k = %" PRIdPTR "\n", off, rr-amem);
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate qq = rr;
1750Sstevel@tonic-gate for (pp = p; pp <= q; ++pp, ++qq) {
1760Sstevel@tonic-gate if (*pp) {
1770Sstevel@tonic-gate diff = qq - rr;
1780Sstevel@tonic-gate while (qq >= &amem[new_actsize-1]) {
1790Sstevel@tonic-gate exp_act(&rr);
1800Sstevel@tonic-gate qq = diff + rr;
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate if (qq > memp)
1830Sstevel@tonic-gate memp = qq;
1840Sstevel@tonic-gate *qq = *pp;
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate if (pkdebug && foutput != NULL) {
1880Sstevel@tonic-gate for (pp = amem; pp <= memp; pp += 10) {
1890Sstevel@tonic-gate (void) fprintf(foutput, "\t");
1900Sstevel@tonic-gate for (qq = pp; qq <= pp + 9; ++qq)
1910Sstevel@tonic-gate (void) fprintf(foutput, "%d ", *qq);
1920Sstevel@tonic-gate (void) fprintf(foutput, "\n");
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate return (off);
1960Sstevel@tonic-gate nextk:;
1970Sstevel@tonic-gate }
1980Sstevel@tonic-gate /* error("no space in action table" ); */
1990Sstevel@tonic-gate /* NOTREACHED */
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate void
go2out()2030Sstevel@tonic-gate go2out()
2040Sstevel@tonic-gate {
2050Sstevel@tonic-gate /* output the gotos for the nontermninals */
2060Sstevel@tonic-gate int i, j, k, best, count, cbest, times;
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate (void) fprintf(ftemp, "$\n"); /* mark begining of gotos */
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate for (i = 1; i <= nnonter; ++i) {
2110Sstevel@tonic-gate go2gen(i);
2120Sstevel@tonic-gate /* find the best one to make default */
2130Sstevel@tonic-gate best = -1;
2140Sstevel@tonic-gate times = 0;
2150Sstevel@tonic-gate for (j = 0; j < nstate; ++j) { /* is j the most frequent */
2160Sstevel@tonic-gate if (tystate[j] == 0)
2170Sstevel@tonic-gate continue;
2180Sstevel@tonic-gate if (tystate[j] == best)
2190Sstevel@tonic-gate continue;
2200Sstevel@tonic-gate /* is tystate[j] the most frequent */
2210Sstevel@tonic-gate count = 0;
2220Sstevel@tonic-gate cbest = tystate[j];
2230Sstevel@tonic-gate for (k = j; k < nstate; ++k)
2240Sstevel@tonic-gate if (tystate[k] == cbest)
2250Sstevel@tonic-gate ++count;
2260Sstevel@tonic-gate if (count > times) {
2270Sstevel@tonic-gate best = cbest;
2280Sstevel@tonic-gate times = count;
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate /* best is now the default entry */
2330Sstevel@tonic-gate zzgobest += (times-1);
2340Sstevel@tonic-gate for (j = 0; j < nstate; ++j) {
2350Sstevel@tonic-gate if (tystate[j] != 0 && tystate[j] != best) {
2360Sstevel@tonic-gate (void) fprintf(ftemp, "%d,%d,", j, tystate[j]);
2370Sstevel@tonic-gate zzgoent += 1;
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate /* now, the default */
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate zzgoent += 1;
2440Sstevel@tonic-gate (void) fprintf(ftemp, "%d\n", best);
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate }
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate static int g2debug = 0;
go2gen(int c)250100Smike_s static void go2gen(int c)
2510Sstevel@tonic-gate {
2520Sstevel@tonic-gate /* output the gotos for nonterminal c */
2530Sstevel@tonic-gate int i, work, cc;
2540Sstevel@tonic-gate ITEM *p, *q;
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate /* first, find nonterminals with gotos on c */
2570Sstevel@tonic-gate aryfil(temp1, nnonter + 1, 0);
2580Sstevel@tonic-gate temp1[c] = 1;
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate work = 1;
2610Sstevel@tonic-gate while (work) {
2620Sstevel@tonic-gate work = 0;
2630Sstevel@tonic-gate PLOOP(0, i) {
2640Sstevel@tonic-gate if ((cc = prdptr[i][1] - NTBASE) >= 0) {
2650Sstevel@tonic-gate /* cc is a nonterminal */
2660Sstevel@tonic-gate if (temp1[cc] != 0) {
2670Sstevel@tonic-gate /*
2680Sstevel@tonic-gate * cc has a goto on c
2690Sstevel@tonic-gate * thus, the left side of
2700Sstevel@tonic-gate * production i does too.
2710Sstevel@tonic-gate */
2720Sstevel@tonic-gate cc = *prdptr[i] - NTBASE;
2730Sstevel@tonic-gate if (temp1[cc] == 0) {
2740Sstevel@tonic-gate work = 1;
2750Sstevel@tonic-gate temp1[cc] = 1;
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate }
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate }
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate if (g2debug && foutput != NULL) {
285*6951Sab196087 (void) fprintf(foutput, WSFMT("%ws: gotos on "),
286*6951Sab196087 nontrst[c].name);
2870Sstevel@tonic-gate NTLOOP(i) if (temp1[i])
288*6951Sab196087 (void) fprintf(foutput, WSFMT("%ws "), nontrst[i].name);
2890Sstevel@tonic-gate (void) fprintf(foutput, "\n");
2900Sstevel@tonic-gate }
2910Sstevel@tonic-gate
2920Sstevel@tonic-gate /* now, go through and put gotos into tystate */
2930Sstevel@tonic-gate aryfil(tystate, nstate, 0);
2940Sstevel@tonic-gate SLOOP(i) {
2950Sstevel@tonic-gate ITMLOOP(i, p, q) {
2960Sstevel@tonic-gate if ((cc = *p->pitem) >= NTBASE) {
2970Sstevel@tonic-gate if (temp1[cc -= NTBASE]) {
2980Sstevel@tonic-gate /* goto on c is possible */
2990Sstevel@tonic-gate tystate[i] = amem[indgo[i] + c];
3000Sstevel@tonic-gate break;
3010Sstevel@tonic-gate }
3020Sstevel@tonic-gate }
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate }
3050Sstevel@tonic-gate }
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate /* decide a shift/reduce conflict by precedence. */
3080Sstevel@tonic-gate static void
precftn(int r,int t,int s)309100Smike_s precftn(int r, int t, int s)
3100Sstevel@tonic-gate {
3110Sstevel@tonic-gate
3120Sstevel@tonic-gate /*
3130Sstevel@tonic-gate * r is a rule number, t a token number
3140Sstevel@tonic-gate * the conflict is in state s
3150Sstevel@tonic-gate * temp1[t] is changed to reflect the action
3160Sstevel@tonic-gate */
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate int lp, lt, action;
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate lp = levprd[r];
3210Sstevel@tonic-gate lt = toklev[t];
3220Sstevel@tonic-gate if (PLEVEL(lt) == 0 || PLEVEL(lp) == 0) {
3230Sstevel@tonic-gate /* conflict */
3240Sstevel@tonic-gate if (foutput != NULL)
3250Sstevel@tonic-gate (void) fprintf(foutput,
326*6951Sab196087 WSFMT("\n%d: shift/reduce conflict"
327*6951Sab196087 " (shift %d, red'n %d) on %ws"),
328*6951Sab196087 s, temp1[t], r, symnam(t));
3290Sstevel@tonic-gate ++zzsrconf;
3300Sstevel@tonic-gate return;
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate if (PLEVEL(lt) == PLEVEL(lp))
3330Sstevel@tonic-gate action = ASSOC(lt) & ~04;
3340Sstevel@tonic-gate else if (PLEVEL(lt) > PLEVEL(lp))
3350Sstevel@tonic-gate action = RASC; /* shift */
3360Sstevel@tonic-gate else
3370Sstevel@tonic-gate action = LASC; /* reduce */
3380Sstevel@tonic-gate
3390Sstevel@tonic-gate switch (action) {
3400Sstevel@tonic-gate case BASC: /* error action */
3410Sstevel@tonic-gate temp1[t] = ERRCODE;
3420Sstevel@tonic-gate return;
3430Sstevel@tonic-gate case LASC: /* reduce */
3440Sstevel@tonic-gate temp1[t] = -r;
3450Sstevel@tonic-gate return;
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate static void
wract(int i)350100Smike_s wract(int i)
3510Sstevel@tonic-gate {
3520Sstevel@tonic-gate /* output state i */
3530Sstevel@tonic-gate /* temp1 has the actions, lastred the default */
3540Sstevel@tonic-gate int p, p0, p1;
3550Sstevel@tonic-gate int ntimes, tred, count, j;
3560Sstevel@tonic-gate int flag;
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate /* find the best choice for lastred */
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate lastred = 0;
3610Sstevel@tonic-gate ntimes = 0;
3620Sstevel@tonic-gate TLOOP(j) {
3630Sstevel@tonic-gate if (temp1[j] >= 0)
3640Sstevel@tonic-gate continue;
3650Sstevel@tonic-gate if (temp1[j] + lastred == 0)
3660Sstevel@tonic-gate continue;
3670Sstevel@tonic-gate /* count the number of appearances of temp1[j] */
3680Sstevel@tonic-gate count = 0;
3690Sstevel@tonic-gate tred = -temp1[j];
3700Sstevel@tonic-gate levprd[tred] |= REDFLAG;
3710Sstevel@tonic-gate TLOOP(p) {
3720Sstevel@tonic-gate if (temp1[p] + tred == 0)
3730Sstevel@tonic-gate ++count;
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate if (count > ntimes) {
3760Sstevel@tonic-gate lastred = tred;
3770Sstevel@tonic-gate ntimes = count;
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate /*
3820Sstevel@tonic-gate * for error recovery, arrange that, if there is a shift on the
3830Sstevel@tonic-gate * error recovery token, `error', that the default be the error action
3840Sstevel@tonic-gate */
3850Sstevel@tonic-gate if (temp1[2] > 0)
3860Sstevel@tonic-gate lastred = 0;
3870Sstevel@tonic-gate
3880Sstevel@tonic-gate /* clear out entries in temp1 which equal lastred */
3890Sstevel@tonic-gate TLOOP(p) {
3900Sstevel@tonic-gate if (temp1[p] + lastred == 0)
3910Sstevel@tonic-gate temp1[p] = 0;
3920Sstevel@tonic-gate }
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate wrstate(i);
3950Sstevel@tonic-gate defact[i] = lastred;
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate flag = 0;
3980Sstevel@tonic-gate TLOOP(p0) {
3990Sstevel@tonic-gate if ((p1 = temp1[p0]) != 0) {
4000Sstevel@tonic-gate if (p1 < 0) {
4010Sstevel@tonic-gate p1 = -p1;
4020Sstevel@tonic-gate goto exc;
4030Sstevel@tonic-gate } else if (p1 == ACCEPTCODE) {
4040Sstevel@tonic-gate p1 = -1;
4050Sstevel@tonic-gate goto exc;
4060Sstevel@tonic-gate } else if (p1 == ERRCODE) {
4070Sstevel@tonic-gate p1 = 0;
4080Sstevel@tonic-gate goto exc;
4090Sstevel@tonic-gate exc:
4100Sstevel@tonic-gate if (flag++ == 0)
4110Sstevel@tonic-gate (void) fprintf(ftable, "-1, %d,\n", i);
4120Sstevel@tonic-gate (void) fprintf(ftable,
413*6951Sab196087 "\t%d, %d,\n", tokset[p0].value, p1);
4140Sstevel@tonic-gate ++zzexcp;
4150Sstevel@tonic-gate } else {
4160Sstevel@tonic-gate (void) fprintf(ftemp,
417*6951Sab196087 "%d,%d,", tokset[p0].value, p1);
4180Sstevel@tonic-gate ++zzacent;
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate }
4220Sstevel@tonic-gate if (flag) {
4230Sstevel@tonic-gate defact[i] = -2;
4240Sstevel@tonic-gate (void) fprintf(ftable, "\t-2, %d,\n", lastred);
4250Sstevel@tonic-gate }
4260Sstevel@tonic-gate (void) fprintf(ftemp, "\n");
4270Sstevel@tonic-gate }
4280Sstevel@tonic-gate
4290Sstevel@tonic-gate static void
wrstate(int i)430100Smike_s wrstate(int i)
4310Sstevel@tonic-gate {
4320Sstevel@tonic-gate /* writes state i */
433100Smike_s int j0, j1;
4340Sstevel@tonic-gate register ITEM *pp, *qq;
4350Sstevel@tonic-gate register WSET *u;
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate if (foutput == NULL)
4380Sstevel@tonic-gate return;
4390Sstevel@tonic-gate (void) fprintf(foutput, "\nstate %d\n", i);
4400Sstevel@tonic-gate ITMLOOP(i, pp, qq) {
441*6951Sab196087 (void) fprintf(foutput, WSFMT("\t%ws\n"), writem(pp->pitem));
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate if (tystate[i] == MUSTLOOKAHEAD) {
4440Sstevel@tonic-gate /* print out empty productions in closure */
4450Sstevel@tonic-gate WSLOOP(wsets + (pstate[i + 1] - pstate[i]), u) {
4460Sstevel@tonic-gate if (*(u->pitem) < 0)
4470Sstevel@tonic-gate (void) fprintf(foutput,
448*6951Sab196087 WSFMT("\t%ws\n"), writem(u->pitem));
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate }
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate /* check for state equal to another */
4530Sstevel@tonic-gate TLOOP(j0) if ((j1 = temp1[j0]) != 0) {
454*6951Sab196087 (void) fprintf(foutput, WSFMT("\n\t%ws "), symnam(j0));
4550Sstevel@tonic-gate if (j1 > 0) { /* shift, error, or accept */
4560Sstevel@tonic-gate if (j1 == ACCEPTCODE)
4570Sstevel@tonic-gate (void) fprintf(foutput, "accept");
4580Sstevel@tonic-gate else if (j1 == ERRCODE)
4590Sstevel@tonic-gate (void) fprintf(foutput, "error");
4600Sstevel@tonic-gate else
4610Sstevel@tonic-gate (void) fprintf(foutput, "shift %d", j1);
4620Sstevel@tonic-gate }
4630Sstevel@tonic-gate else
4640Sstevel@tonic-gate (void) fprintf(foutput, "reduce %d", -j1);
4650Sstevel@tonic-gate }
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate /* output the final production */
4680Sstevel@tonic-gate if (lastred)
4690Sstevel@tonic-gate (void) fprintf(foutput, "\n\t. reduce %d\n\n", lastred);
4700Sstevel@tonic-gate else
4710Sstevel@tonic-gate (void) fprintf(foutput, "\n\t. error\n\n");
4720Sstevel@tonic-gate
4730Sstevel@tonic-gate /* now, output nonterminal actions */
4740Sstevel@tonic-gate j1 = ntokens;
4750Sstevel@tonic-gate for (j0 = 1; j0 <= nnonter; ++j0) {
4760Sstevel@tonic-gate if (temp1[++j1])
4770Sstevel@tonic-gate (void) fprintf(foutput,
478*6951Sab196087 WSFMT("\t%ws goto %d\n"),
479*6951Sab196087 symnam(j0 + NTBASE), temp1[j1]);
4800Sstevel@tonic-gate }
4810Sstevel@tonic-gate }
4820Sstevel@tonic-gate
4830Sstevel@tonic-gate static void
wdef(wchar_t * s,int n)484100Smike_s wdef(wchar_t *s, int n)
4850Sstevel@tonic-gate {
4860Sstevel@tonic-gate /* output a definition of s to the value n */
487*6951Sab196087 (void) fprintf(ftable, WSFMT("# define %ws %d\n"), s, n);
4880Sstevel@tonic-gate }
4890Sstevel@tonic-gate
4900Sstevel@tonic-gate void
warray(s,v,n)4910Sstevel@tonic-gate warray(s, v, n)
4920Sstevel@tonic-gate wchar_t *s;
4930Sstevel@tonic-gate int *v, n;
4940Sstevel@tonic-gate {
495100Smike_s int i;
496*6951Sab196087 (void) fprintf(ftable, WSFMT("static YYCONST yytabelem %ws[]={\n"), s);
4970Sstevel@tonic-gate for (i = 0; i < n; ) {
4980Sstevel@tonic-gate if (i % 10 == 0)
4990Sstevel@tonic-gate (void) fprintf(ftable, "\n");
5000Sstevel@tonic-gate (void) fprintf(ftable, "%6d", v[i]);
5010Sstevel@tonic-gate if (++i == n)
5020Sstevel@tonic-gate (void) fprintf(ftable, " };\n");
5030Sstevel@tonic-gate else
5040Sstevel@tonic-gate (void) fprintf(ftable, ",");
5050Sstevel@tonic-gate }
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate void
hideprod()5090Sstevel@tonic-gate hideprod()
5100Sstevel@tonic-gate {
5110Sstevel@tonic-gate /*
5120Sstevel@tonic-gate * in order to free up the mem and amem arrays for the optimizer,
5130Sstevel@tonic-gate * and still be able to output yyr1, etc., after the sizes of
5140Sstevel@tonic-gate * the action array is known, we hide the nonterminals
5150Sstevel@tonic-gate * derived by productions in levprd.
5160Sstevel@tonic-gate */
5170Sstevel@tonic-gate
518100Smike_s int i, j;
5190Sstevel@tonic-gate
5200Sstevel@tonic-gate j = 0;
5210Sstevel@tonic-gate levprd[0] = 0;
5220Sstevel@tonic-gate PLOOP(1, i) {
5230Sstevel@tonic-gate if (!(levprd[i] & REDFLAG)) {
5240Sstevel@tonic-gate ++j;
5250Sstevel@tonic-gate if (foutput != NULL) {
5260Sstevel@tonic-gate (void) fprintf(foutput,
527*6951Sab196087 WSFMT("Rule not reduced: %ws\n"),
528*6951Sab196087 writem(prdptr[i]));
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate }
5310Sstevel@tonic-gate levprd[i] = *prdptr[i] - NTBASE;
5320Sstevel@tonic-gate }
5330Sstevel@tonic-gate if (j)
5340Sstevel@tonic-gate /*
5350Sstevel@tonic-gate * TRANSLATION_NOTE -- This is a message from yacc.
5360Sstevel@tonic-gate * Check how 'reduced' is translated in yacc man page/document.
5370Sstevel@tonic-gate */
538*6951Sab196087 (void) fprintf(stderr,
539*6951Sab196087 gettext("%d rules never reduced\n"),
540*6951Sab196087 j);
5410Sstevel@tonic-gate }
5420Sstevel@tonic-gate
5430Sstevel@tonic-gate
5440Sstevel@tonic-gate static int
cmpmbchars(p,q)5450Sstevel@tonic-gate cmpmbchars(p, q)
5460Sstevel@tonic-gate MBCLIT *p, *q;
5470Sstevel@tonic-gate {
5480Sstevel@tonic-gate /* Compare two MBLITs. */
5490Sstevel@tonic-gate return ((p->character) - (q->character));
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate static void
wrmbchars()5530Sstevel@tonic-gate wrmbchars()
5540Sstevel@tonic-gate {
5550Sstevel@tonic-gate int i;
5560Sstevel@tonic-gate wdef(L"YYNMBCHARS", nmbchars);
5570Sstevel@tonic-gate qsort(mbchars, nmbchars, sizeof (*mbchars),
558*6951Sab196087 (int (*)(const void *, const void *))cmpmbchars);
5590Sstevel@tonic-gate (void) fprintf(ftable,
560*6951Sab196087 "static struct{\n\twchar_t character;"
561*6951Sab196087 "\n\tint tvalue;\n}yymbchars[YYNMBCHARS]={\n");
5620Sstevel@tonic-gate for (i = 0; i < nmbchars; ++i) {
5630Sstevel@tonic-gate (void) fprintf(ftable, "\t{%#x,%d}",
564*6951Sab196087 (int)mbchars[i].character, mbchars[i].tvalue);
5650Sstevel@tonic-gate if (i < nmbchars - 1) {
5660Sstevel@tonic-gate /* Not the last. */
5670Sstevel@tonic-gate (void) fprintf(ftable, ",\n");
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate }
5700Sstevel@tonic-gate (void) fprintf(ftable, "\n};\n");
5710Sstevel@tonic-gate }
572