xref: /illumos-gate/usr/src/cmd/sgs/yacc/common/y3.c (revision caeaa751)
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
51dd08564Sab  * Common Development and Distribution License (the "License").
61dd08564Sab  * 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 /*
221dd08564Sab  * 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 
29e29394bdSmike_s #include "dextern.h"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate static void go2gen(int);
327c478bd9Sstevel@tonic-gate static void precftn(int, int, int);
337c478bd9Sstevel@tonic-gate static void wract(int);
347c478bd9Sstevel@tonic-gate static void wrstate(int);
357c478bd9Sstevel@tonic-gate static void wdef(wchar_t *, int);
367c478bd9Sstevel@tonic-gate static void wrmbchars(void);
377c478bd9Sstevel@tonic-gate 	/* important local variables */
387c478bd9Sstevel@tonic-gate static int lastred; /* number of the last reduction of a state */
397c478bd9Sstevel@tonic-gate int *defact;
407c478bd9Sstevel@tonic-gate extern int *toklev;
417c478bd9Sstevel@tonic-gate extern int cwp;
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /* print the output for the states */
447c478bd9Sstevel@tonic-gate void
output(void)45a97db1b7SToomas Soome output(void)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate 	int i, k, c;
48a97db1b7SToomas Soome 	WSET *u, *v;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 	(void) fprintf(ftable, "static YYCONST yytabelem yyexca[] ={\n");
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate 	SLOOP(i) { /* output the stuff for state i */
537c478bd9Sstevel@tonic-gate 		nolook = !(tystate[i] == MUSTLOOKAHEAD);
547c478bd9Sstevel@tonic-gate 		closure(i);
557c478bd9Sstevel@tonic-gate 		/* output actions */
567c478bd9Sstevel@tonic-gate 		nolook = 1;
577c478bd9Sstevel@tonic-gate 		aryfil(temp1, ntoksz+nnontersz+1, 0);
587c478bd9Sstevel@tonic-gate 		WSLOOP(wsets, u) {
597c478bd9Sstevel@tonic-gate 			c = *(u->pitem);
607c478bd9Sstevel@tonic-gate 			if (c > 1 && c < NTBASE && temp1[c] == 0) {
617c478bd9Sstevel@tonic-gate 				WSLOOP(u, v) {
627c478bd9Sstevel@tonic-gate 					if (c == *(v->pitem))
637c478bd9Sstevel@tonic-gate 						putitem(v->pitem + 1,
641dd08564Sab 						    (LOOKSETS *)0);
657c478bd9Sstevel@tonic-gate 				}
667c478bd9Sstevel@tonic-gate 				temp1[c] = state(c);
677c478bd9Sstevel@tonic-gate 			} else if (c > NTBASE &&
681dd08564Sab 			    temp1[(c -= NTBASE) + ntokens] == 0) {
697c478bd9Sstevel@tonic-gate 				temp1[c + ntokens] = amem[indgo[i] + c];
707c478bd9Sstevel@tonic-gate 			}
717c478bd9Sstevel@tonic-gate 		}
727c478bd9Sstevel@tonic-gate 		if (i == 1)
737c478bd9Sstevel@tonic-gate 			temp1[1] = ACCEPTCODE;
747c478bd9Sstevel@tonic-gate 		/* now, we have the shifts; look at the reductions */
757c478bd9Sstevel@tonic-gate 		lastred = 0;
767c478bd9Sstevel@tonic-gate 		WSLOOP(wsets, u) {
777c478bd9Sstevel@tonic-gate 			c = *(u->pitem);
787c478bd9Sstevel@tonic-gate 			if (c <= 0) { /* reduction */
797c478bd9Sstevel@tonic-gate 				lastred = -c;
807c478bd9Sstevel@tonic-gate 				TLOOP(k) {
817c478bd9Sstevel@tonic-gate 					if (BIT(u->ws.lset, k)) {
827c478bd9Sstevel@tonic-gate 						if (temp1[k] == 0)
837c478bd9Sstevel@tonic-gate 							temp1[k] = c;
847c478bd9Sstevel@tonic-gate 						else if (temp1[k] < 0) {
857c478bd9Sstevel@tonic-gate 							/*
867c478bd9Sstevel@tonic-gate 							 * reduce/reduce
877c478bd9Sstevel@tonic-gate 							 * conflict
887c478bd9Sstevel@tonic-gate 							 */
891dd08564Sab 							/* BEGIN CSTYLED */
907c478bd9Sstevel@tonic-gate 							if (foutput != NULL)
917c478bd9Sstevel@tonic-gate 					(void) fprintf(foutput,
92*caeaa751SToomas Soome 				"\n%d: reduce/reduce conflict"
93*caeaa751SToomas Soome 				" (red'ns %d and %d ) on %ws",
947c478bd9Sstevel@tonic-gate 							i, -temp1[k],
957c478bd9Sstevel@tonic-gate 							lastred, symnam(k));
967c478bd9Sstevel@tonic-gate 						    if (-temp1[k] > lastred)
977c478bd9Sstevel@tonic-gate 							temp1[k] = -lastred;
987c478bd9Sstevel@tonic-gate 						    ++zzrrconf;
991dd08564Sab 							/* END CSTYLED */
1007c478bd9Sstevel@tonic-gate 						} else
1017c478bd9Sstevel@tonic-gate 							/*
1027c478bd9Sstevel@tonic-gate 							 * potentia
1037c478bd9Sstevel@tonic-gate 							 * shift/reduce
1047c478bd9Sstevel@tonic-gate 							 * conflict.
1057c478bd9Sstevel@tonic-gate 							 */
1067c478bd9Sstevel@tonic-gate 							precftn(lastred, k, i);
1077c478bd9Sstevel@tonic-gate 					}
1087c478bd9Sstevel@tonic-gate 				}
1097c478bd9Sstevel@tonic-gate 			}
1107c478bd9Sstevel@tonic-gate 		}
1117c478bd9Sstevel@tonic-gate 		wract(i);
1127c478bd9Sstevel@tonic-gate 	}
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 	(void) fprintf(ftable, "\t};\n");
1157c478bd9Sstevel@tonic-gate 	wdef(L"YYNPROD", nprod);
1167c478bd9Sstevel@tonic-gate 	if (nmbchars > 0) {
1177c478bd9Sstevel@tonic-gate 		wrmbchars();
1187c478bd9Sstevel@tonic-gate 	}
1197c478bd9Sstevel@tonic-gate }
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate static int pkdebug = 0;
122e29394bdSmike_s int
apack(int * p,int n)123a97db1b7SToomas Soome apack(int *p, int n)
1247c478bd9Sstevel@tonic-gate {
1257c478bd9Sstevel@tonic-gate 	/* pack state i from temp1 into amem */
1267c478bd9Sstevel@tonic-gate 	int off;
127e29394bdSmike_s 	int *pp, *qq;
128e29394bdSmike_s 	int *q, *rr;
1297c478bd9Sstevel@tonic-gate 	int diff;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	/*
1327c478bd9Sstevel@tonic-gate 	 * we don't need to worry about checking because we
1337c478bd9Sstevel@tonic-gate 	 * we will only look up entries known to be there...
1347c478bd9Sstevel@tonic-gate 	 */
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	/* eliminate leading and trailing 0's */
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	q = p + n;
1397c478bd9Sstevel@tonic-gate 	for (pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)
140e29394bdSmike_s 		/* NULL */;
1417c478bd9Sstevel@tonic-gate 	if (pp > q)
1427c478bd9Sstevel@tonic-gate 		return (0);  /* no actions */
1437c478bd9Sstevel@tonic-gate 	p = pp;
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	/* now, find a place for the elements from p to q, inclusive */
1467c478bd9Sstevel@tonic-gate 	/* for( rr=amem; rr<=r; ++rr,++off ){ */  /* try rr */
1477c478bd9Sstevel@tonic-gate 	rr = amem;
1487c478bd9Sstevel@tonic-gate 	for (; ; ++rr, ++off) {
1497c478bd9Sstevel@tonic-gate 		while (rr >= &amem[new_actsize-1])
1507c478bd9Sstevel@tonic-gate 			exp_act(&rr);
1517c478bd9Sstevel@tonic-gate 		qq = rr;
1527c478bd9Sstevel@tonic-gate 		for (pp = p; pp <= q; ++pp, ++qq) {
1537c478bd9Sstevel@tonic-gate 			if (*pp) {
1547c478bd9Sstevel@tonic-gate 				diff = qq - rr;
1557c478bd9Sstevel@tonic-gate 				while (qq >= &amem[new_actsize-1]) {
1567c478bd9Sstevel@tonic-gate 					exp_act(&rr);
1577c478bd9Sstevel@tonic-gate 					qq = diff + rr;
1587c478bd9Sstevel@tonic-gate 				}
1597c478bd9Sstevel@tonic-gate 				if (*pp != *qq && *qq != 0)
1607c478bd9Sstevel@tonic-gate 					goto nextk;
1617c478bd9Sstevel@tonic-gate 			}
1627c478bd9Sstevel@tonic-gate 		}
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 		/* we have found an acceptable k */
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 		if (pkdebug && foutput != NULL)
1677c478bd9Sstevel@tonic-gate 			(void) fprintf(foutput,
168a97db1b7SToomas Soome 			    "off = %d, k = %" PRIdPTR "\n", off, rr-amem);
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 		qq = rr;
1717c478bd9Sstevel@tonic-gate 		for (pp = p; pp <= q; ++pp, ++qq) {
1727c478bd9Sstevel@tonic-gate 			if (*pp) {
1737c478bd9Sstevel@tonic-gate 				diff = qq - rr;
1747c478bd9Sstevel@tonic-gate 				while (qq >= &amem[new_actsize-1]) {
1757c478bd9Sstevel@tonic-gate 					exp_act(&rr);
1767c478bd9Sstevel@tonic-gate 					qq = diff + rr;
1777c478bd9Sstevel@tonic-gate 				}
1787c478bd9Sstevel@tonic-gate 				if (qq > memp)
1797c478bd9Sstevel@tonic-gate 					memp = qq;
1807c478bd9Sstevel@tonic-gate 				*qq = *pp;
1817c478bd9Sstevel@tonic-gate 			}
1827c478bd9Sstevel@tonic-gate 		}
1837c478bd9Sstevel@tonic-gate 		if (pkdebug && foutput != NULL) {
1847c478bd9Sstevel@tonic-gate 			for (pp = amem; pp <= memp; pp += 10) {
1857c478bd9Sstevel@tonic-gate 				(void) fprintf(foutput, "\t");
1867c478bd9Sstevel@tonic-gate 				for (qq = pp; qq <= pp + 9; ++qq)
1877c478bd9Sstevel@tonic-gate 					(void) fprintf(foutput, "%d ", *qq);
1887c478bd9Sstevel@tonic-gate 				(void) fprintf(foutput, "\n");
1897c478bd9Sstevel@tonic-gate 			}
1907c478bd9Sstevel@tonic-gate 		}
1917c478bd9Sstevel@tonic-gate 		return (off);
1927c478bd9Sstevel@tonic-gate 		nextk:;
1937c478bd9Sstevel@tonic-gate 	}
1947c478bd9Sstevel@tonic-gate 	/* error("no space in action table" ); */
1957c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate void
go2out(void)199a97db1b7SToomas Soome go2out(void)
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate 	/* output the gotos for the nontermninals */
2027c478bd9Sstevel@tonic-gate 	int i, j, k, best, count, cbest, times;
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 	(void) fprintf(ftemp, "$\n");  /* mark begining of gotos */
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	for (i = 1; i <= nnonter; ++i) {
2077c478bd9Sstevel@tonic-gate 		go2gen(i);
2087c478bd9Sstevel@tonic-gate 		/* find the best one to make default */
2097c478bd9Sstevel@tonic-gate 		best = -1;
2107c478bd9Sstevel@tonic-gate 		times = 0;
2117c478bd9Sstevel@tonic-gate 		for (j = 0; j < nstate; ++j) { /* is j the most frequent */
2127c478bd9Sstevel@tonic-gate 			if (tystate[j] == 0)
2137c478bd9Sstevel@tonic-gate 				continue;
2147c478bd9Sstevel@tonic-gate 			if (tystate[j] == best)
2157c478bd9Sstevel@tonic-gate 				continue;
2167c478bd9Sstevel@tonic-gate 			/* is tystate[j] the most frequent */
2177c478bd9Sstevel@tonic-gate 			count = 0;
2187c478bd9Sstevel@tonic-gate 			cbest = tystate[j];
2197c478bd9Sstevel@tonic-gate 			for (k = j; k < nstate; ++k)
2207c478bd9Sstevel@tonic-gate 				if (tystate[k] == cbest)
2217c478bd9Sstevel@tonic-gate 					++count;
2227c478bd9Sstevel@tonic-gate 			if (count > times) {
2237c478bd9Sstevel@tonic-gate 				best = cbest;
2247c478bd9Sstevel@tonic-gate 				times = count;
2257c478bd9Sstevel@tonic-gate 			}
2267c478bd9Sstevel@tonic-gate 		}
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 		/* best is now the default entry */
2297c478bd9Sstevel@tonic-gate 		zzgobest += (times-1);
2307c478bd9Sstevel@tonic-gate 		for (j = 0; j < nstate; ++j) {
2317c478bd9Sstevel@tonic-gate 			if (tystate[j] != 0 && tystate[j] != best) {
2327c478bd9Sstevel@tonic-gate 				(void) fprintf(ftemp, "%d,%d,", j, tystate[j]);
2337c478bd9Sstevel@tonic-gate 				zzgoent += 1;
2347c478bd9Sstevel@tonic-gate 			}
2357c478bd9Sstevel@tonic-gate 		}
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 		/* now, the default */
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 		zzgoent += 1;
2407c478bd9Sstevel@tonic-gate 		(void) fprintf(ftemp, "%d\n", best);
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	}
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate static int g2debug = 0;
246a97db1b7SToomas Soome static void
go2gen(int c)247a97db1b7SToomas Soome go2gen(int c)
2487c478bd9Sstevel@tonic-gate {
2497c478bd9Sstevel@tonic-gate 	/* output the gotos for nonterminal c */
2507c478bd9Sstevel@tonic-gate 	int i, work, cc;
2517c478bd9Sstevel@tonic-gate 	ITEM *p, *q;
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	/* first, find nonterminals with gotos on c */
2547c478bd9Sstevel@tonic-gate 	aryfil(temp1, nnonter + 1, 0);
2557c478bd9Sstevel@tonic-gate 	temp1[c] = 1;
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	work = 1;
2587c478bd9Sstevel@tonic-gate 	while (work) {
2597c478bd9Sstevel@tonic-gate 		work = 0;
2607c478bd9Sstevel@tonic-gate 		PLOOP(0, i) {
2617c478bd9Sstevel@tonic-gate 			if ((cc = prdptr[i][1] - NTBASE) >= 0) {
2627c478bd9Sstevel@tonic-gate 				/* cc is a nonterminal */
2637c478bd9Sstevel@tonic-gate 				if (temp1[cc] != 0) {
2647c478bd9Sstevel@tonic-gate 					/*
2657c478bd9Sstevel@tonic-gate 					 * cc has a goto on c
2667c478bd9Sstevel@tonic-gate 					 * thus, the left side of
2677c478bd9Sstevel@tonic-gate 					 * production i does too.
2687c478bd9Sstevel@tonic-gate 					 */
2697c478bd9Sstevel@tonic-gate 					cc = *prdptr[i] - NTBASE;
2707c478bd9Sstevel@tonic-gate 					if (temp1[cc] == 0) {
2717c478bd9Sstevel@tonic-gate 						work = 1;
2727c478bd9Sstevel@tonic-gate 						temp1[cc] = 1;
2737c478bd9Sstevel@tonic-gate 					}
2747c478bd9Sstevel@tonic-gate 				}
2757c478bd9Sstevel@tonic-gate 			}
2767c478bd9Sstevel@tonic-gate 		}
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	/* now, we have temp1[c] = 1 if a goto on c in closure of cc */
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	if (g2debug && foutput != NULL) {
282*caeaa751SToomas Soome 		(void) fprintf(foutput, "%ws: gotos on ",
2831dd08564Sab 		    nontrst[c].name);
2847c478bd9Sstevel@tonic-gate 		NTLOOP(i) if (temp1[i])
285*caeaa751SToomas Soome 			(void) fprintf(foutput, "%ws ", nontrst[i].name);
2867c478bd9Sstevel@tonic-gate 		(void) fprintf(foutput, "\n");
2877c478bd9Sstevel@tonic-gate 	}
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 	/* now, go through and put gotos into tystate */
2907c478bd9Sstevel@tonic-gate 	aryfil(tystate, nstate, 0);
2917c478bd9Sstevel@tonic-gate 	SLOOP(i) {
2927c478bd9Sstevel@tonic-gate 		ITMLOOP(i, p, q) {
2937c478bd9Sstevel@tonic-gate 			if ((cc = *p->pitem) >= NTBASE) {
2947c478bd9Sstevel@tonic-gate 				if (temp1[cc -= NTBASE]) {
2957c478bd9Sstevel@tonic-gate 					/* goto on c is possible */
2967c478bd9Sstevel@tonic-gate 					tystate[i] = amem[indgo[i] + c];
2977c478bd9Sstevel@tonic-gate 					break;
2987c478bd9Sstevel@tonic-gate 				}
2997c478bd9Sstevel@tonic-gate 			}
3007c478bd9Sstevel@tonic-gate 		}
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate /* decide a shift/reduce conflict by precedence.  */
3057c478bd9Sstevel@tonic-gate static void
precftn(int r,int t,int s)306e29394bdSmike_s precftn(int r, int t, int s)
3077c478bd9Sstevel@tonic-gate {
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	/*
3107c478bd9Sstevel@tonic-gate 	 * r is a rule number, t a token number
3117c478bd9Sstevel@tonic-gate 	 * the conflict is in state s
3127c478bd9Sstevel@tonic-gate 	 * temp1[t] is changed to reflect the action
3137c478bd9Sstevel@tonic-gate 	 */
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	int lp, lt, action;
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 	lp = levprd[r];
3187c478bd9Sstevel@tonic-gate 	lt = toklev[t];
3197c478bd9Sstevel@tonic-gate 	if (PLEVEL(lt) == 0 || PLEVEL(lp) == 0) {
3207c478bd9Sstevel@tonic-gate 		/* conflict */
3217c478bd9Sstevel@tonic-gate 		if (foutput != NULL)
3227c478bd9Sstevel@tonic-gate 			(void) fprintf(foutput,
323*caeaa751SToomas Soome 			    "\n%d: shift/reduce conflict"
324*caeaa751SToomas Soome 			    " (shift %d, red'n %d) on %ws",
3251dd08564Sab 			    s, temp1[t], r, symnam(t));
3267c478bd9Sstevel@tonic-gate 		++zzsrconf;
3277c478bd9Sstevel@tonic-gate 		return;
3287c478bd9Sstevel@tonic-gate 	}
3297c478bd9Sstevel@tonic-gate 	if (PLEVEL(lt) == PLEVEL(lp))
3307c478bd9Sstevel@tonic-gate 		action = ASSOC(lt) & ~04;
3317c478bd9Sstevel@tonic-gate 	else if (PLEVEL(lt) > PLEVEL(lp))
3327c478bd9Sstevel@tonic-gate 		action = RASC;  /* shift */
3337c478bd9Sstevel@tonic-gate 	else
3347c478bd9Sstevel@tonic-gate 		action = LASC;  /* reduce */
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 	switch (action) {
3377c478bd9Sstevel@tonic-gate 	case BASC:  /* error action */
3387c478bd9Sstevel@tonic-gate 		temp1[t] = ERRCODE;
3397c478bd9Sstevel@tonic-gate 		return;
3407c478bd9Sstevel@tonic-gate 	case LASC:  /* reduce */
3417c478bd9Sstevel@tonic-gate 		temp1[t] = -r;
3427c478bd9Sstevel@tonic-gate 		return;
3437c478bd9Sstevel@tonic-gate 	}
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate static void
wract(int i)347e29394bdSmike_s wract(int i)
3487c478bd9Sstevel@tonic-gate {
3497c478bd9Sstevel@tonic-gate 	/* output state i */
3507c478bd9Sstevel@tonic-gate 	/* temp1 has the actions, lastred the default */
3517c478bd9Sstevel@tonic-gate 	int p, p0, p1;
3527c478bd9Sstevel@tonic-gate 	int ntimes, tred, count, j;
3537c478bd9Sstevel@tonic-gate 	int flag;
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	/* find the best choice for lastred */
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 	lastred = 0;
3587c478bd9Sstevel@tonic-gate 	ntimes = 0;
3597c478bd9Sstevel@tonic-gate 	TLOOP(j) {
3607c478bd9Sstevel@tonic-gate 		if (temp1[j] >= 0)
3617c478bd9Sstevel@tonic-gate 			continue;
3627c478bd9Sstevel@tonic-gate 		if (temp1[j] + lastred == 0)
3637c478bd9Sstevel@tonic-gate 			continue;
3647c478bd9Sstevel@tonic-gate 		/* count the number of appearances of temp1[j] */
3657c478bd9Sstevel@tonic-gate 		count = 0;
3667c478bd9Sstevel@tonic-gate 		tred = -temp1[j];
3677c478bd9Sstevel@tonic-gate 		levprd[tred] |= REDFLAG;
3687c478bd9Sstevel@tonic-gate 		TLOOP(p) {
3697c478bd9Sstevel@tonic-gate 			if (temp1[p] + tred == 0)
3707c478bd9Sstevel@tonic-gate 				++count;
3717c478bd9Sstevel@tonic-gate 		}
3727c478bd9Sstevel@tonic-gate 		if (count > ntimes) {
3737c478bd9Sstevel@tonic-gate 			lastred = tred;
3747c478bd9Sstevel@tonic-gate 			ntimes = count;
3757c478bd9Sstevel@tonic-gate 		}
3767c478bd9Sstevel@tonic-gate 	}
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	/*
3797c478bd9Sstevel@tonic-gate 	 * for error recovery, arrange that, if there is a shift on the
3807c478bd9Sstevel@tonic-gate 	 * error recovery token, `error', that the default be the error action
3817c478bd9Sstevel@tonic-gate 	 */
3827c478bd9Sstevel@tonic-gate 	if (temp1[2] > 0)
3837c478bd9Sstevel@tonic-gate 		lastred = 0;
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 	/* clear out entries in temp1 which equal lastred */
3867c478bd9Sstevel@tonic-gate 	TLOOP(p) {
3877c478bd9Sstevel@tonic-gate 		if (temp1[p] + lastred == 0)
3887c478bd9Sstevel@tonic-gate 			temp1[p] = 0;
3897c478bd9Sstevel@tonic-gate 	}
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 	wrstate(i);
3927c478bd9Sstevel@tonic-gate 	defact[i] = lastred;
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate 	flag = 0;
3957c478bd9Sstevel@tonic-gate 	TLOOP(p0) {
3967c478bd9Sstevel@tonic-gate 		if ((p1 = temp1[p0]) != 0) {
3977c478bd9Sstevel@tonic-gate 			if (p1 < 0) {
3987c478bd9Sstevel@tonic-gate 				p1 = -p1;
3997c478bd9Sstevel@tonic-gate 				goto exc;
4007c478bd9Sstevel@tonic-gate 			} else if (p1 == ACCEPTCODE) {
4017c478bd9Sstevel@tonic-gate 				p1 = -1;
4027c478bd9Sstevel@tonic-gate 				goto exc;
4037c478bd9Sstevel@tonic-gate 			} else if (p1 == ERRCODE) {
4047c478bd9Sstevel@tonic-gate 				p1 = 0;
4057c478bd9Sstevel@tonic-gate 				goto exc;
4067c478bd9Sstevel@tonic-gate 			exc:
4077c478bd9Sstevel@tonic-gate 				if (flag++ == 0)
4087c478bd9Sstevel@tonic-gate 					(void) fprintf(ftable, "-1, %d,\n", i);
4097c478bd9Sstevel@tonic-gate 				(void) fprintf(ftable,
4101dd08564Sab 				    "\t%d, %d,\n", tokset[p0].value, p1);
4117c478bd9Sstevel@tonic-gate 				++zzexcp;
4127c478bd9Sstevel@tonic-gate 			} else {
4137c478bd9Sstevel@tonic-gate 				(void) fprintf(ftemp,
4141dd08564Sab 				    "%d,%d,", tokset[p0].value, p1);
4157c478bd9Sstevel@tonic-gate 				++zzacent;
4167c478bd9Sstevel@tonic-gate 			}
4177c478bd9Sstevel@tonic-gate 		}
4187c478bd9Sstevel@tonic-gate 	}
4197c478bd9Sstevel@tonic-gate 	if (flag) {
4207c478bd9Sstevel@tonic-gate 		defact[i] = -2;
4217c478bd9Sstevel@tonic-gate 		(void) fprintf(ftable, "\t-2, %d,\n", lastred);
4227c478bd9Sstevel@tonic-gate 	}
4237c478bd9Sstevel@tonic-gate 	(void) fprintf(ftemp, "\n");
4247c478bd9Sstevel@tonic-gate }
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate static void
wrstate(int i)427e29394bdSmike_s wrstate(int i)
4287c478bd9Sstevel@tonic-gate {
4297c478bd9Sstevel@tonic-gate 	/* writes state i */
430e29394bdSmike_s 	int j0, j1;
4317c478bd9Sstevel@tonic-gate 	register ITEM *pp, *qq;
4327c478bd9Sstevel@tonic-gate 	register WSET *u;
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 	if (foutput == NULL)
4357c478bd9Sstevel@tonic-gate 		return;
4367c478bd9Sstevel@tonic-gate 	(void) fprintf(foutput, "\nstate %d\n", i);
4377c478bd9Sstevel@tonic-gate 	ITMLOOP(i, pp, qq) {
438*caeaa751SToomas Soome 		(void) fprintf(foutput, "\t%ws\n", writem(pp->pitem));
4397c478bd9Sstevel@tonic-gate 	}
4407c478bd9Sstevel@tonic-gate 	if (tystate[i] == MUSTLOOKAHEAD) {
4417c478bd9Sstevel@tonic-gate 		/* print out empty productions in closure */
4427c478bd9Sstevel@tonic-gate 		WSLOOP(wsets + (pstate[i + 1] - pstate[i]), u) {
4437c478bd9Sstevel@tonic-gate 			if (*(u->pitem) < 0)
4447c478bd9Sstevel@tonic-gate 				(void) fprintf(foutput,
445*caeaa751SToomas Soome 				    "\t%ws\n", writem(u->pitem));
4467c478bd9Sstevel@tonic-gate 		}
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 	/* check for state equal to another */
4507c478bd9Sstevel@tonic-gate 	TLOOP(j0) if ((j1 = temp1[j0]) != 0) {
451*caeaa751SToomas Soome 		(void) fprintf(foutput, "\n\t%ws  ", symnam(j0));
4527c478bd9Sstevel@tonic-gate 		if (j1 > 0) { /* shift, error, or accept */
4537c478bd9Sstevel@tonic-gate 			if (j1 == ACCEPTCODE)
4547c478bd9Sstevel@tonic-gate 				(void) fprintf(foutput,  "accept");
4557c478bd9Sstevel@tonic-gate 			else if (j1 == ERRCODE)
4567c478bd9Sstevel@tonic-gate 				(void) fprintf(foutput, "error");
4577c478bd9Sstevel@tonic-gate 			else
4587c478bd9Sstevel@tonic-gate 				(void) fprintf(foutput, "shift %d", j1);
4597c478bd9Sstevel@tonic-gate 		}
4607c478bd9Sstevel@tonic-gate 		else
4617c478bd9Sstevel@tonic-gate 			(void) fprintf(foutput, "reduce %d", -j1);
4627c478bd9Sstevel@tonic-gate 	}
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	/* output the final production */
4657c478bd9Sstevel@tonic-gate 	if (lastred)
4667c478bd9Sstevel@tonic-gate 		(void) fprintf(foutput, "\n\t.  reduce %d\n\n", lastred);
4677c478bd9Sstevel@tonic-gate 	else
4687c478bd9Sstevel@tonic-gate 		(void) fprintf(foutput, "\n\t.  error\n\n");
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	/* now, output nonterminal actions */
4717c478bd9Sstevel@tonic-gate 	j1 = ntokens;
4727c478bd9Sstevel@tonic-gate 	for (j0 = 1; j0 <= nnonter; ++j0) {
4737c478bd9Sstevel@tonic-gate 		if (temp1[++j1])
4747c478bd9Sstevel@tonic-gate 			(void) fprintf(foutput,
475*caeaa751SToomas Soome 			    "\t%ws  goto %d\n",
4761dd08564Sab 			    symnam(j0 + NTBASE), temp1[j1]);
4777c478bd9Sstevel@tonic-gate 	}
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate static void
wdef(wchar_t * s,int n)481e29394bdSmike_s wdef(wchar_t *s, int n)
4827c478bd9Sstevel@tonic-gate {
4837c478bd9Sstevel@tonic-gate 	/* output a definition of s to the value n */
484*caeaa751SToomas Soome 	(void) fprintf(ftable, "# define %ws %d\n", s, n);
4857c478bd9Sstevel@tonic-gate }
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate void
warray(wchar_t * s,int * v,int n)488a97db1b7SToomas Soome warray(wchar_t *s, int *v, int n)
4897c478bd9Sstevel@tonic-gate {
490e29394bdSmike_s 	int i;
491*caeaa751SToomas Soome 	(void) fprintf(ftable, "static YYCONST yytabelem %ws[]={\n", s);
4927c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; ) {
4937c478bd9Sstevel@tonic-gate 		if (i % 10 == 0)
4947c478bd9Sstevel@tonic-gate 			(void) fprintf(ftable, "\n");
4957c478bd9Sstevel@tonic-gate 		(void) fprintf(ftable, "%6d", v[i]);
4967c478bd9Sstevel@tonic-gate 		if (++i == n)
4977c478bd9Sstevel@tonic-gate 			(void) fprintf(ftable, " };\n");
4987c478bd9Sstevel@tonic-gate 		else
4997c478bd9Sstevel@tonic-gate 			(void) fprintf(ftable, ",");
5007c478bd9Sstevel@tonic-gate 	}
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate void
hideprod(void)504a97db1b7SToomas Soome hideprod(void)
5057c478bd9Sstevel@tonic-gate {
5067c478bd9Sstevel@tonic-gate 	/*
5077c478bd9Sstevel@tonic-gate 	 * in order to free up the mem and amem arrays for the optimizer,
5087c478bd9Sstevel@tonic-gate 	 * and still be able to output yyr1, etc., after the sizes of
5097c478bd9Sstevel@tonic-gate 	 * the action array is known, we hide the nonterminals
5107c478bd9Sstevel@tonic-gate 	 * derived by productions in levprd.
5117c478bd9Sstevel@tonic-gate 	 */
5127c478bd9Sstevel@tonic-gate 
513e29394bdSmike_s 	int i, j;
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 	j = 0;
5167c478bd9Sstevel@tonic-gate 	levprd[0] = 0;
5177c478bd9Sstevel@tonic-gate 	PLOOP(1, i) {
5187c478bd9Sstevel@tonic-gate 		if (!(levprd[i] & REDFLAG)) {
5197c478bd9Sstevel@tonic-gate 			++j;
5207c478bd9Sstevel@tonic-gate 			if (foutput != NULL) {
5217c478bd9Sstevel@tonic-gate 				(void) fprintf(foutput,
522*caeaa751SToomas Soome 				    "Rule not reduced:   %ws\n",
5231dd08564Sab 				    writem(prdptr[i]));
5247c478bd9Sstevel@tonic-gate 			}
5257c478bd9Sstevel@tonic-gate 		}
5267c478bd9Sstevel@tonic-gate 		levprd[i] = *prdptr[i] - NTBASE;
5277c478bd9Sstevel@tonic-gate 	}
5287c478bd9Sstevel@tonic-gate 	if (j)
5297c478bd9Sstevel@tonic-gate /*
5307c478bd9Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
5317c478bd9Sstevel@tonic-gate  *	Check how 'reduced' is translated in yacc man page/document.
5327c478bd9Sstevel@tonic-gate  */
5331dd08564Sab 		(void) fprintf(stderr,
5341dd08564Sab 		    gettext("%d rules never reduced\n"),
5351dd08564Sab 		    j);
5367c478bd9Sstevel@tonic-gate }
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate static int
cmpmbchars(MBCLIT * p,MBCLIT * q)540a97db1b7SToomas Soome cmpmbchars(MBCLIT *p, MBCLIT *q)
5417c478bd9Sstevel@tonic-gate {
5427c478bd9Sstevel@tonic-gate 	/* Compare two MBLITs. */
5437c478bd9Sstevel@tonic-gate 	return ((p->character) - (q->character));
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate static void
wrmbchars(void)547a97db1b7SToomas Soome wrmbchars(void)
5487c478bd9Sstevel@tonic-gate {
5497c478bd9Sstevel@tonic-gate 	int i;
5507c478bd9Sstevel@tonic-gate 	wdef(L"YYNMBCHARS", nmbchars);
5517c478bd9Sstevel@tonic-gate 	qsort(mbchars, nmbchars, sizeof (*mbchars),
5521dd08564Sab 	    (int (*)(const void *, const void *))cmpmbchars);
5537c478bd9Sstevel@tonic-gate 	(void) fprintf(ftable,
5541dd08564Sab 	    "static struct{\n\twchar_t character;"
5551dd08564Sab 	    "\n\tint tvalue;\n}yymbchars[YYNMBCHARS]={\n");
5567c478bd9Sstevel@tonic-gate 	for (i = 0; i < nmbchars; ++i) {
5577c478bd9Sstevel@tonic-gate 		(void) fprintf(ftable, "\t{%#x,%d}",
5581dd08564Sab 		    (int)mbchars[i].character, mbchars[i].tvalue);
5597c478bd9Sstevel@tonic-gate 		if (i < nmbchars - 1) {
5607c478bd9Sstevel@tonic-gate 			/* Not the last. */
5617c478bd9Sstevel@tonic-gate 			(void) fprintf(ftable, ",\n");
5627c478bd9Sstevel@tonic-gate 		}
5637c478bd9Sstevel@tonic-gate 	}
5647c478bd9Sstevel@tonic-gate 	(void) fprintf(ftable, "\n};\n");
5657c478bd9Sstevel@tonic-gate }
566