xref: /titanic_52/usr/src/cmd/sgs/lex/common/sub2.c (revision 1dd08564e4a3aafe66b00aee6f222b0885346fe8)
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
567298654Sdamico  * Common Development and Distribution License (the "License").
667298654Sdamico  * 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 
3167298654Sdamico #include "ldefs.h"
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate static void add(int **array, int n);
347c478bd9Sstevel@tonic-gate static void follow(int v);
357c478bd9Sstevel@tonic-gate static void first(int v);
367c478bd9Sstevel@tonic-gate static void nextstate(int s, int c);
377c478bd9Sstevel@tonic-gate static void packtrans(int st, CHR *tch, int *tst, int cnt, int tryit);
387c478bd9Sstevel@tonic-gate static void acompute(int s);
397c478bd9Sstevel@tonic-gate static void rprint(int *a, char *s, int n);
407c478bd9Sstevel@tonic-gate static void shiftr(int *a, int n);
417c478bd9Sstevel@tonic-gate static void upone(int *a, int n);
427c478bd9Sstevel@tonic-gate static void bprint(char *a, char *s, int n);
437c478bd9Sstevel@tonic-gate static int notin(int n);
447c478bd9Sstevel@tonic-gate static int member(int d, CHR *t);
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #ifdef PP
477c478bd9Sstevel@tonic-gate static void padd(int **array, int n);
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate void
517c478bd9Sstevel@tonic-gate cfoll(int v)
527c478bd9Sstevel@tonic-gate {
537c478bd9Sstevel@tonic-gate 	int i, j, k;
547c478bd9Sstevel@tonic-gate 	CHR *p;
557c478bd9Sstevel@tonic-gate 	i = name[v];
567c478bd9Sstevel@tonic-gate 	if (!ISOPERATOR(i))
577c478bd9Sstevel@tonic-gate 		i = 1;
587c478bd9Sstevel@tonic-gate 	switch (i) {
597c478bd9Sstevel@tonic-gate 		case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:
607c478bd9Sstevel@tonic-gate 			for (j = 0; j < tptr; j++)
617c478bd9Sstevel@tonic-gate 				tmpstat[j] = FALSE;
627c478bd9Sstevel@tonic-gate 			count = 0;
637c478bd9Sstevel@tonic-gate 			follow(v);
647c478bd9Sstevel@tonic-gate #ifdef PP
657c478bd9Sstevel@tonic-gate 			padd(foll, v); /* packing version */
667c478bd9Sstevel@tonic-gate #else
677c478bd9Sstevel@tonic-gate 			add(foll, v); /* no packing version */
687c478bd9Sstevel@tonic-gate #endif
697c478bd9Sstevel@tonic-gate 			if (i == RSTR)
707c478bd9Sstevel@tonic-gate 				cfoll(left[v]);
717c478bd9Sstevel@tonic-gate 			else if (i == RCCL || i == RNCCL) {
727c478bd9Sstevel@tonic-gate 				for (j = 1; j < ncg; j++)
737c478bd9Sstevel@tonic-gate 					symbol[j] = (i == RNCCL);
747c478bd9Sstevel@tonic-gate 				p = (CHR *) left[v];
757c478bd9Sstevel@tonic-gate 				while (*p)
767c478bd9Sstevel@tonic-gate 					symbol[*p++] = (i == RCCL);
777c478bd9Sstevel@tonic-gate 				p = pcptr;
787c478bd9Sstevel@tonic-gate 				for (j = 1; j < ncg; j++)
797c478bd9Sstevel@tonic-gate 					if (symbol[j]) {
807c478bd9Sstevel@tonic-gate 						for (k = 0; p + k < pcptr; k++)
8167298654Sdamico 							if (cindex[j] ==
8267298654Sdamico 							    *(p + k))
837c478bd9Sstevel@tonic-gate 								break;
847c478bd9Sstevel@tonic-gate 						if (p + k >= pcptr)
857c478bd9Sstevel@tonic-gate 							*pcptr++ = cindex[j];
867c478bd9Sstevel@tonic-gate 					}
877c478bd9Sstevel@tonic-gate 				*pcptr++ = 0;
887c478bd9Sstevel@tonic-gate 				if (pcptr > pchar + pchlen)
897c478bd9Sstevel@tonic-gate 					error(
907c478bd9Sstevel@tonic-gate 					"Too many packed character classes");
917c478bd9Sstevel@tonic-gate 				left[v] = (int)p;
927c478bd9Sstevel@tonic-gate 				name[v] = RCCL;	/* RNCCL eliminated */
937c478bd9Sstevel@tonic-gate #ifdef DEBUG
947c478bd9Sstevel@tonic-gate 				if (debug && *p) {
957c478bd9Sstevel@tonic-gate 					(void) printf("ccl %d: %d", v, *p++);
967c478bd9Sstevel@tonic-gate 					while (*p)
977c478bd9Sstevel@tonic-gate 						(void) printf(", %d", *p++);
987c478bd9Sstevel@tonic-gate 					(void) putchar('\n');
997c478bd9Sstevel@tonic-gate 				}
1007c478bd9Sstevel@tonic-gate #endif
1017c478bd9Sstevel@tonic-gate 			}
1027c478bd9Sstevel@tonic-gate 			break;
1037c478bd9Sstevel@tonic-gate 		case CARAT:
1047c478bd9Sstevel@tonic-gate 			cfoll(left[v]);
1057c478bd9Sstevel@tonic-gate 			break;
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 		/* XCU4: add RXSCON */
1087c478bd9Sstevel@tonic-gate 		case RXSCON:
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 		case STAR: case PLUS: case QUEST: case RSCON:
1117c478bd9Sstevel@tonic-gate 			cfoll(left[v]);
1127c478bd9Sstevel@tonic-gate 			break;
1137c478bd9Sstevel@tonic-gate 		case BAR: case RCAT: case DIV: case RNEWE:
1147c478bd9Sstevel@tonic-gate 			cfoll(left[v]);
1157c478bd9Sstevel@tonic-gate 			cfoll(right[v]);
1167c478bd9Sstevel@tonic-gate 			break;
1177c478bd9Sstevel@tonic-gate #ifdef DEBUG
1187c478bd9Sstevel@tonic-gate 		case FINAL:
1197c478bd9Sstevel@tonic-gate 		case S1FINAL:
1207c478bd9Sstevel@tonic-gate 		case S2FINAL:
1217c478bd9Sstevel@tonic-gate 			break;
1227c478bd9Sstevel@tonic-gate 		default:
1237c478bd9Sstevel@tonic-gate 			warning("bad switch cfoll %d", v);
1247c478bd9Sstevel@tonic-gate #endif
1257c478bd9Sstevel@tonic-gate 	}
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate #ifdef DEBUG
1297c478bd9Sstevel@tonic-gate void
1307c478bd9Sstevel@tonic-gate pfoll(void)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	int i, k, *p;
1337c478bd9Sstevel@tonic-gate 	int j;
1347c478bd9Sstevel@tonic-gate 	/* print sets of chars which may follow positions */
1357c478bd9Sstevel@tonic-gate 	(void) printf("pos\tchars\n");
1367c478bd9Sstevel@tonic-gate 	for (i = 0; i < tptr; i++)
1377c478bd9Sstevel@tonic-gate 		if (p = foll[i]) {
1387c478bd9Sstevel@tonic-gate 			j = *p++;
1397c478bd9Sstevel@tonic-gate 			if (j >= 1) {
1407c478bd9Sstevel@tonic-gate 				(void) printf("%d:\t%d", i, *p++);
1417c478bd9Sstevel@tonic-gate 				for (k = 2; k <= j; k++)
1427c478bd9Sstevel@tonic-gate 					(void) printf(", %d", *p++);
1437c478bd9Sstevel@tonic-gate 				(void) putchar('\n');
1447c478bd9Sstevel@tonic-gate 			}
1457c478bd9Sstevel@tonic-gate 		}
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate #endif
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate static void
1507c478bd9Sstevel@tonic-gate add(int **array, int n)
1517c478bd9Sstevel@tonic-gate {
1527c478bd9Sstevel@tonic-gate 	int i, *temp;
1537c478bd9Sstevel@tonic-gate 	CHR *ctemp;
1547c478bd9Sstevel@tonic-gate 	temp = nxtpos;
1557c478bd9Sstevel@tonic-gate 	ctemp = tmpstat;
1567c478bd9Sstevel@tonic-gate 	array[n] = nxtpos;	/* note no packing is done in positions */
1577c478bd9Sstevel@tonic-gate 	*temp++ = count;
1587c478bd9Sstevel@tonic-gate 	for (i = 0; i < tptr; i++)
1597c478bd9Sstevel@tonic-gate 		if (ctemp[i] == TRUE)
1607c478bd9Sstevel@tonic-gate 			*temp++ = i;
1617c478bd9Sstevel@tonic-gate 	nxtpos = temp;
1627c478bd9Sstevel@tonic-gate 	if (nxtpos >= positions+maxpos)
1637c478bd9Sstevel@tonic-gate 		error(
1647c478bd9Sstevel@tonic-gate 		"Too many positions %s",
1657c478bd9Sstevel@tonic-gate 		    (maxpos == MAXPOS ? "\nTry using %p num" : ""));
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate static void
1697c478bd9Sstevel@tonic-gate follow(int v)
1707c478bd9Sstevel@tonic-gate {
1717c478bd9Sstevel@tonic-gate 	int p;
1727c478bd9Sstevel@tonic-gate 	if (v >= tptr-1)
1737c478bd9Sstevel@tonic-gate 		return;
1747c478bd9Sstevel@tonic-gate 	p = parent[v];
1757c478bd9Sstevel@tonic-gate 	if (p == 0)
1767c478bd9Sstevel@tonic-gate 		return;
1777c478bd9Sstevel@tonic-gate 	switch (name[p]) {
1787c478bd9Sstevel@tonic-gate 	/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
1797c478bd9Sstevel@tonic-gate 	case RSTR:
1807c478bd9Sstevel@tonic-gate 		if (tmpstat[p] == FALSE) {
1817c478bd9Sstevel@tonic-gate 			count++;
1827c478bd9Sstevel@tonic-gate 			tmpstat[p] = TRUE;
1837c478bd9Sstevel@tonic-gate 		}
1847c478bd9Sstevel@tonic-gate 		break;
1857c478bd9Sstevel@tonic-gate 	case STAR: case PLUS:
1867c478bd9Sstevel@tonic-gate 		first(v);
1877c478bd9Sstevel@tonic-gate 		follow(p);
1887c478bd9Sstevel@tonic-gate 		break;
1897c478bd9Sstevel@tonic-gate 	case BAR: case QUEST: case RNEWE:
1907c478bd9Sstevel@tonic-gate 		follow(p);
1917c478bd9Sstevel@tonic-gate 		break;
1927c478bd9Sstevel@tonic-gate 	case RCAT: case DIV:
1937c478bd9Sstevel@tonic-gate 		if (v == left[p]) {
1947c478bd9Sstevel@tonic-gate 			if (nullstr[right[p]])
1957c478bd9Sstevel@tonic-gate 				follow(p);
1967c478bd9Sstevel@tonic-gate 			first(right[p]);
1977c478bd9Sstevel@tonic-gate 		}
1987c478bd9Sstevel@tonic-gate 		else
1997c478bd9Sstevel@tonic-gate 			follow(p);
2007c478bd9Sstevel@tonic-gate 		break;
2017c478bd9Sstevel@tonic-gate 	/* XCU4: add RXSCON */
2027c478bd9Sstevel@tonic-gate 	case RXSCON:
2037c478bd9Sstevel@tonic-gate 	case RSCON: case CARAT:
2047c478bd9Sstevel@tonic-gate 		follow(p);
2057c478bd9Sstevel@tonic-gate 		break;
2067c478bd9Sstevel@tonic-gate #ifdef DEBUG
2077c478bd9Sstevel@tonic-gate 	default:
2087c478bd9Sstevel@tonic-gate 		warning("bad switch follow %d", p);
2097c478bd9Sstevel@tonic-gate #endif
2107c478bd9Sstevel@tonic-gate 	}
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate /*
2147c478bd9Sstevel@tonic-gate  * Check if I have a RXSCON in my upper node
2157c478bd9Sstevel@tonic-gate  */
2167c478bd9Sstevel@tonic-gate static int
2177c478bd9Sstevel@tonic-gate check_me(int v)
2187c478bd9Sstevel@tonic-gate {
2197c478bd9Sstevel@tonic-gate 	int tmp = parent[v];
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	while (name[tmp] != RNEWE) {
2227c478bd9Sstevel@tonic-gate 		if (name[tmp] == RXSCON)
2237c478bd9Sstevel@tonic-gate 			return (1);
2247c478bd9Sstevel@tonic-gate 		tmp = parent[tmp];
2257c478bd9Sstevel@tonic-gate 	}
2267c478bd9Sstevel@tonic-gate 	return (0);
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate /* calculate set of positions with v as root which can be active initially */
2307c478bd9Sstevel@tonic-gate static void
2317c478bd9Sstevel@tonic-gate first(int v)
2327c478bd9Sstevel@tonic-gate {
2337c478bd9Sstevel@tonic-gate 	int i;
2347c478bd9Sstevel@tonic-gate 	CHR *p;
2357c478bd9Sstevel@tonic-gate 	i = name[v];
2367c478bd9Sstevel@tonic-gate 	if (!ISOPERATOR(i))
2377c478bd9Sstevel@tonic-gate 		i = 1;
2387c478bd9Sstevel@tonic-gate 	switch (i) {
2397c478bd9Sstevel@tonic-gate 	case 1: case RCCL: case RNCCL:
2407c478bd9Sstevel@tonic-gate 	case RNULLS: case FINAL:
2417c478bd9Sstevel@tonic-gate 	case S1FINAL: case S2FINAL:
2427c478bd9Sstevel@tonic-gate 	/*
2437c478bd9Sstevel@tonic-gate 	 * XCU4: if we are working on an exclusive start state and
2447c478bd9Sstevel@tonic-gate 	 * the parent of this position is not RXSCON or RSTR this
2457c478bd9Sstevel@tonic-gate 	 * is not an active position.
2467c478bd9Sstevel@tonic-gate 	 *
2477c478bd9Sstevel@tonic-gate 	 * (There is a possibility that RSXCON appreas as the
2487c478bd9Sstevel@tonic-gate 	 *  (parent)* node. Check it by check_me().)
2497c478bd9Sstevel@tonic-gate 	 */
2507c478bd9Sstevel@tonic-gate 		if ((exclusive[stnum/2]) &&
2517c478bd9Sstevel@tonic-gate 		    ISOPERATOR(name[parent[v]]) &&
2527c478bd9Sstevel@tonic-gate 		    (name[parent[v]] != RXSCON) &&
2537c478bd9Sstevel@tonic-gate 		    (name[parent[v]] != RSTR) &&
2547c478bd9Sstevel@tonic-gate 		    (check_me(v) == 0)) {
2557c478bd9Sstevel@tonic-gate 				break;
2567c478bd9Sstevel@tonic-gate 		}
2577c478bd9Sstevel@tonic-gate 		if (tmpstat[v] == FALSE) {
2587c478bd9Sstevel@tonic-gate 			count++;
2597c478bd9Sstevel@tonic-gate 			tmpstat[v] = TRUE;
2607c478bd9Sstevel@tonic-gate 		}
2617c478bd9Sstevel@tonic-gate 		break;
2627c478bd9Sstevel@tonic-gate 	case BAR: case RNEWE:
2637c478bd9Sstevel@tonic-gate 		first(left[v]);
2647c478bd9Sstevel@tonic-gate 		first(right[v]);
2657c478bd9Sstevel@tonic-gate 		break;
2667c478bd9Sstevel@tonic-gate 	case CARAT:
2677c478bd9Sstevel@tonic-gate 		if (stnum % 2 == 1)
2687c478bd9Sstevel@tonic-gate 			first(left[v]);
2697c478bd9Sstevel@tonic-gate 		break;
2707c478bd9Sstevel@tonic-gate 	/* XCU4: add RXSCON */
2717c478bd9Sstevel@tonic-gate 	case RXSCON:
2727c478bd9Sstevel@tonic-gate 	case RSCON:
2737c478bd9Sstevel@tonic-gate 		i = stnum/2 +1;
2747c478bd9Sstevel@tonic-gate 		p = (CHR *) right[v];
2757c478bd9Sstevel@tonic-gate 		while (*p)
2767c478bd9Sstevel@tonic-gate 			if (*p++ == i) {
2777c478bd9Sstevel@tonic-gate 				first(left[v]);
2787c478bd9Sstevel@tonic-gate 				break;
2797c478bd9Sstevel@tonic-gate 			}
2807c478bd9Sstevel@tonic-gate 		break;
2817c478bd9Sstevel@tonic-gate 	case STAR: case QUEST:
2827c478bd9Sstevel@tonic-gate 	case PLUS:  case RSTR:
2837c478bd9Sstevel@tonic-gate 	/*
2847c478bd9Sstevel@tonic-gate 	 * XCU4: if we are working on an exclusive start state and
2857c478bd9Sstevel@tonic-gate 	 * the parent of this position is not RXSCON or RSTR this
2867c478bd9Sstevel@tonic-gate 	 * is not an active position.
2877c478bd9Sstevel@tonic-gate 	 *
2887c478bd9Sstevel@tonic-gate 	 * (There is a possibility that RSXCON appreas as the
2897c478bd9Sstevel@tonic-gate 	 *  (parent)* node. Check it by check_me().)
2907c478bd9Sstevel@tonic-gate 	 */
2917c478bd9Sstevel@tonic-gate 		if ((exclusive[stnum/2]) &&
2927c478bd9Sstevel@tonic-gate 		    ISOPERATOR(name[parent[v]]) &&
2937c478bd9Sstevel@tonic-gate 		    (name[parent[v]] != RXSCON) &&
2947c478bd9Sstevel@tonic-gate 		    (name[parent[v]] != RSTR) &&
2957c478bd9Sstevel@tonic-gate 		    (check_me(v) == 0)) {
2967c478bd9Sstevel@tonic-gate 				break;
2977c478bd9Sstevel@tonic-gate 		}
2987c478bd9Sstevel@tonic-gate 		first(left[v]);
2997c478bd9Sstevel@tonic-gate 		break;
3007c478bd9Sstevel@tonic-gate 	case RCAT: case DIV:
3017c478bd9Sstevel@tonic-gate 		first(left[v]);
3027c478bd9Sstevel@tonic-gate 		if (nullstr[left[v]])
3037c478bd9Sstevel@tonic-gate 			first(right[v]);
3047c478bd9Sstevel@tonic-gate 		break;
3057c478bd9Sstevel@tonic-gate #ifdef DEBUG
3067c478bd9Sstevel@tonic-gate 	default:
3077c478bd9Sstevel@tonic-gate 		warning("bad switch first %d", v);
3087c478bd9Sstevel@tonic-gate #endif
3097c478bd9Sstevel@tonic-gate 	}
3107c478bd9Sstevel@tonic-gate }
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate void
3137c478bd9Sstevel@tonic-gate cgoto(void)
3147c478bd9Sstevel@tonic-gate {
3157c478bd9Sstevel@tonic-gate 	int i, j;
3167c478bd9Sstevel@tonic-gate 	static int s;
3177c478bd9Sstevel@tonic-gate 	int npos, curpos, n;
3187c478bd9Sstevel@tonic-gate 	int tryit;
3197c478bd9Sstevel@tonic-gate 	CHR tch[MAXNCG];
3207c478bd9Sstevel@tonic-gate 	int tst[MAXNCG];
3217c478bd9Sstevel@tonic-gate 	CHR *q;
3227c478bd9Sstevel@tonic-gate 	/* generate initial state, for each start condition */
3237c478bd9Sstevel@tonic-gate 	if (ratfor) {
3247c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "blockdata\n");
3257c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "common /Lvstop/ vstop\n");
3267c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "define Svstop %d\n", nstates+1);
3277c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "integer vstop(Svstop)\n");
3287c478bd9Sstevel@tonic-gate 	} else
3297c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "int yyvstop[] = {\n0,\n");
3307c478bd9Sstevel@tonic-gate 	while (stnum < 2 || stnum/2 < sptr) {
3317c478bd9Sstevel@tonic-gate 		for (i = 0; i < tptr; i++)
3327c478bd9Sstevel@tonic-gate 			tmpstat[i] = 0;
3337c478bd9Sstevel@tonic-gate 		count = 0;
3347c478bd9Sstevel@tonic-gate 		if (tptr > 0)
3357c478bd9Sstevel@tonic-gate 			first(tptr-1);
3367c478bd9Sstevel@tonic-gate 		add(state, stnum);
3377c478bd9Sstevel@tonic-gate #ifdef DEBUG
3387c478bd9Sstevel@tonic-gate 		if (debug) {
3397c478bd9Sstevel@tonic-gate 			if (stnum > 1)
3407c478bd9Sstevel@tonic-gate 				(void) printf("%ws:\n", sname[stnum/2]);
3417c478bd9Sstevel@tonic-gate 			pstate(stnum);
3427c478bd9Sstevel@tonic-gate 		}
3437c478bd9Sstevel@tonic-gate #endif
3447c478bd9Sstevel@tonic-gate 		stnum++;
3457c478bd9Sstevel@tonic-gate 	}
3467c478bd9Sstevel@tonic-gate 	stnum--;
3477c478bd9Sstevel@tonic-gate 	/* even stnum = might not be at line begin */
3487c478bd9Sstevel@tonic-gate 	/* odd stnum  = must be at line begin */
3497c478bd9Sstevel@tonic-gate 	/* even states can occur anywhere, odd states only at line begin */
3507c478bd9Sstevel@tonic-gate 	for (s = 0; s <= stnum; s++) {
3517c478bd9Sstevel@tonic-gate 		tryit = FALSE;
3527c478bd9Sstevel@tonic-gate 		cpackflg[s] = FALSE;
3537c478bd9Sstevel@tonic-gate 		sfall[s] = -1;
3547c478bd9Sstevel@tonic-gate 		acompute(s);
3557c478bd9Sstevel@tonic-gate 		for (i = 0; i < ncg; i++)
3567c478bd9Sstevel@tonic-gate 			symbol[i] = 0;
3577c478bd9Sstevel@tonic-gate 		npos = *state[s];
3587c478bd9Sstevel@tonic-gate 		for (i = 1; i <= npos; i++) {
3597c478bd9Sstevel@tonic-gate 			curpos = *(state[s]+i);
3607c478bd9Sstevel@tonic-gate 			if (!ISOPERATOR(name[curpos]))
3617c478bd9Sstevel@tonic-gate 				symbol[name[curpos]] = TRUE;
3627c478bd9Sstevel@tonic-gate 			else {
3637c478bd9Sstevel@tonic-gate 				switch (name[curpos]) {
3647c478bd9Sstevel@tonic-gate 				case RCCL:
3657c478bd9Sstevel@tonic-gate 					tryit = TRUE;
3667c478bd9Sstevel@tonic-gate 					q = (CHR *)left[curpos];
3677c478bd9Sstevel@tonic-gate 					while (*q) {
3687c478bd9Sstevel@tonic-gate 						for (j = 1; j < ncg; j++)
3697c478bd9Sstevel@tonic-gate 							if (cindex[j] == *q)
37067298654Sdamico 								symbol[j] =
37167298654Sdamico 								    TRUE;
3727c478bd9Sstevel@tonic-gate 						q++;
3737c478bd9Sstevel@tonic-gate 					}
3747c478bd9Sstevel@tonic-gate 					break;
3757c478bd9Sstevel@tonic-gate 				case RSTR:
3767c478bd9Sstevel@tonic-gate 					symbol[right[curpos]] = TRUE;
3777c478bd9Sstevel@tonic-gate 					break;
3787c478bd9Sstevel@tonic-gate #ifdef DEBUG
3797c478bd9Sstevel@tonic-gate 				case RNULLS:
3807c478bd9Sstevel@tonic-gate 				case FINAL:
3817c478bd9Sstevel@tonic-gate 				case S1FINAL:
3827c478bd9Sstevel@tonic-gate 				case S2FINAL:
3837c478bd9Sstevel@tonic-gate 					break;
3847c478bd9Sstevel@tonic-gate 				default:
3857c478bd9Sstevel@tonic-gate 					warning(
3867c478bd9Sstevel@tonic-gate 					"bad switch cgoto %d state %d",
3877c478bd9Sstevel@tonic-gate 					    curpos, s);
3887c478bd9Sstevel@tonic-gate 					break;
3897c478bd9Sstevel@tonic-gate #endif
3907c478bd9Sstevel@tonic-gate 				}
3917c478bd9Sstevel@tonic-gate 			}
3927c478bd9Sstevel@tonic-gate 		}
3937c478bd9Sstevel@tonic-gate #ifdef DEBUG
3947c478bd9Sstevel@tonic-gate 		if (debug) {
3957c478bd9Sstevel@tonic-gate 			printf("State %d transitions on char-group {", s);
3967c478bd9Sstevel@tonic-gate 			charc = 0;
3977c478bd9Sstevel@tonic-gate 			for (i = 1; i < ncg; i++) {
3987c478bd9Sstevel@tonic-gate 				if (symbol[i]) {
3997c478bd9Sstevel@tonic-gate 					printf("%d,", i);
4007c478bd9Sstevel@tonic-gate 				}
4017c478bd9Sstevel@tonic-gate 				if (i == ncg-1)
4027c478bd9Sstevel@tonic-gate 					printf("}\n");
4037c478bd9Sstevel@tonic-gate 				if (charc > LINESIZE/4) {
4047c478bd9Sstevel@tonic-gate 					charc = 0;
4057c478bd9Sstevel@tonic-gate 					printf("\n\t");
4067c478bd9Sstevel@tonic-gate 				}
4077c478bd9Sstevel@tonic-gate 			}
4087c478bd9Sstevel@tonic-gate 		}
4097c478bd9Sstevel@tonic-gate #endif
4107c478bd9Sstevel@tonic-gate 		/* for each char, calculate next state */
4117c478bd9Sstevel@tonic-gate 		n = 0;
4127c478bd9Sstevel@tonic-gate 		for (i = 1; i < ncg; i++) {
4137c478bd9Sstevel@tonic-gate 			if (symbol[i]) {
4147c478bd9Sstevel@tonic-gate 				/* executed for each state, transition pair */
4157c478bd9Sstevel@tonic-gate 				nextstate(s, i);
4167c478bd9Sstevel@tonic-gate 				xstate = notin(stnum);
4177c478bd9Sstevel@tonic-gate 				if (xstate == -2)
4187c478bd9Sstevel@tonic-gate 					warning("bad state  %d %o", s, i);
4197c478bd9Sstevel@tonic-gate 				else if (xstate == -1) {
4207c478bd9Sstevel@tonic-gate 					if (stnum+1 >= nstates) {
4217c478bd9Sstevel@tonic-gate 						stnum++;
4227c478bd9Sstevel@tonic-gate 						error("Too many states %s",
4237c478bd9Sstevel@tonic-gate 						    (nstates == NSTATES ?
4247c478bd9Sstevel@tonic-gate 						    "\nTry using %n num":""));
4257c478bd9Sstevel@tonic-gate 					}
4267c478bd9Sstevel@tonic-gate 					add(state, ++stnum);
4277c478bd9Sstevel@tonic-gate #ifdef DEBUG
4287c478bd9Sstevel@tonic-gate 					if (debug)
4297c478bd9Sstevel@tonic-gate 						pstate(stnum);
4307c478bd9Sstevel@tonic-gate #endif
4317c478bd9Sstevel@tonic-gate 					tch[n] = i;
4327c478bd9Sstevel@tonic-gate 					tst[n++] = stnum;
4337c478bd9Sstevel@tonic-gate 				} else { /* xstate >= 0 ==> state exists */
4347c478bd9Sstevel@tonic-gate 					tch[n] = i;
4357c478bd9Sstevel@tonic-gate 					tst[n++] = xstate;
4367c478bd9Sstevel@tonic-gate 				}
4377c478bd9Sstevel@tonic-gate 			}
4387c478bd9Sstevel@tonic-gate 		}
4397c478bd9Sstevel@tonic-gate 		tch[n] = 0;
4407c478bd9Sstevel@tonic-gate 		tst[n] = -1;
4417c478bd9Sstevel@tonic-gate 		/* pack transitions into permanent array */
4427c478bd9Sstevel@tonic-gate 		if (n > 0)
4437c478bd9Sstevel@tonic-gate 			packtrans(s, tch, tst, n, tryit);
4447c478bd9Sstevel@tonic-gate 		else
4457c478bd9Sstevel@tonic-gate 			gotof[s] = -1;
4467c478bd9Sstevel@tonic-gate 	}
447*1dd08564Sab196087 	(void) (ratfor ? fprintf(fout, "end\n") : fprintf(fout, "0};\n"));
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate /*
4517c478bd9Sstevel@tonic-gate  * Beware -- 70% of total CPU time is spent in this subroutine -
4527c478bd9Sstevel@tonic-gate  * if you don't believe me - try it yourself !
4537c478bd9Sstevel@tonic-gate  */
4547c478bd9Sstevel@tonic-gate static void
4557c478bd9Sstevel@tonic-gate nextstate(int s, int c)
4567c478bd9Sstevel@tonic-gate {
4577c478bd9Sstevel@tonic-gate 	int j, *newpos;
4587c478bd9Sstevel@tonic-gate 	CHR *temp, *tz;
4597c478bd9Sstevel@tonic-gate 	int *pos, i, *f, num, curpos, number;
4607c478bd9Sstevel@tonic-gate 	/* state to goto from state s on char c */
4617c478bd9Sstevel@tonic-gate 	num = *state[s];
4627c478bd9Sstevel@tonic-gate 	temp = tmpstat;
4637c478bd9Sstevel@tonic-gate 	pos = state[s] + 1;
4647c478bd9Sstevel@tonic-gate 	for (i = 0; i < num; i++) {
4657c478bd9Sstevel@tonic-gate 		curpos = *pos++;
4667c478bd9Sstevel@tonic-gate 		j = name[curpos];
4677c478bd9Sstevel@tonic-gate 		if ((!ISOPERATOR(j)) && j == c ||
4687c478bd9Sstevel@tonic-gate 		    j == RSTR && c == right[curpos] ||
4697c478bd9Sstevel@tonic-gate 		    j == RCCL && member(c, (CHR *) left[curpos])) {
4707c478bd9Sstevel@tonic-gate 			f = foll[curpos];
4717c478bd9Sstevel@tonic-gate 			number = *f;
4727c478bd9Sstevel@tonic-gate 			newpos = f+1;
4737c478bd9Sstevel@tonic-gate 			for (j = 0; j < number; j++)
4747c478bd9Sstevel@tonic-gate 				temp[*newpos++] = 2;
4757c478bd9Sstevel@tonic-gate 		}
4767c478bd9Sstevel@tonic-gate 	}
4777c478bd9Sstevel@tonic-gate 	j = 0;
4787c478bd9Sstevel@tonic-gate 	tz = temp + tptr;
4797c478bd9Sstevel@tonic-gate 	while (temp < tz) {
4807c478bd9Sstevel@tonic-gate 		if (*temp == 2) {
4817c478bd9Sstevel@tonic-gate 			j++;
4827c478bd9Sstevel@tonic-gate 			*temp++ = 1;
4837c478bd9Sstevel@tonic-gate 		}
4847c478bd9Sstevel@tonic-gate 		else
4857c478bd9Sstevel@tonic-gate 			*temp++ = 0;
4867c478bd9Sstevel@tonic-gate 	}
4877c478bd9Sstevel@tonic-gate 	count = j;
4887c478bd9Sstevel@tonic-gate }
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate static int
4917c478bd9Sstevel@tonic-gate notin(int n)
4927c478bd9Sstevel@tonic-gate {	/* see if tmpstat occurs previously */
4937c478bd9Sstevel@tonic-gate 	int *j, k;
4947c478bd9Sstevel@tonic-gate 	CHR *temp;
4957c478bd9Sstevel@tonic-gate 	int i;
4967c478bd9Sstevel@tonic-gate 	if (count == 0)
4977c478bd9Sstevel@tonic-gate 		return (-2);
4987c478bd9Sstevel@tonic-gate 	temp = tmpstat;
4997c478bd9Sstevel@tonic-gate 	for (i = n; i >= 0; i--) { /* for each state */
5007c478bd9Sstevel@tonic-gate 		j = state[i];
5017c478bd9Sstevel@tonic-gate 		if (count == *j++) {
5027c478bd9Sstevel@tonic-gate 			for (k = 0; k < count; k++)
5037c478bd9Sstevel@tonic-gate 				if (!temp[*j++])
5047c478bd9Sstevel@tonic-gate 					break;
5057c478bd9Sstevel@tonic-gate 			if (k >= count)
5067c478bd9Sstevel@tonic-gate 				return (i);
5077c478bd9Sstevel@tonic-gate 		}
5087c478bd9Sstevel@tonic-gate 	}
5097c478bd9Sstevel@tonic-gate 	return (-1);
5107c478bd9Sstevel@tonic-gate }
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate static void
5137c478bd9Sstevel@tonic-gate packtrans(int st, CHR *tch, int *tst, int cnt, int tryit)
5147c478bd9Sstevel@tonic-gate {
5157c478bd9Sstevel@tonic-gate 	/*
5167c478bd9Sstevel@tonic-gate 	 * pack transitions into nchar, nexts
5177c478bd9Sstevel@tonic-gate 	 * nchar is terminated by '\0', nexts uses cnt, followed by elements
5187c478bd9Sstevel@tonic-gate 	 * gotof[st] = index into nchr, nexts for state st
5197c478bd9Sstevel@tonic-gate 	 * sfall[st] =  t implies t is fall back state for st
5207c478bd9Sstevel@tonic-gate 	 * == -1 implies no fall back
5217c478bd9Sstevel@tonic-gate 	 */
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 	int cmin, cval, tcnt, diff, p, *ast;
5247c478bd9Sstevel@tonic-gate 	int i, j, k;
5257c478bd9Sstevel@tonic-gate 	CHR *ach;
5267c478bd9Sstevel@tonic-gate 	int go[MAXNCG], temp[MAXNCG], index, c;
5277c478bd9Sstevel@tonic-gate 	int swork[MAXNCG];
5287c478bd9Sstevel@tonic-gate 	CHR cwork[MAXNCG];
5297c478bd9Sstevel@tonic-gate 	int upper;
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate 	rcount += (long)cnt;
5327c478bd9Sstevel@tonic-gate 	cmin = -1;
5337c478bd9Sstevel@tonic-gate 	cval = ncg;
5347c478bd9Sstevel@tonic-gate 	ast = tst;
5357c478bd9Sstevel@tonic-gate 	ach = tch;
5367c478bd9Sstevel@tonic-gate 	/* try to pack transitions using ccl's */
5377c478bd9Sstevel@tonic-gate 	if (!optim)
5387c478bd9Sstevel@tonic-gate 		goto nopack; /* skip all compaction */
5397c478bd9Sstevel@tonic-gate 	if (tryit) { /* ccl's used */
5407c478bd9Sstevel@tonic-gate 		for (i = 1; i < ncg; i++) {
5417c478bd9Sstevel@tonic-gate 			go[i] = temp[i] = -1;
5427c478bd9Sstevel@tonic-gate 			symbol[i] = 1;
5437c478bd9Sstevel@tonic-gate 		}
5447c478bd9Sstevel@tonic-gate 		for (i = 0; i < cnt; i++) {
5457c478bd9Sstevel@tonic-gate 			index = (unsigned char) tch[i];
5467c478bd9Sstevel@tonic-gate 			if ((index >= 0) && (index < NCH)) {
5477c478bd9Sstevel@tonic-gate 				go[index] = tst[i];
5487c478bd9Sstevel@tonic-gate 				symbol[index] = 0;
5497c478bd9Sstevel@tonic-gate 			} else {
550*1dd08564Sab196087 				(void) fprintf(stderr,
5517c478bd9Sstevel@tonic-gate "lex`sub2`packtran: tch[%d] out of bounds (%d)\n",
552*1dd08564Sab196087 				    i, (int)tch[i]);
5537c478bd9Sstevel@tonic-gate 			}
5547c478bd9Sstevel@tonic-gate 		}
5557c478bd9Sstevel@tonic-gate 		for (i = 0; i < cnt; i++) {
5567c478bd9Sstevel@tonic-gate 			c = match[tch[i]];
5577c478bd9Sstevel@tonic-gate 			if (go[c] != tst[i] || c == tch[i])
5587c478bd9Sstevel@tonic-gate 				temp[tch[i]] = tst[i];
5597c478bd9Sstevel@tonic-gate 		}
5607c478bd9Sstevel@tonic-gate 		/* fill in error entries */
5617c478bd9Sstevel@tonic-gate 		for (i = 1; i < ncg; i++)
5627c478bd9Sstevel@tonic-gate 			if (symbol[i])
5637c478bd9Sstevel@tonic-gate 				temp[i] = -2;	/* error trans */
5647c478bd9Sstevel@tonic-gate 		/* count them */
5657c478bd9Sstevel@tonic-gate 		k = 0;
5667c478bd9Sstevel@tonic-gate 		for (i = 1; i < ncg; i++)
5677c478bd9Sstevel@tonic-gate 			if (temp[i] != -1)
5687c478bd9Sstevel@tonic-gate 				k++;
5697c478bd9Sstevel@tonic-gate 		if (k < cnt) { /* compress by char */
5707c478bd9Sstevel@tonic-gate #ifdef DEBUG
5717c478bd9Sstevel@tonic-gate 			if (debug)
5727c478bd9Sstevel@tonic-gate 				(void) printf(
5737c478bd9Sstevel@tonic-gate 				"use compression  %d,  %d vs %d\n", st, k, cnt);
5747c478bd9Sstevel@tonic-gate #endif
5757c478bd9Sstevel@tonic-gate 			k = 0;
5767c478bd9Sstevel@tonic-gate 			for (i = 1; i < ncg; i++)
5777c478bd9Sstevel@tonic-gate 				if (temp[i] != -1) {
5787c478bd9Sstevel@tonic-gate 					cwork[k] = i;
5797c478bd9Sstevel@tonic-gate 					swork[k++] =
5807c478bd9Sstevel@tonic-gate 					    (temp[i] == -2 ? -1 : temp[i]);
5817c478bd9Sstevel@tonic-gate 				}
5827c478bd9Sstevel@tonic-gate 			cwork[k] = 0;
5837c478bd9Sstevel@tonic-gate #ifdef PC
5847c478bd9Sstevel@tonic-gate 			ach = cwork;
5857c478bd9Sstevel@tonic-gate 			ast = swork;
5867c478bd9Sstevel@tonic-gate 			cnt = k;
5877c478bd9Sstevel@tonic-gate 			cpackflg[st] = TRUE;
5887c478bd9Sstevel@tonic-gate #endif
5897c478bd9Sstevel@tonic-gate 		}
5907c478bd9Sstevel@tonic-gate 	}
5917c478bd9Sstevel@tonic-gate 	/*
5927c478bd9Sstevel@tonic-gate 	 * get most similar state
5937c478bd9Sstevel@tonic-gate 	 * reject state with more transitions,
5947c478bd9Sstevel@tonic-gate 	 * state already represented by a third state,
5957c478bd9Sstevel@tonic-gate 	 * and state which is compressed by char if ours is not to be
5967c478bd9Sstevel@tonic-gate 	 */
5977c478bd9Sstevel@tonic-gate 	for (i = 0; i < st; i++) {
5987c478bd9Sstevel@tonic-gate 		if (sfall[i] != -1)
5997c478bd9Sstevel@tonic-gate 			continue;
6007c478bd9Sstevel@tonic-gate 		if (cpackflg[st] == 1)
6017c478bd9Sstevel@tonic-gate 			if (!(cpackflg[i] == 1))
6027c478bd9Sstevel@tonic-gate 				continue;
6037c478bd9Sstevel@tonic-gate 		p = gotof[i];
6047c478bd9Sstevel@tonic-gate 		if (p == -1) /* no transitions */
6057c478bd9Sstevel@tonic-gate 			continue;
6067c478bd9Sstevel@tonic-gate 		tcnt = nexts[p];
6077c478bd9Sstevel@tonic-gate 		if (tcnt > cnt)
6087c478bd9Sstevel@tonic-gate 			continue;
6097c478bd9Sstevel@tonic-gate 		diff = 0;
6107c478bd9Sstevel@tonic-gate 		k = 0;
6117c478bd9Sstevel@tonic-gate 		j = 0;
6127c478bd9Sstevel@tonic-gate 		upper = p + tcnt;
6137c478bd9Sstevel@tonic-gate 		while (ach[j] && p < upper) {
6147c478bd9Sstevel@tonic-gate 			while (ach[j] < nchar[p] && ach[j]) {
6157c478bd9Sstevel@tonic-gate 				diff++;
6167c478bd9Sstevel@tonic-gate 				j++;
6177c478bd9Sstevel@tonic-gate 			}
6187c478bd9Sstevel@tonic-gate 			if (ach[j] == 0)
6197c478bd9Sstevel@tonic-gate 				break;
6207c478bd9Sstevel@tonic-gate 			if (ach[j] > nchar[p]) {
6217c478bd9Sstevel@tonic-gate 				diff = ncg;
6227c478bd9Sstevel@tonic-gate 				break;
6237c478bd9Sstevel@tonic-gate 			}
6247c478bd9Sstevel@tonic-gate 			/* ach[j] == nchar[p] */
6257c478bd9Sstevel@tonic-gate 			if (ast[j] != nexts[++p] ||
6267c478bd9Sstevel@tonic-gate 			    ast[j] == -1 ||
6277c478bd9Sstevel@tonic-gate 			    (cpackflg[st] && ach[j] != match[ach[j]]))
6287c478bd9Sstevel@tonic-gate 				diff++;
6297c478bd9Sstevel@tonic-gate 			j++;
6307c478bd9Sstevel@tonic-gate 		}
6317c478bd9Sstevel@tonic-gate 		while (ach[j]) {
6327c478bd9Sstevel@tonic-gate 			diff++;
6337c478bd9Sstevel@tonic-gate 			j++;
6347c478bd9Sstevel@tonic-gate 		}
6357c478bd9Sstevel@tonic-gate 		if (p < upper)
6367c478bd9Sstevel@tonic-gate 			diff = ncg;
6377c478bd9Sstevel@tonic-gate 		if (diff < cval && diff < tcnt) {
6387c478bd9Sstevel@tonic-gate 			cval = diff;
6397c478bd9Sstevel@tonic-gate 			cmin = i;
6407c478bd9Sstevel@tonic-gate 			if (cval == 0)
6417c478bd9Sstevel@tonic-gate 				break;
6427c478bd9Sstevel@tonic-gate 		}
6437c478bd9Sstevel@tonic-gate 	}
6447c478bd9Sstevel@tonic-gate 	/* cmin = state "most like" state st */
6457c478bd9Sstevel@tonic-gate #ifdef DEBUG
6467c478bd9Sstevel@tonic-gate 	if (debug)
6477c478bd9Sstevel@tonic-gate 		(void) printf("select st %d for st %d diff %d\n",
6487c478bd9Sstevel@tonic-gate 		    cmin, st, cval);
6497c478bd9Sstevel@tonic-gate #endif
6507c478bd9Sstevel@tonic-gate #ifdef PS
6517c478bd9Sstevel@tonic-gate 	if (cmin != -1) { /* if we can use st cmin */
6527c478bd9Sstevel@tonic-gate 		gotof[st] = nptr;
6537c478bd9Sstevel@tonic-gate 		k = 0;
6547c478bd9Sstevel@tonic-gate 		sfall[st] = cmin;
6557c478bd9Sstevel@tonic-gate 		p = gotof[cmin] + 1;
6567c478bd9Sstevel@tonic-gate 		j = 0;
6577c478bd9Sstevel@tonic-gate 		while (ach[j]) {
6587c478bd9Sstevel@tonic-gate 			/* if cmin has a transition on c, then so will st */
6597c478bd9Sstevel@tonic-gate 			/* st may be "larger" than cmin, however */
6607c478bd9Sstevel@tonic-gate 			while (ach[j] < nchar[p-1] && ach[j]) {
6617c478bd9Sstevel@tonic-gate 				k++;
6627c478bd9Sstevel@tonic-gate 				nchar[nptr] = ach[j];
6637c478bd9Sstevel@tonic-gate 				nexts[++nptr] = ast[j];
6647c478bd9Sstevel@tonic-gate 				j++;
6657c478bd9Sstevel@tonic-gate 			}
6667c478bd9Sstevel@tonic-gate 			if (nchar[p-1] == 0)
6677c478bd9Sstevel@tonic-gate 				break;
6687c478bd9Sstevel@tonic-gate 			if (ach[j] > nchar[p-1]) {
6697c478bd9Sstevel@tonic-gate 				warning("bad transition %d %d", st, cmin);
6707c478bd9Sstevel@tonic-gate 				goto nopack;
6717c478bd9Sstevel@tonic-gate 			}
6727c478bd9Sstevel@tonic-gate 			/* ach[j] == nchar[p-1] */
6737c478bd9Sstevel@tonic-gate 			if (ast[j] != nexts[p] ||
6747c478bd9Sstevel@tonic-gate 			    ast[j] == -1 ||
6757c478bd9Sstevel@tonic-gate 			    (cpackflg[st] && ach[j] != match[ach[j]])) {
6767c478bd9Sstevel@tonic-gate 				k++;
6777c478bd9Sstevel@tonic-gate 				nchar[nptr] = ach[j];
6787c478bd9Sstevel@tonic-gate 				nexts[++nptr] = ast[j];
6797c478bd9Sstevel@tonic-gate 			}
6807c478bd9Sstevel@tonic-gate 			p++;
6817c478bd9Sstevel@tonic-gate 			j++;
6827c478bd9Sstevel@tonic-gate 		}
6837c478bd9Sstevel@tonic-gate 		while (ach[j]) {
6847c478bd9Sstevel@tonic-gate 			nchar[nptr] = ach[j];
6857c478bd9Sstevel@tonic-gate 			nexts[++nptr] = ast[j++];
6867c478bd9Sstevel@tonic-gate 			k++;
6877c478bd9Sstevel@tonic-gate 		}
6887c478bd9Sstevel@tonic-gate 		nexts[gotof[st]] = cnt = k;
6897c478bd9Sstevel@tonic-gate 		nchar[nptr++] = 0;
6907c478bd9Sstevel@tonic-gate 	} else {
6917c478bd9Sstevel@tonic-gate #endif
6927c478bd9Sstevel@tonic-gate nopack:
6937c478bd9Sstevel@tonic-gate 	/* stick it in */
6947c478bd9Sstevel@tonic-gate 		gotof[st] = nptr;
6957c478bd9Sstevel@tonic-gate 		nexts[nptr] = cnt;
6967c478bd9Sstevel@tonic-gate 		for (i = 0; i < cnt; i++) {
6977c478bd9Sstevel@tonic-gate 			nchar[nptr] = ach[i];
6987c478bd9Sstevel@tonic-gate 			nexts[++nptr] = ast[i];
6997c478bd9Sstevel@tonic-gate 		}
7007c478bd9Sstevel@tonic-gate 		nchar[nptr++] = 0;
7017c478bd9Sstevel@tonic-gate #ifdef PS
7027c478bd9Sstevel@tonic-gate 	}
7037c478bd9Sstevel@tonic-gate #endif
7047c478bd9Sstevel@tonic-gate 	if (cnt < 1) {
7057c478bd9Sstevel@tonic-gate 		gotof[st] = -1;
7067c478bd9Sstevel@tonic-gate 		nptr--;
7077c478bd9Sstevel@tonic-gate 	} else
7087c478bd9Sstevel@tonic-gate 		if (nptr > ntrans)
7097c478bd9Sstevel@tonic-gate 			error(
7107c478bd9Sstevel@tonic-gate 			"Too many transitions %s",
7117c478bd9Sstevel@tonic-gate 			    (ntrans == NTRANS ? "\nTry using %a num" : ""));
7127c478bd9Sstevel@tonic-gate }
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate #ifdef DEBUG
7157c478bd9Sstevel@tonic-gate void
7167c478bd9Sstevel@tonic-gate pstate(int s)
7177c478bd9Sstevel@tonic-gate {
7187c478bd9Sstevel@tonic-gate 	int *p, i, j;
7197c478bd9Sstevel@tonic-gate 	(void) printf("State %d:\n", s);
7207c478bd9Sstevel@tonic-gate 	p = state[s];
7217c478bd9Sstevel@tonic-gate 	i = *p++;
7227c478bd9Sstevel@tonic-gate 	if (i == 0)
7237c478bd9Sstevel@tonic-gate 		return;
7247c478bd9Sstevel@tonic-gate 	(void) printf("%4d", *p++);
7257c478bd9Sstevel@tonic-gate 	for (j = 1; j < i; j++) {
7267c478bd9Sstevel@tonic-gate 		(void) printf(", %4d", *p++);
7277c478bd9Sstevel@tonic-gate 		if (j%30 == 0)
7287c478bd9Sstevel@tonic-gate 			(void) putchar('\n');
7297c478bd9Sstevel@tonic-gate 	}
7307c478bd9Sstevel@tonic-gate 	(void) putchar('\n');
7317c478bd9Sstevel@tonic-gate }
7327c478bd9Sstevel@tonic-gate #endif
7337c478bd9Sstevel@tonic-gate 
7347c478bd9Sstevel@tonic-gate static int
7357c478bd9Sstevel@tonic-gate member(int d, CHR *t)
7367c478bd9Sstevel@tonic-gate {
7377c478bd9Sstevel@tonic-gate 	int c;
7387c478bd9Sstevel@tonic-gate 	CHR *s;
7397c478bd9Sstevel@tonic-gate 	c = d;
7407c478bd9Sstevel@tonic-gate 	s = t;
7417c478bd9Sstevel@tonic-gate 	c = cindex[c];
7427c478bd9Sstevel@tonic-gate 	while (*s)
7437c478bd9Sstevel@tonic-gate 		if (*s++ == c)
7447c478bd9Sstevel@tonic-gate 			return (1);
7457c478bd9Sstevel@tonic-gate 	return (0);
7467c478bd9Sstevel@tonic-gate }
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate #ifdef DEBUG
7497c478bd9Sstevel@tonic-gate void
7507c478bd9Sstevel@tonic-gate stprt(int i)
7517c478bd9Sstevel@tonic-gate {
7527c478bd9Sstevel@tonic-gate 	int p, t;
7537c478bd9Sstevel@tonic-gate 	(void) printf("State %d:", i);
7547c478bd9Sstevel@tonic-gate 	/* print actions, if any */
7557c478bd9Sstevel@tonic-gate 	t = atable[i];
7567c478bd9Sstevel@tonic-gate 	if (t != -1)
7577c478bd9Sstevel@tonic-gate 		(void) printf(" final");
7587c478bd9Sstevel@tonic-gate 	(void) putchar('\n');
7597c478bd9Sstevel@tonic-gate 	if (cpackflg[i] == TRUE)
7607c478bd9Sstevel@tonic-gate 		(void) printf("backup char in use\n");
7617c478bd9Sstevel@tonic-gate 	if (sfall[i] != -1)
7627c478bd9Sstevel@tonic-gate 		(void) printf("fall back state %d\n", sfall[i]);
7637c478bd9Sstevel@tonic-gate 	p = gotof[i];
7647c478bd9Sstevel@tonic-gate 	if (p == -1)
7657c478bd9Sstevel@tonic-gate 		return;
7667c478bd9Sstevel@tonic-gate 	(void) printf("(%d transitions)\n", nexts[p]);
7677c478bd9Sstevel@tonic-gate 	while (nchar[p]) {
7687c478bd9Sstevel@tonic-gate 		charc = 0;
7697c478bd9Sstevel@tonic-gate 		if (nexts[p+1] >= 0)
7707c478bd9Sstevel@tonic-gate 			(void) printf("%d\t", nexts[p+1]);
7717c478bd9Sstevel@tonic-gate 		else
7727c478bd9Sstevel@tonic-gate 			(void) printf("err\t");
7737c478bd9Sstevel@tonic-gate 		allprint(nchar[p++]);
7747c478bd9Sstevel@tonic-gate 		while (nexts[p] == nexts[p+1] && nchar[p]) {
7757c478bd9Sstevel@tonic-gate 			if (charc > LINESIZE) {
7767c478bd9Sstevel@tonic-gate 				charc = 0;
7777c478bd9Sstevel@tonic-gate 				(void) printf("\n\t");
7787c478bd9Sstevel@tonic-gate 			}
7797c478bd9Sstevel@tonic-gate 			allprint(nchar[p++]);
7807c478bd9Sstevel@tonic-gate 		}
7817c478bd9Sstevel@tonic-gate 		(void) putchar('\n');
7827c478bd9Sstevel@tonic-gate 	}
7837c478bd9Sstevel@tonic-gate 	(void) putchar('\n');
7847c478bd9Sstevel@tonic-gate }
7857c478bd9Sstevel@tonic-gate #endif
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate /* compute action list = set of poss. actions */
7887c478bd9Sstevel@tonic-gate static void
7897c478bd9Sstevel@tonic-gate acompute(int s)
7907c478bd9Sstevel@tonic-gate {
7917c478bd9Sstevel@tonic-gate 	int *p, i, j;
7927c478bd9Sstevel@tonic-gate 	int q, r;
7937c478bd9Sstevel@tonic-gate 	int cnt, m;
7947c478bd9Sstevel@tonic-gate 	int temp[MAXPOSSTATE], k, neg[MAXPOSSTATE], n;
7957c478bd9Sstevel@tonic-gate 	k = 0;
7967c478bd9Sstevel@tonic-gate 	n = 0;
7977c478bd9Sstevel@tonic-gate 	p = state[s];
7987c478bd9Sstevel@tonic-gate 	cnt = *p++;
7997c478bd9Sstevel@tonic-gate 	if (cnt > MAXPOSSTATE)
8007c478bd9Sstevel@tonic-gate 		error("Too many positions for one state - acompute");
8017c478bd9Sstevel@tonic-gate 	for (i = 0; i < cnt; i++) {
8027c478bd9Sstevel@tonic-gate 		q = *p;
8037c478bd9Sstevel@tonic-gate 		if (name[q] == FINAL)
8047c478bd9Sstevel@tonic-gate 			temp[k++] = left[q];
8057c478bd9Sstevel@tonic-gate 		else if (name[q] == S1FINAL) {
8067c478bd9Sstevel@tonic-gate 			temp[k++] = left[q];
8077c478bd9Sstevel@tonic-gate 			if ((r = left[q]) >= NACTIONS)
8087c478bd9Sstevel@tonic-gate 				error(
8097c478bd9Sstevel@tonic-gate 				"INTERNAL ERROR:left[%d]==%d>=NACTIONS", q, r);
8107c478bd9Sstevel@tonic-gate 			extra[r] = 1;
8117c478bd9Sstevel@tonic-gate 		} else if (name[q] == S2FINAL)
8127c478bd9Sstevel@tonic-gate 			neg[n++] = left[q];
8137c478bd9Sstevel@tonic-gate 		p++;
8147c478bd9Sstevel@tonic-gate 	}
8157c478bd9Sstevel@tonic-gate 	atable[s] = -1;
8167c478bd9Sstevel@tonic-gate 	if (k < 1 && n < 1)
8177c478bd9Sstevel@tonic-gate 		return;
8187c478bd9Sstevel@tonic-gate #ifdef DEBUG
8197c478bd9Sstevel@tonic-gate 	if (debug)
8207c478bd9Sstevel@tonic-gate 		(void) printf("final %d actions:", s);
8217c478bd9Sstevel@tonic-gate #endif
8227c478bd9Sstevel@tonic-gate 	/* sort action list */
8237c478bd9Sstevel@tonic-gate 	for (i = 0; i < k; i++)
8247c478bd9Sstevel@tonic-gate 		for (j = i+1; j < k; j++)
8257c478bd9Sstevel@tonic-gate 			if (temp[j] < temp[i]) {
8267c478bd9Sstevel@tonic-gate 				m = temp[j];
8277c478bd9Sstevel@tonic-gate 				temp[j] = temp[i];
8287c478bd9Sstevel@tonic-gate 				temp[i] = m;
8297c478bd9Sstevel@tonic-gate 			}
8307c478bd9Sstevel@tonic-gate 	/* remove dups */
8317c478bd9Sstevel@tonic-gate 	for (i = 0; i < k-1; i++)
8327c478bd9Sstevel@tonic-gate 		if (temp[i] == temp[i+1])
8337c478bd9Sstevel@tonic-gate 			temp[i] = 0;
8347c478bd9Sstevel@tonic-gate 	/* copy to permanent quarters */
8357c478bd9Sstevel@tonic-gate 	atable[s] = aptr;
8367c478bd9Sstevel@tonic-gate #ifdef DEBUG
8377c478bd9Sstevel@tonic-gate 	if (!ratfor)
8387c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "/* actions for state %d */", s);
8397c478bd9Sstevel@tonic-gate #endif
8407c478bd9Sstevel@tonic-gate 	(void) putc('\n', fout);
8417c478bd9Sstevel@tonic-gate 	for (i = 0; i < k; i++)
8427c478bd9Sstevel@tonic-gate 		if (temp[i] != 0) {
843*1dd08564Sab196087 			(void) (ratfor ?
84467298654Sdamico 			    fprintf(fout, "data vstop(%d)/%d/\n",
84567298654Sdamico 			    aptr, temp[i]) :
846*1dd08564Sab196087 			    fprintf(fout, "%d,\n", temp[i]));
8477c478bd9Sstevel@tonic-gate #ifdef DEBUG
8487c478bd9Sstevel@tonic-gate 			if (debug)
8497c478bd9Sstevel@tonic-gate 				(void) printf("%d ", temp[i]);
8507c478bd9Sstevel@tonic-gate #endif
8517c478bd9Sstevel@tonic-gate 			aptr++;
8527c478bd9Sstevel@tonic-gate 		}
8537c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; i++) { /* copy fall back actions - all neg */
8547c478bd9Sstevel@tonic-gate 		ratfor ?
855*1dd08564Sab196087 		    (void) fprintf(fout, "data vstop(%d)/%d/\n", aptr, neg[i]) :
856*1dd08564Sab196087 		    (void) fprintf(fout, "%d,\n", neg[i]);
8577c478bd9Sstevel@tonic-gate 		aptr++;
8587c478bd9Sstevel@tonic-gate #ifdef DEBUG
8597c478bd9Sstevel@tonic-gate 		if (debug)
8607c478bd9Sstevel@tonic-gate 			(void) printf("%d ", neg[i]);
8617c478bd9Sstevel@tonic-gate #endif
8627c478bd9Sstevel@tonic-gate 		}
8637c478bd9Sstevel@tonic-gate #ifdef DEBUG
8647c478bd9Sstevel@tonic-gate 	if (debug)
8657c478bd9Sstevel@tonic-gate 		(void) putchar('\n');
8667c478bd9Sstevel@tonic-gate #endif
867*1dd08564Sab196087 	(void) (ratfor ? fprintf(fout, "data vstop (%d)/0/\n", aptr) :
868*1dd08564Sab196087 	    fprintf(fout, "0, \n"));
8697c478bd9Sstevel@tonic-gate 	aptr++;
8707c478bd9Sstevel@tonic-gate }
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate #ifdef DEBUG
8737c478bd9Sstevel@tonic-gate void
8747c478bd9Sstevel@tonic-gate pccl(void)
8757c478bd9Sstevel@tonic-gate {
8767c478bd9Sstevel@tonic-gate 	/* print character class sets */
8777c478bd9Sstevel@tonic-gate 	int i, j;
8787c478bd9Sstevel@tonic-gate 	(void) printf("char class intersection\n");
8797c478bd9Sstevel@tonic-gate 	for (i = 0; i < ccount; i++) {
8807c478bd9Sstevel@tonic-gate 		charc = 0;
8817c478bd9Sstevel@tonic-gate 		(void) printf("class %d:\n\t", i);
8827c478bd9Sstevel@tonic-gate 		for (j = 1; j < ncg; j++)
8837c478bd9Sstevel@tonic-gate 			if (cindex[j] == i) {
8847c478bd9Sstevel@tonic-gate 				allprint(j);
8857c478bd9Sstevel@tonic-gate 				if (charc > LINESIZE) {
8867c478bd9Sstevel@tonic-gate 					(void) printf("\n\t");
8877c478bd9Sstevel@tonic-gate 					charc = 0;
8887c478bd9Sstevel@tonic-gate 				}
8897c478bd9Sstevel@tonic-gate 			}
8907c478bd9Sstevel@tonic-gate 		(void) putchar('\n');
8917c478bd9Sstevel@tonic-gate 	}
8927c478bd9Sstevel@tonic-gate 	charc = 0;
8937c478bd9Sstevel@tonic-gate 	(void) printf("match:\n");
8947c478bd9Sstevel@tonic-gate 	for (i = 0; i < ncg; i++) {
8957c478bd9Sstevel@tonic-gate 		allprint(match[i]);
8967c478bd9Sstevel@tonic-gate 		if (charc > LINESIZE) {
8977c478bd9Sstevel@tonic-gate 			(void) putchar('\n');
8987c478bd9Sstevel@tonic-gate 			charc = 0;
8997c478bd9Sstevel@tonic-gate 		}
9007c478bd9Sstevel@tonic-gate 	}
9017c478bd9Sstevel@tonic-gate 	(void) putchar('\n');
9027c478bd9Sstevel@tonic-gate }
9037c478bd9Sstevel@tonic-gate #endif
9047c478bd9Sstevel@tonic-gate 
9057c478bd9Sstevel@tonic-gate void
9067c478bd9Sstevel@tonic-gate mkmatch(void)
9077c478bd9Sstevel@tonic-gate {
9087c478bd9Sstevel@tonic-gate 	int i;
9097c478bd9Sstevel@tonic-gate 	CHR tab[MAXNCG];
9107c478bd9Sstevel@tonic-gate 	for (i = 0; i < ccount; i++)
9117c478bd9Sstevel@tonic-gate 		tab[i] = 0;
9127c478bd9Sstevel@tonic-gate 	for (i = 1; i < ncg; i++)
9137c478bd9Sstevel@tonic-gate 		if (tab[cindex[i]] == 0)
9147c478bd9Sstevel@tonic-gate 			tab[cindex[i]] = i;
9157c478bd9Sstevel@tonic-gate 	/* tab[i] = principal char for new ccl i */
9167c478bd9Sstevel@tonic-gate 	for (i = 1; i < ncg; i++)
9177c478bd9Sstevel@tonic-gate 		match[i] = tab[cindex[i]];
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate void
9217c478bd9Sstevel@tonic-gate layout(void)
9227c478bd9Sstevel@tonic-gate {
9237c478bd9Sstevel@tonic-gate 	/* format and output final program's tables */
9247c478bd9Sstevel@tonic-gate 	int i, j, k;
9257c478bd9Sstevel@tonic-gate 	int  top, bot, startup, omin;
9267c478bd9Sstevel@tonic-gate 	startup = 0;
9277c478bd9Sstevel@tonic-gate 	for (i = 0; i < outsize; i++)
9287c478bd9Sstevel@tonic-gate 		verify[i] = advance[i] = 0;
9297c478bd9Sstevel@tonic-gate 	omin = 0;
9307c478bd9Sstevel@tonic-gate 	yytop = 0;
9317c478bd9Sstevel@tonic-gate 	for (i = 0; i <= stnum; i++) { /* for each state */
9327c478bd9Sstevel@tonic-gate 		j = gotof[i];
9337c478bd9Sstevel@tonic-gate 		if (j == -1) {
9347c478bd9Sstevel@tonic-gate 			stoff[i] = 0;
9357c478bd9Sstevel@tonic-gate 			continue;
9367c478bd9Sstevel@tonic-gate 		}
9377c478bd9Sstevel@tonic-gate 		bot = j;
9387c478bd9Sstevel@tonic-gate 		while (nchar[j])
9397c478bd9Sstevel@tonic-gate 			j++;
9407c478bd9Sstevel@tonic-gate 		top = j - 1;
9417c478bd9Sstevel@tonic-gate #if DEBUG
9427c478bd9Sstevel@tonic-gate 		if (debug) {
9437c478bd9Sstevel@tonic-gate 			(void) printf("State %d: (layout)\n", i);
9447c478bd9Sstevel@tonic-gate 			for (j = bot; j <= top; j++) {
9457c478bd9Sstevel@tonic-gate 				(void) printf("  %o", nchar[j]);
9467c478bd9Sstevel@tonic-gate 				if (j % 10 == 0)
9477c478bd9Sstevel@tonic-gate 					(void) putchar('\n');
9487c478bd9Sstevel@tonic-gate 			}
9497c478bd9Sstevel@tonic-gate 			(void) putchar('\n');
9507c478bd9Sstevel@tonic-gate 		}
9517c478bd9Sstevel@tonic-gate #endif
9527c478bd9Sstevel@tonic-gate 		while (verify[omin+ZCH])
9537c478bd9Sstevel@tonic-gate 			omin++;
9547c478bd9Sstevel@tonic-gate 		startup = omin;
9557c478bd9Sstevel@tonic-gate #if DEBUG
9567c478bd9Sstevel@tonic-gate 		if (debug)
9577c478bd9Sstevel@tonic-gate 			(void) printf(
9587c478bd9Sstevel@tonic-gate 			"bot,top %d, %d startup begins %d\n",
9597c478bd9Sstevel@tonic-gate 			    bot, top, startup);
9607c478bd9Sstevel@tonic-gate #endif
9617c478bd9Sstevel@tonic-gate 		if (chset) {
9627c478bd9Sstevel@tonic-gate 			do {
9637c478bd9Sstevel@tonic-gate 				startup += 1;
9647c478bd9Sstevel@tonic-gate 				if (startup > outsize - ZCH)
9657c478bd9Sstevel@tonic-gate 					error("output table overflow");
9667c478bd9Sstevel@tonic-gate 				for (j = bot; j <= top; j++) {
9677c478bd9Sstevel@tonic-gate 					k = startup+ctable[nchar[j]];
9687c478bd9Sstevel@tonic-gate 					if (verify[k])
9697c478bd9Sstevel@tonic-gate 						break;
9707c478bd9Sstevel@tonic-gate 				}
9717c478bd9Sstevel@tonic-gate 			} while (j <= top);
9727c478bd9Sstevel@tonic-gate #if DEBUG
9737c478bd9Sstevel@tonic-gate 			if (debug)
9747c478bd9Sstevel@tonic-gate 				(void) printf(" startup will be %d\n",
9757c478bd9Sstevel@tonic-gate 				    startup);
9767c478bd9Sstevel@tonic-gate #endif
9777c478bd9Sstevel@tonic-gate 			/* have found place */
9787c478bd9Sstevel@tonic-gate 			for (j = bot; j <= top; j++) {
9797c478bd9Sstevel@tonic-gate 				k = startup + ctable[nchar[j]];
9807c478bd9Sstevel@tonic-gate 				if (ctable[nchar[j]] <= 0)
9817c478bd9Sstevel@tonic-gate 					(void) printf(
9827c478bd9Sstevel@tonic-gate 					"j %d nchar %d ctable.nch %d\n",
983*1dd08564Sab196087 					    j, (int)nchar[j], ctable[nchar[k]]);
9847c478bd9Sstevel@tonic-gate 				verify[k] = i + 1;	/* state number + 1 */
9857c478bd9Sstevel@tonic-gate 				advance[k] = nexts[j+1]+1;
9867c478bd9Sstevel@tonic-gate 				if (yytop < k)
9877c478bd9Sstevel@tonic-gate 					yytop = k;
9887c478bd9Sstevel@tonic-gate 			}
9897c478bd9Sstevel@tonic-gate 		} else {
9907c478bd9Sstevel@tonic-gate 			do {
9917c478bd9Sstevel@tonic-gate 				startup += 1;
9927c478bd9Sstevel@tonic-gate 				if (startup > outsize - ZCH)
9937c478bd9Sstevel@tonic-gate 					error("output table overflow");
9947c478bd9Sstevel@tonic-gate 				for (j = bot; j <= top; j++) {
9957c478bd9Sstevel@tonic-gate 					k = startup + nchar[j];
9967c478bd9Sstevel@tonic-gate 					if (verify[k])
9977c478bd9Sstevel@tonic-gate 						break;
9987c478bd9Sstevel@tonic-gate 				}
9997c478bd9Sstevel@tonic-gate 			} while (j <= top);
10007c478bd9Sstevel@tonic-gate 			/* have found place */
10017c478bd9Sstevel@tonic-gate #if DEBUG
10027c478bd9Sstevel@tonic-gate 	if (debug)
10037c478bd9Sstevel@tonic-gate 		(void) printf(" startup going to be %d\n", startup);
10047c478bd9Sstevel@tonic-gate #endif
10057c478bd9Sstevel@tonic-gate 			for (j = bot; j <= top; j++) {
10067c478bd9Sstevel@tonic-gate 				k = startup + nchar[j];
10077c478bd9Sstevel@tonic-gate 				verify[k] = i+1; /* state number + 1 */
10087c478bd9Sstevel@tonic-gate 				advance[k] = nexts[j+1] + 1;
10097c478bd9Sstevel@tonic-gate 				if (yytop < k)
10107c478bd9Sstevel@tonic-gate 					yytop = k;
10117c478bd9Sstevel@tonic-gate 			}
10127c478bd9Sstevel@tonic-gate 		}
10137c478bd9Sstevel@tonic-gate 		stoff[i] = startup;
10147c478bd9Sstevel@tonic-gate 	}
10157c478bd9Sstevel@tonic-gate 
10167c478bd9Sstevel@tonic-gate 	/* stoff[i] = offset into verify, advance for trans for state i */
10177c478bd9Sstevel@tonic-gate 	/* put out yywork */
10187c478bd9Sstevel@tonic-gate 	if (ratfor) {
10197c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "define YYTOPVAL %d\n", yytop);
10207c478bd9Sstevel@tonic-gate 		rprint(verify, "verif", yytop+1);
10217c478bd9Sstevel@tonic-gate 		rprint(advance, "advan", yytop+1);
10227c478bd9Sstevel@tonic-gate 		shiftr(stoff, stnum);
10237c478bd9Sstevel@tonic-gate 		rprint(stoff, "stoff", stnum+1);
10247c478bd9Sstevel@tonic-gate 		shiftr(sfall, stnum);
10257c478bd9Sstevel@tonic-gate 		upone(sfall, stnum+1);
10267c478bd9Sstevel@tonic-gate 		rprint(sfall, "fall", stnum+1);
10277c478bd9Sstevel@tonic-gate 		bprint(extra, "extra", casecount+1);
10287c478bd9Sstevel@tonic-gate 		bprint((char *)match, "match", ncg);
10297c478bd9Sstevel@tonic-gate 		shiftr(atable, stnum);
10307c478bd9Sstevel@tonic-gate 		rprint(atable, "atable", stnum+1);
10317c478bd9Sstevel@tonic-gate 	}
10327c478bd9Sstevel@tonic-gate 	(void) fprintf(fout,
10337c478bd9Sstevel@tonic-gate 	"# define YYTYPE %s\n", stnum+1 >= NCH ? "int" : "unsigned char");
10347c478bd9Sstevel@tonic-gate 	(void) fprintf(fout,
10357c478bd9Sstevel@tonic-gate 	"struct yywork { YYTYPE verify, advance; } yycrank[] = {\n");
10367c478bd9Sstevel@tonic-gate 	for (i = 0; i <= yytop; i += 4) {
10377c478bd9Sstevel@tonic-gate 		for (j = 0; j < 4; j++) {
10387c478bd9Sstevel@tonic-gate 			k = i+j;
10397c478bd9Sstevel@tonic-gate 			if (verify[k])
10407c478bd9Sstevel@tonic-gate 				(void) fprintf(fout,
10417c478bd9Sstevel@tonic-gate 				"%d,%d,\t", verify[k], advance[k]);
10427c478bd9Sstevel@tonic-gate 			else
10437c478bd9Sstevel@tonic-gate 				(void) fprintf(fout, "0,0,\t");
10447c478bd9Sstevel@tonic-gate 		}
10457c478bd9Sstevel@tonic-gate 		(void) putc('\n', fout);
10467c478bd9Sstevel@tonic-gate 	}
10477c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "0,0};\n");
10487c478bd9Sstevel@tonic-gate 
10497c478bd9Sstevel@tonic-gate 	/* put out yysvec */
10507c478bd9Sstevel@tonic-gate 
10517c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "struct yysvf yysvec[] = {\n");
10527c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "0,\t0,\t0,\n");
10537c478bd9Sstevel@tonic-gate 	for (i = 0; i <= stnum; i++) {	/* for each state */
10547c478bd9Sstevel@tonic-gate 		if (cpackflg[i])
10557c478bd9Sstevel@tonic-gate 			stoff[i] = -stoff[i];
10567c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "yycrank+%d,\t", stoff[i]);
10577c478bd9Sstevel@tonic-gate 		if (sfall[i] != -1)
10587c478bd9Sstevel@tonic-gate 			(void) fprintf(fout,
10597c478bd9Sstevel@tonic-gate 			"yysvec+%d,\t", sfall[i]+1); /* state + 1 */
10607c478bd9Sstevel@tonic-gate 		else
10617c478bd9Sstevel@tonic-gate 			(void) fprintf(fout, "0,\t\t");
10627c478bd9Sstevel@tonic-gate 		if (atable[i] != -1)
10637c478bd9Sstevel@tonic-gate 			(void) fprintf(fout, "yyvstop+%d,", atable[i]);
10647c478bd9Sstevel@tonic-gate 		else
10657c478bd9Sstevel@tonic-gate 			(void) fprintf(fout, "0,\t");
10667c478bd9Sstevel@tonic-gate #ifdef DEBUG
10677c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "\t\t/* state %d */", i);
10687c478bd9Sstevel@tonic-gate #endif
10697c478bd9Sstevel@tonic-gate 		(void) putc('\n', fout);
10707c478bd9Sstevel@tonic-gate 	}
10717c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "0,\t0,\t0};\n");
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 	/* put out yymatch */
10747c478bd9Sstevel@tonic-gate 
10757c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "struct yywork *yytop = yycrank+%d;\n", yytop);
10767c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "struct yysvf *yybgin = yysvec+1;\n");
10777c478bd9Sstevel@tonic-gate 	if (optim) {
10787c478bd9Sstevel@tonic-gate 		if (handleeuc) {
10797c478bd9Sstevel@tonic-gate 			(void) fprintf(fout, "int yymatch[] = {\n");
10807c478bd9Sstevel@tonic-gate 		} else {
10817c478bd9Sstevel@tonic-gate 			(void) fprintf(fout, "char yymatch[] = {\n");
10827c478bd9Sstevel@tonic-gate 		}
10837c478bd9Sstevel@tonic-gate 		if (chset == 0) { /* no chset, put out in normal order */
10847c478bd9Sstevel@tonic-gate 			for (i = 0; i < ncg; i += 8) {
10857c478bd9Sstevel@tonic-gate 				for (j = 0; j < 8; j++) {
10867c478bd9Sstevel@tonic-gate 					int fbch;
10877c478bd9Sstevel@tonic-gate 					fbch = match[i+j];
1088*1dd08564Sab196087 					(void) fprintf(fout, "%3d, ", fbch);
10897c478bd9Sstevel@tonic-gate 				}
10907c478bd9Sstevel@tonic-gate 				(void) putc('\n', fout);
10917c478bd9Sstevel@tonic-gate 			}
10927c478bd9Sstevel@tonic-gate 		} else {
10937c478bd9Sstevel@tonic-gate 			int *fbarr;
1094*1dd08564Sab196087 			/*LINTED: E_BAD_PTR_CAST_ALIGN*/
10957c478bd9Sstevel@tonic-gate 			fbarr = (int *)myalloc(2*MAXNCG, sizeof (*fbarr));
10967c478bd9Sstevel@tonic-gate 			if (fbarr == 0)
10977c478bd9Sstevel@tonic-gate 				error("No space for char table reverse", 0);
10987c478bd9Sstevel@tonic-gate 			for (i = 0; i < MAXNCG; i++)
10997c478bd9Sstevel@tonic-gate 				fbarr[i] = 0;
11007c478bd9Sstevel@tonic-gate 			for (i = 0; i < ncg; i++)
11017c478bd9Sstevel@tonic-gate 				fbarr[ctable[i]] = ctable[match[i]];
11027c478bd9Sstevel@tonic-gate 			for (i = 0; i < ncg; i += 8) {
11037c478bd9Sstevel@tonic-gate 				for (j = 0; j < 8; j++)
1104*1dd08564Sab196087 					(void) fprintf(fout, "0%-3o,",
1105*1dd08564Sab196087 					    fbarr[i+j]);
1106*1dd08564Sab196087 				(void) putc('\n', fout);
11077c478bd9Sstevel@tonic-gate 			}
11087c478bd9Sstevel@tonic-gate 			free(fbarr);
11097c478bd9Sstevel@tonic-gate 		}
11107c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "0};\n");
11117c478bd9Sstevel@tonic-gate 	}
11127c478bd9Sstevel@tonic-gate 	/* put out yyextra */
11137c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "char yyextra[] = {\n");
11147c478bd9Sstevel@tonic-gate 	for (i = 0; i < casecount; i += 8) {
11157c478bd9Sstevel@tonic-gate 		for (j = 0; j < 8; j++)
11167c478bd9Sstevel@tonic-gate 			(void) fprintf(fout, "%d,", i+j < NACTIONS ?
11177c478bd9Sstevel@tonic-gate 			    extra[i+j] : 0);
11187c478bd9Sstevel@tonic-gate 		(void) putc('\n', fout);
11197c478bd9Sstevel@tonic-gate 	}
11207c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "0};\n");
11217c478bd9Sstevel@tonic-gate 	if (handleeuc) {
11227c478bd9Sstevel@tonic-gate 		/* Put out yycgidtbl */
1123*1dd08564Sab196087 		(void) fprintf(fout, "#define YYNCGIDTBL %d\n", ncgidtbl);
1124*1dd08564Sab196087 		(void) fprintf(fout, "\tunsigned long yycgidtbl[]={");
11257c478bd9Sstevel@tonic-gate 		/*
11267c478bd9Sstevel@tonic-gate 		 * Use "unsigned long" instead of "lchar" to minimize
11277c478bd9Sstevel@tonic-gate 		 * the name-space polution for the application program.
11287c478bd9Sstevel@tonic-gate 		 */
11297c478bd9Sstevel@tonic-gate 		for (i = 0; i < ncgidtbl; ++i) {
11307c478bd9Sstevel@tonic-gate 			if (i%8 == 0)
1131*1dd08564Sab196087 				(void) fprintf(fout, "\n\t\t");
1132*1dd08564Sab196087 			(void) fprintf(fout, "0x%08x, ",  (int)yycgidtbl[i]);
11337c478bd9Sstevel@tonic-gate 		}
1134*1dd08564Sab196087 		(void) fprintf(fout, "\n\t0};\n");
11357c478bd9Sstevel@tonic-gate 	}
11367c478bd9Sstevel@tonic-gate }
11377c478bd9Sstevel@tonic-gate 
11387c478bd9Sstevel@tonic-gate static void
11397c478bd9Sstevel@tonic-gate rprint(int *a, char *s, int n)
11407c478bd9Sstevel@tonic-gate {
11417c478bd9Sstevel@tonic-gate 	int i;
11427c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "block data\n");
11437c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "common /L%s/ %s\n", s, s);
11447c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "define S%s %d\n", s, n);
11457c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "integer %s (S%s)\n", s, s);
11467c478bd9Sstevel@tonic-gate 	for (i = 1; i <= n; i++) {
11477c478bd9Sstevel@tonic-gate 		if (i%8 == 1)
11487c478bd9Sstevel@tonic-gate 			(void) fprintf(fout, "data ");
11497c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "%s (%d)/%d/", s, i, a[i]);
11507c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, (i%8 && i < n) ? ", " : "\n");
11517c478bd9Sstevel@tonic-gate 	}
11527c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "end\n");
11537c478bd9Sstevel@tonic-gate }
11547c478bd9Sstevel@tonic-gate 
11557c478bd9Sstevel@tonic-gate static void
11567c478bd9Sstevel@tonic-gate shiftr(int *a, int n)
11577c478bd9Sstevel@tonic-gate {
11587c478bd9Sstevel@tonic-gate 	int i;
11597c478bd9Sstevel@tonic-gate 	for (i = n; i >= 0; i--)
11607c478bd9Sstevel@tonic-gate 		a[i+1] = a[i];
11617c478bd9Sstevel@tonic-gate }
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate static void
11647c478bd9Sstevel@tonic-gate upone(int *a, int n)
11657c478bd9Sstevel@tonic-gate {
11667c478bd9Sstevel@tonic-gate 	int i;
11677c478bd9Sstevel@tonic-gate 	for (i = 0; i <= n; i++)
11687c478bd9Sstevel@tonic-gate 		a[i]++;
11697c478bd9Sstevel@tonic-gate }
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate static void
11727c478bd9Sstevel@tonic-gate bprint(char *a, char *s, int n)
11737c478bd9Sstevel@tonic-gate {
11747c478bd9Sstevel@tonic-gate 	int i, j, k;
11757c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "block data\n");
11767c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "common /L%s/ %s\n", s, s);
11777c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "define S%s %d\n", s, n);
11787c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "integer %s (S%s)\n", s, s);
11797c478bd9Sstevel@tonic-gate 	for (i = 1; i < n; i += 8) {
11807c478bd9Sstevel@tonic-gate 		(void) fprintf(fout, "data %s (%d)/%d/", s, i, a[i]);
11817c478bd9Sstevel@tonic-gate 		for (j = 1; j < 8; j++) {
11827c478bd9Sstevel@tonic-gate 			k = i+j;
11837c478bd9Sstevel@tonic-gate 			if (k < n)
11847c478bd9Sstevel@tonic-gate 				(void) fprintf(fout,
11857c478bd9Sstevel@tonic-gate 				    ", %s (%d)/%d/", s, k, a[k]);
11867c478bd9Sstevel@tonic-gate 		}
11877c478bd9Sstevel@tonic-gate 		(void) putc('\n', fout);
11887c478bd9Sstevel@tonic-gate 	}
11897c478bd9Sstevel@tonic-gate 	(void) fprintf(fout, "end\n");
11907c478bd9Sstevel@tonic-gate }
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate #ifdef PP
11937c478bd9Sstevel@tonic-gate static void
11947c478bd9Sstevel@tonic-gate padd(int **array, int n)
11957c478bd9Sstevel@tonic-gate {
11967c478bd9Sstevel@tonic-gate 	int i, *j, k;
11977c478bd9Sstevel@tonic-gate 	array[n] = nxtpos;
11987c478bd9Sstevel@tonic-gate 	if (count == 0) {
11997c478bd9Sstevel@tonic-gate 		*nxtpos++ = 0;
12007c478bd9Sstevel@tonic-gate 		return;
12017c478bd9Sstevel@tonic-gate 	}
12027c478bd9Sstevel@tonic-gate 	for (i = tptr-1; i >= 0; i--) {
12037c478bd9Sstevel@tonic-gate 		j = array[i];
12047c478bd9Sstevel@tonic-gate 		if (j && *j++ == count) {
12057c478bd9Sstevel@tonic-gate 			for (k = 0; k < count; k++)
12067c478bd9Sstevel@tonic-gate 				if (!tmpstat[*j++])
12077c478bd9Sstevel@tonic-gate 					break;
12087c478bd9Sstevel@tonic-gate 			if (k >= count) {
12097c478bd9Sstevel@tonic-gate 				array[n] = array[i];
12107c478bd9Sstevel@tonic-gate 				return;
12117c478bd9Sstevel@tonic-gate 			}
12127c478bd9Sstevel@tonic-gate 		}
12137c478bd9Sstevel@tonic-gate 	}
12147c478bd9Sstevel@tonic-gate 	add(array, n);
12157c478bd9Sstevel@tonic-gate }
12167c478bd9Sstevel@tonic-gate #endif
1217