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 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 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 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; 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 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 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 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 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 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 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 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 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