xref: /onnv-gate/usr/src/cmd/sgs/lex/common/sub2.c (revision 6951:59445bec7ef4)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
54538Sdamico  * Common Development and Distribution License (the "License").
64538Sdamico  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*6951Sab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
270Sstevel@tonic-gate /*	All Rights Reserved	*/
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
300Sstevel@tonic-gate 
314538Sdamico #include "ldefs.h"
320Sstevel@tonic-gate 
330Sstevel@tonic-gate static void add(int **array, int n);
340Sstevel@tonic-gate static void follow(int v);
350Sstevel@tonic-gate static void first(int v);
360Sstevel@tonic-gate static void nextstate(int s, int c);
370Sstevel@tonic-gate static void packtrans(int st, CHR *tch, int *tst, int cnt, int tryit);
380Sstevel@tonic-gate static void acompute(int s);
390Sstevel@tonic-gate static void rprint(int *a, char *s, int n);
400Sstevel@tonic-gate static void shiftr(int *a, int n);
410Sstevel@tonic-gate static void upone(int *a, int n);
420Sstevel@tonic-gate static void bprint(char *a, char *s, int n);
430Sstevel@tonic-gate static int notin(int n);
440Sstevel@tonic-gate static int member(int d, CHR *t);
450Sstevel@tonic-gate 
460Sstevel@tonic-gate #ifdef PP
470Sstevel@tonic-gate static void padd(int **array, int n);
480Sstevel@tonic-gate #endif
490Sstevel@tonic-gate 
500Sstevel@tonic-gate void
cfoll(int v)510Sstevel@tonic-gate cfoll(int v)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate 	int i, j, k;
540Sstevel@tonic-gate 	CHR *p;
550Sstevel@tonic-gate 	i = name[v];
560Sstevel@tonic-gate 	if (!ISOPERATOR(i))
570Sstevel@tonic-gate 		i = 1;
580Sstevel@tonic-gate 	switch (i) {
590Sstevel@tonic-gate 		case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:
600Sstevel@tonic-gate 			for (j = 0; j < tptr; j++)
610Sstevel@tonic-gate 				tmpstat[j] = FALSE;
620Sstevel@tonic-gate 			count = 0;
630Sstevel@tonic-gate 			follow(v);
640Sstevel@tonic-gate #ifdef PP
650Sstevel@tonic-gate 			padd(foll, v); /* packing version */
660Sstevel@tonic-gate #else
670Sstevel@tonic-gate 			add(foll, v); /* no packing version */
680Sstevel@tonic-gate #endif
690Sstevel@tonic-gate 			if (i == RSTR)
700Sstevel@tonic-gate 				cfoll(left[v]);
710Sstevel@tonic-gate 			else if (i == RCCL || i == RNCCL) {
720Sstevel@tonic-gate 				for (j = 1; j < ncg; j++)
730Sstevel@tonic-gate 					symbol[j] = (i == RNCCL);
740Sstevel@tonic-gate 				p = (CHR *) left[v];
750Sstevel@tonic-gate 				while (*p)
760Sstevel@tonic-gate 					symbol[*p++] = (i == RCCL);
770Sstevel@tonic-gate 				p = pcptr;
780Sstevel@tonic-gate 				for (j = 1; j < ncg; j++)
790Sstevel@tonic-gate 					if (symbol[j]) {
800Sstevel@tonic-gate 						for (k = 0; p + k < pcptr; k++)
814538Sdamico 							if (cindex[j] ==
824538Sdamico 							    *(p + k))
834538Sdamico 								break;
840Sstevel@tonic-gate 						if (p + k >= pcptr)
850Sstevel@tonic-gate 							*pcptr++ = cindex[j];
860Sstevel@tonic-gate 					}
870Sstevel@tonic-gate 				*pcptr++ = 0;
880Sstevel@tonic-gate 				if (pcptr > pchar + pchlen)
890Sstevel@tonic-gate 					error(
900Sstevel@tonic-gate 					"Too many packed character classes");
910Sstevel@tonic-gate 				left[v] = (int)p;
920Sstevel@tonic-gate 				name[v] = RCCL;	/* RNCCL eliminated */
930Sstevel@tonic-gate #ifdef DEBUG
940Sstevel@tonic-gate 				if (debug && *p) {
950Sstevel@tonic-gate 					(void) printf("ccl %d: %d", v, *p++);
960Sstevel@tonic-gate 					while (*p)
970Sstevel@tonic-gate 						(void) printf(", %d", *p++);
980Sstevel@tonic-gate 					(void) putchar('\n');
990Sstevel@tonic-gate 				}
1000Sstevel@tonic-gate #endif
1010Sstevel@tonic-gate 			}
1020Sstevel@tonic-gate 			break;
1030Sstevel@tonic-gate 		case CARAT:
1040Sstevel@tonic-gate 			cfoll(left[v]);
1050Sstevel@tonic-gate 			break;
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 		/* XCU4: add RXSCON */
1080Sstevel@tonic-gate 		case RXSCON:
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 		case STAR: case PLUS: case QUEST: case RSCON:
1110Sstevel@tonic-gate 			cfoll(left[v]);
1120Sstevel@tonic-gate 			break;
1130Sstevel@tonic-gate 		case BAR: case RCAT: case DIV: case RNEWE:
1140Sstevel@tonic-gate 			cfoll(left[v]);
1150Sstevel@tonic-gate 			cfoll(right[v]);
1160Sstevel@tonic-gate 			break;
1170Sstevel@tonic-gate #ifdef DEBUG
1180Sstevel@tonic-gate 		case FINAL:
1190Sstevel@tonic-gate 		case S1FINAL:
1200Sstevel@tonic-gate 		case S2FINAL:
1210Sstevel@tonic-gate 			break;
1220Sstevel@tonic-gate 		default:
1230Sstevel@tonic-gate 			warning("bad switch cfoll %d", v);
1240Sstevel@tonic-gate #endif
1250Sstevel@tonic-gate 	}
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate #ifdef DEBUG
1290Sstevel@tonic-gate void
pfoll(void)1300Sstevel@tonic-gate pfoll(void)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate 	int i, k, *p;
1330Sstevel@tonic-gate 	int j;
1340Sstevel@tonic-gate 	/* print sets of chars which may follow positions */
1350Sstevel@tonic-gate 	(void) printf("pos\tchars\n");
1360Sstevel@tonic-gate 	for (i = 0; i < tptr; i++)
1370Sstevel@tonic-gate 		if (p = foll[i]) {
1380Sstevel@tonic-gate 			j = *p++;
1390Sstevel@tonic-gate 			if (j >= 1) {
1400Sstevel@tonic-gate 				(void) printf("%d:\t%d", i, *p++);
1410Sstevel@tonic-gate 				for (k = 2; k <= j; k++)
1420Sstevel@tonic-gate 					(void) printf(", %d", *p++);
1430Sstevel@tonic-gate 				(void) putchar('\n');
1440Sstevel@tonic-gate 			}
1450Sstevel@tonic-gate 		}
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate #endif
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate static void
add(int ** array,int n)1500Sstevel@tonic-gate add(int **array, int n)
1510Sstevel@tonic-gate {
1520Sstevel@tonic-gate 	int i, *temp;
1530Sstevel@tonic-gate 	CHR *ctemp;
1540Sstevel@tonic-gate 	temp = nxtpos;
1550Sstevel@tonic-gate 	ctemp = tmpstat;
1560Sstevel@tonic-gate 	array[n] = nxtpos;	/* note no packing is done in positions */
1570Sstevel@tonic-gate 	*temp++ = count;
1580Sstevel@tonic-gate 	for (i = 0; i < tptr; i++)
1590Sstevel@tonic-gate 		if (ctemp[i] == TRUE)
1600Sstevel@tonic-gate 			*temp++ = i;
1610Sstevel@tonic-gate 	nxtpos = temp;
1620Sstevel@tonic-gate 	if (nxtpos >= positions+maxpos)
1630Sstevel@tonic-gate 		error(
1640Sstevel@tonic-gate 		"Too many positions %s",
1654538Sdamico 		    (maxpos == MAXPOS ? "\nTry using %p num" : ""));
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate static void
follow(int v)1690Sstevel@tonic-gate follow(int v)
1700Sstevel@tonic-gate {
1710Sstevel@tonic-gate 	int p;
1720Sstevel@tonic-gate 	if (v >= tptr-1)
1730Sstevel@tonic-gate 		return;
1740Sstevel@tonic-gate 	p = parent[v];
1750Sstevel@tonic-gate 	if (p == 0)
1760Sstevel@tonic-gate 		return;
1770Sstevel@tonic-gate 	switch (name[p]) {
1780Sstevel@tonic-gate 	/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
1790Sstevel@tonic-gate 	case RSTR:
1800Sstevel@tonic-gate 		if (tmpstat[p] == FALSE) {
1810Sstevel@tonic-gate 			count++;
1820Sstevel@tonic-gate 			tmpstat[p] = TRUE;
1830Sstevel@tonic-gate 		}
1840Sstevel@tonic-gate 		break;
1850Sstevel@tonic-gate 	case STAR: case PLUS:
1860Sstevel@tonic-gate 		first(v);
1870Sstevel@tonic-gate 		follow(p);
1880Sstevel@tonic-gate 		break;
1890Sstevel@tonic-gate 	case BAR: case QUEST: case RNEWE:
1900Sstevel@tonic-gate 		follow(p);
1910Sstevel@tonic-gate 		break;
1920Sstevel@tonic-gate 	case RCAT: case DIV:
1930Sstevel@tonic-gate 		if (v == left[p]) {
1940Sstevel@tonic-gate 			if (nullstr[right[p]])
1950Sstevel@tonic-gate 				follow(p);
1960Sstevel@tonic-gate 			first(right[p]);
1970Sstevel@tonic-gate 		}
1980Sstevel@tonic-gate 		else
1990Sstevel@tonic-gate 			follow(p);
2000Sstevel@tonic-gate 		break;
2010Sstevel@tonic-gate 	/* XCU4: add RXSCON */
2020Sstevel@tonic-gate 	case RXSCON:
2030Sstevel@tonic-gate 	case RSCON: case CARAT:
2040Sstevel@tonic-gate 		follow(p);
2050Sstevel@tonic-gate 		break;
2060Sstevel@tonic-gate #ifdef DEBUG
2070Sstevel@tonic-gate 	default:
2080Sstevel@tonic-gate 		warning("bad switch follow %d", p);
2090Sstevel@tonic-gate #endif
2100Sstevel@tonic-gate 	}
2110Sstevel@tonic-gate }
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate /*
2140Sstevel@tonic-gate  * Check if I have a RXSCON in my upper node
2150Sstevel@tonic-gate  */
2160Sstevel@tonic-gate static int
check_me(int v)2170Sstevel@tonic-gate check_me(int v)
2180Sstevel@tonic-gate {
2190Sstevel@tonic-gate 	int tmp = parent[v];
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate 	while (name[tmp] != RNEWE) {
2220Sstevel@tonic-gate 		if (name[tmp] == RXSCON)
2230Sstevel@tonic-gate 			return (1);
2240Sstevel@tonic-gate 		tmp = parent[tmp];
2250Sstevel@tonic-gate 	}
2260Sstevel@tonic-gate 	return (0);
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate /* calculate set of positions with v as root which can be active initially */
2300Sstevel@tonic-gate static void
first(int v)2310Sstevel@tonic-gate first(int v)
2320Sstevel@tonic-gate {
2330Sstevel@tonic-gate 	int i;
2340Sstevel@tonic-gate 	CHR *p;
2350Sstevel@tonic-gate 	i = name[v];
2360Sstevel@tonic-gate 	if (!ISOPERATOR(i))
2370Sstevel@tonic-gate 		i = 1;
2380Sstevel@tonic-gate 	switch (i) {
2390Sstevel@tonic-gate 	case 1: case RCCL: case RNCCL:
2400Sstevel@tonic-gate 	case RNULLS: case FINAL:
2410Sstevel@tonic-gate 	case S1FINAL: case S2FINAL:
2420Sstevel@tonic-gate 	/*
2430Sstevel@tonic-gate 	 * XCU4: if we are working on an exclusive start state and
2440Sstevel@tonic-gate 	 * the parent of this position is not RXSCON or RSTR this
2450Sstevel@tonic-gate 	 * is not an active position.
2460Sstevel@tonic-gate 	 *
2470Sstevel@tonic-gate 	 * (There is a possibility that RSXCON appreas as the
2480Sstevel@tonic-gate 	 *  (parent)* node. Check it by check_me().)
2490Sstevel@tonic-gate 	 */
2500Sstevel@tonic-gate 		if ((exclusive[stnum/2]) &&
2510Sstevel@tonic-gate 		    ISOPERATOR(name[parent[v]]) &&
2520Sstevel@tonic-gate 		    (name[parent[v]] != RXSCON) &&
2530Sstevel@tonic-gate 		    (name[parent[v]] != RSTR) &&
2540Sstevel@tonic-gate 		    (check_me(v) == 0)) {
2550Sstevel@tonic-gate 				break;
2560Sstevel@tonic-gate 		}
2570Sstevel@tonic-gate 		if (tmpstat[v] == FALSE) {
2580Sstevel@tonic-gate 			count++;
2590Sstevel@tonic-gate 			tmpstat[v] = TRUE;
2600Sstevel@tonic-gate 		}
2610Sstevel@tonic-gate 		break;
2620Sstevel@tonic-gate 	case BAR: case RNEWE:
2630Sstevel@tonic-gate 		first(left[v]);
2640Sstevel@tonic-gate 		first(right[v]);
2650Sstevel@tonic-gate 		break;
2660Sstevel@tonic-gate 	case CARAT:
2670Sstevel@tonic-gate 		if (stnum % 2 == 1)
2680Sstevel@tonic-gate 			first(left[v]);
2690Sstevel@tonic-gate 		break;
2700Sstevel@tonic-gate 	/* XCU4: add RXSCON */
2710Sstevel@tonic-gate 	case RXSCON:
2720Sstevel@tonic-gate 	case RSCON:
2730Sstevel@tonic-gate 		i = stnum/2 +1;
2740Sstevel@tonic-gate 		p = (CHR *) right[v];
2750Sstevel@tonic-gate 		while (*p)
2760Sstevel@tonic-gate 			if (*p++ == i) {
2770Sstevel@tonic-gate 				first(left[v]);
2780Sstevel@tonic-gate 				break;
2790Sstevel@tonic-gate 			}
2800Sstevel@tonic-gate 		break;
2810Sstevel@tonic-gate 	case STAR: case QUEST:
2820Sstevel@tonic-gate 	case PLUS:  case RSTR:
2830Sstevel@tonic-gate 	/*
2840Sstevel@tonic-gate 	 * XCU4: if we are working on an exclusive start state and
2850Sstevel@tonic-gate 	 * the parent of this position is not RXSCON or RSTR this
2860Sstevel@tonic-gate 	 * is not an active position.
2870Sstevel@tonic-gate 	 *
2880Sstevel@tonic-gate 	 * (There is a possibility that RSXCON appreas as the
2890Sstevel@tonic-gate 	 *  (parent)* node. Check it by check_me().)
2900Sstevel@tonic-gate 	 */
2910Sstevel@tonic-gate 		if ((exclusive[stnum/2]) &&
2920Sstevel@tonic-gate 		    ISOPERATOR(name[parent[v]]) &&
2930Sstevel@tonic-gate 		    (name[parent[v]] != RXSCON) &&
2940Sstevel@tonic-gate 		    (name[parent[v]] != RSTR) &&
2950Sstevel@tonic-gate 		    (check_me(v) == 0)) {
2960Sstevel@tonic-gate 				break;
2970Sstevel@tonic-gate 		}
2980Sstevel@tonic-gate 		first(left[v]);
2990Sstevel@tonic-gate 		break;
3000Sstevel@tonic-gate 	case RCAT: case DIV:
3010Sstevel@tonic-gate 		first(left[v]);
3020Sstevel@tonic-gate 		if (nullstr[left[v]])
3030Sstevel@tonic-gate 			first(right[v]);
3040Sstevel@tonic-gate 		break;
3050Sstevel@tonic-gate #ifdef DEBUG
3060Sstevel@tonic-gate 	default:
3070Sstevel@tonic-gate 		warning("bad switch first %d", v);
3080Sstevel@tonic-gate #endif
3090Sstevel@tonic-gate 	}
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate void
cgoto(void)3130Sstevel@tonic-gate cgoto(void)
3140Sstevel@tonic-gate {
3150Sstevel@tonic-gate 	int i, j;
3160Sstevel@tonic-gate 	static int s;
3170Sstevel@tonic-gate 	int npos, curpos, n;
3180Sstevel@tonic-gate 	int tryit;
3190Sstevel@tonic-gate 	CHR tch[MAXNCG];
3200Sstevel@tonic-gate 	int tst[MAXNCG];
3210Sstevel@tonic-gate 	CHR *q;
3220Sstevel@tonic-gate 	/* generate initial state, for each start condition */
3230Sstevel@tonic-gate 	if (ratfor) {
3240Sstevel@tonic-gate 		(void) fprintf(fout, "blockdata\n");
3250Sstevel@tonic-gate 		(void) fprintf(fout, "common /Lvstop/ vstop\n");
3260Sstevel@tonic-gate 		(void) fprintf(fout, "define Svstop %d\n", nstates+1);
3270Sstevel@tonic-gate 		(void) fprintf(fout, "integer vstop(Svstop)\n");
3280Sstevel@tonic-gate 	} else
3290Sstevel@tonic-gate 		(void) fprintf(fout, "int yyvstop[] = {\n0,\n");
3300Sstevel@tonic-gate 	while (stnum < 2 || stnum/2 < sptr) {
3310Sstevel@tonic-gate 		for (i = 0; i < tptr; i++)
3320Sstevel@tonic-gate 			tmpstat[i] = 0;
3330Sstevel@tonic-gate 		count = 0;
3340Sstevel@tonic-gate 		if (tptr > 0)
3350Sstevel@tonic-gate 			first(tptr-1);
3360Sstevel@tonic-gate 		add(state, stnum);
3370Sstevel@tonic-gate #ifdef DEBUG
3380Sstevel@tonic-gate 		if (debug) {
3390Sstevel@tonic-gate 			if (stnum > 1)
3400Sstevel@tonic-gate 				(void) printf("%ws:\n", sname[stnum/2]);
3410Sstevel@tonic-gate 			pstate(stnum);
3420Sstevel@tonic-gate 		}
3430Sstevel@tonic-gate #endif
3440Sstevel@tonic-gate 		stnum++;
3450Sstevel@tonic-gate 	}
3460Sstevel@tonic-gate 	stnum--;
3470Sstevel@tonic-gate 	/* even stnum = might not be at line begin */
3480Sstevel@tonic-gate 	/* odd stnum  = must be at line begin */
3490Sstevel@tonic-gate 	/* even states can occur anywhere, odd states only at line begin */
3500Sstevel@tonic-gate 	for (s = 0; s <= stnum; s++) {
3510Sstevel@tonic-gate 		tryit = FALSE;
3520Sstevel@tonic-gate 		cpackflg[s] = FALSE;
3530Sstevel@tonic-gate 		sfall[s] = -1;
3540Sstevel@tonic-gate 		acompute(s);
3550Sstevel@tonic-gate 		for (i = 0; i < ncg; i++)
3560Sstevel@tonic-gate 			symbol[i] = 0;
3570Sstevel@tonic-gate 		npos = *state[s];
3580Sstevel@tonic-gate 		for (i = 1; i <= npos; i++) {
3590Sstevel@tonic-gate 			curpos = *(state[s]+i);
3600Sstevel@tonic-gate 			if (!ISOPERATOR(name[curpos]))
3610Sstevel@tonic-gate 				symbol[name[curpos]] = TRUE;
3620Sstevel@tonic-gate 			else {
3630Sstevel@tonic-gate 				switch (name[curpos]) {
3640Sstevel@tonic-gate 				case RCCL:
3650Sstevel@tonic-gate 					tryit = TRUE;
3660Sstevel@tonic-gate 					q = (CHR *)left[curpos];
3670Sstevel@tonic-gate 					while (*q) {
3680Sstevel@tonic-gate 						for (j = 1; j < ncg; j++)
3694538Sdamico 							if (cindex[j] == *q)
3704538Sdamico 								symbol[j] =
3714538Sdamico 								    TRUE;
3720Sstevel@tonic-gate 						q++;
3730Sstevel@tonic-gate 					}
3740Sstevel@tonic-gate 					break;
3750Sstevel@tonic-gate 				case RSTR:
3760Sstevel@tonic-gate 					symbol[right[curpos]] = TRUE;
3770Sstevel@tonic-gate 					break;
3780Sstevel@tonic-gate #ifdef DEBUG
3790Sstevel@tonic-gate 				case RNULLS:
3800Sstevel@tonic-gate 				case FINAL:
3810Sstevel@tonic-gate 				case S1FINAL:
3820Sstevel@tonic-gate 				case S2FINAL:
3830Sstevel@tonic-gate 					break;
3840Sstevel@tonic-gate 				default:
3850Sstevel@tonic-gate 					warning(
3860Sstevel@tonic-gate 					"bad switch cgoto %d state %d",
3874538Sdamico 					    curpos, s);
3880Sstevel@tonic-gate 					break;
3890Sstevel@tonic-gate #endif
3900Sstevel@tonic-gate 				}
3910Sstevel@tonic-gate 			}
3920Sstevel@tonic-gate 		}
3930Sstevel@tonic-gate #ifdef DEBUG
3940Sstevel@tonic-gate 		if (debug) {
3950Sstevel@tonic-gate 			printf("State %d transitions on char-group {", s);
3960Sstevel@tonic-gate 			charc = 0;
3970Sstevel@tonic-gate 			for (i = 1; i < ncg; i++) {
3980Sstevel@tonic-gate 				if (symbol[i]) {
3990Sstevel@tonic-gate 					printf("%d,", i);
4000Sstevel@tonic-gate 				}
4010Sstevel@tonic-gate 				if (i == ncg-1)
4020Sstevel@tonic-gate 					printf("}\n");
4030Sstevel@tonic-gate 				if (charc > LINESIZE/4) {
4040Sstevel@tonic-gate 					charc = 0;
4050Sstevel@tonic-gate 					printf("\n\t");
4060Sstevel@tonic-gate 				}
4070Sstevel@tonic-gate 			}
4080Sstevel@tonic-gate 		}
4090Sstevel@tonic-gate #endif
4100Sstevel@tonic-gate 		/* for each char, calculate next state */
4110Sstevel@tonic-gate 		n = 0;
4120Sstevel@tonic-gate 		for (i = 1; i < ncg; i++) {
4130Sstevel@tonic-gate 			if (symbol[i]) {
4140Sstevel@tonic-gate 				/* executed for each state, transition pair */
4150Sstevel@tonic-gate 				nextstate(s, i);
4160Sstevel@tonic-gate 				xstate = notin(stnum);
4170Sstevel@tonic-gate 				if (xstate == -2)
4180Sstevel@tonic-gate 					warning("bad state  %d %o", s, i);
4190Sstevel@tonic-gate 				else if (xstate == -1) {
4200Sstevel@tonic-gate 					if (stnum+1 >= nstates) {
4210Sstevel@tonic-gate 						stnum++;
4220Sstevel@tonic-gate 						error("Too many states %s",
4234538Sdamico 						    (nstates == NSTATES ?
4244538Sdamico 						    "\nTry using %n num":""));
4250Sstevel@tonic-gate 					}
4260Sstevel@tonic-gate 					add(state, ++stnum);
4270Sstevel@tonic-gate #ifdef DEBUG
4280Sstevel@tonic-gate 					if (debug)
4290Sstevel@tonic-gate 						pstate(stnum);
4300Sstevel@tonic-gate #endif
4310Sstevel@tonic-gate 					tch[n] = i;
4320Sstevel@tonic-gate 					tst[n++] = stnum;
4330Sstevel@tonic-gate 				} else { /* xstate >= 0 ==> state exists */
4340Sstevel@tonic-gate 					tch[n] = i;
4350Sstevel@tonic-gate 					tst[n++] = xstate;
4360Sstevel@tonic-gate 				}
4370Sstevel@tonic-gate 			}
4380Sstevel@tonic-gate 		}
4390Sstevel@tonic-gate 		tch[n] = 0;
4400Sstevel@tonic-gate 		tst[n] = -1;
4410Sstevel@tonic-gate 		/* pack transitions into permanent array */
4420Sstevel@tonic-gate 		if (n > 0)
4430Sstevel@tonic-gate 			packtrans(s, tch, tst, n, tryit);
4440Sstevel@tonic-gate 		else
4450Sstevel@tonic-gate 			gotof[s] = -1;
4460Sstevel@tonic-gate 	}
447*6951Sab196087 	(void) (ratfor ? fprintf(fout, "end\n") : fprintf(fout, "0};\n"));
4480Sstevel@tonic-gate }
4490Sstevel@tonic-gate 
4500Sstevel@tonic-gate /*
4510Sstevel@tonic-gate  * Beware -- 70% of total CPU time is spent in this subroutine -
4520Sstevel@tonic-gate  * if you don't believe me - try it yourself !
4530Sstevel@tonic-gate  */
4540Sstevel@tonic-gate static void
nextstate(int s,int c)4550Sstevel@tonic-gate nextstate(int s, int c)
4560Sstevel@tonic-gate {
4570Sstevel@tonic-gate 	int j, *newpos;
4580Sstevel@tonic-gate 	CHR *temp, *tz;
4590Sstevel@tonic-gate 	int *pos, i, *f, num, curpos, number;
4600Sstevel@tonic-gate 	/* state to goto from state s on char c */
4610Sstevel@tonic-gate 	num = *state[s];
4620Sstevel@tonic-gate 	temp = tmpstat;
4630Sstevel@tonic-gate 	pos = state[s] + 1;
4640Sstevel@tonic-gate 	for (i = 0; i < num; i++) {
4650Sstevel@tonic-gate 		curpos = *pos++;
4660Sstevel@tonic-gate 		j = name[curpos];
4670Sstevel@tonic-gate 		if ((!ISOPERATOR(j)) && j == c ||
4684538Sdamico 		    j == RSTR && c == right[curpos] ||
4694538Sdamico 		    j == RCCL && member(c, (CHR *) left[curpos])) {
4700Sstevel@tonic-gate 			f = foll[curpos];
4710Sstevel@tonic-gate 			number = *f;
4720Sstevel@tonic-gate 			newpos = f+1;
4730Sstevel@tonic-gate 			for (j = 0; j < number; j++)
4740Sstevel@tonic-gate 				temp[*newpos++] = 2;
4750Sstevel@tonic-gate 		}
4760Sstevel@tonic-gate 	}
4770Sstevel@tonic-gate 	j = 0;
4780Sstevel@tonic-gate 	tz = temp + tptr;
4790Sstevel@tonic-gate 	while (temp < tz) {
4800Sstevel@tonic-gate 		if (*temp == 2) {
4810Sstevel@tonic-gate 			j++;
4820Sstevel@tonic-gate 			*temp++ = 1;
4830Sstevel@tonic-gate 		}
4840Sstevel@tonic-gate 		else
4850Sstevel@tonic-gate 			*temp++ = 0;
4860Sstevel@tonic-gate 	}
4870Sstevel@tonic-gate 	count = j;
4880Sstevel@tonic-gate }
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate static int
notin(int n)4910Sstevel@tonic-gate notin(int n)
4920Sstevel@tonic-gate {	/* see if tmpstat occurs previously */
4930Sstevel@tonic-gate 	int *j, k;
4940Sstevel@tonic-gate 	CHR *temp;
4950Sstevel@tonic-gate 	int i;
4960Sstevel@tonic-gate 	if (count == 0)
4970Sstevel@tonic-gate 		return (-2);
4980Sstevel@tonic-gate 	temp = tmpstat;
4990Sstevel@tonic-gate 	for (i = n; i >= 0; i--) { /* for each state */
5000Sstevel@tonic-gate 		j = state[i];
5010Sstevel@tonic-gate 		if (count == *j++) {
5020Sstevel@tonic-gate 			for (k = 0; k < count; k++)
5030Sstevel@tonic-gate 				if (!temp[*j++])
5040Sstevel@tonic-gate 					break;
5050Sstevel@tonic-gate 			if (k >= count)
5060Sstevel@tonic-gate 				return (i);
5070Sstevel@tonic-gate 		}
5080Sstevel@tonic-gate 	}
5090Sstevel@tonic-gate 	return (-1);
5100Sstevel@tonic-gate }
5110Sstevel@tonic-gate 
5120Sstevel@tonic-gate static void
packtrans(int st,CHR * tch,int * tst,int cnt,int tryit)5130Sstevel@tonic-gate packtrans(int st, CHR *tch, int *tst, int cnt, int tryit)
5140Sstevel@tonic-gate {
5150Sstevel@tonic-gate 	/*
5160Sstevel@tonic-gate 	 * pack transitions into nchar, nexts
5170Sstevel@tonic-gate 	 * nchar is terminated by '\0', nexts uses cnt, followed by elements
5180Sstevel@tonic-gate 	 * gotof[st] = index into nchr, nexts for state st
5190Sstevel@tonic-gate 	 * sfall[st] =  t implies t is fall back state for st
5200Sstevel@tonic-gate 	 * == -1 implies no fall back
5210Sstevel@tonic-gate 	 */
5220Sstevel@tonic-gate 
5230Sstevel@tonic-gate 	int cmin, cval, tcnt, diff, p, *ast;
5240Sstevel@tonic-gate 	int i, j, k;
5250Sstevel@tonic-gate 	CHR *ach;
5260Sstevel@tonic-gate 	int go[MAXNCG], temp[MAXNCG], index, c;
5270Sstevel@tonic-gate 	int swork[MAXNCG];
5280Sstevel@tonic-gate 	CHR cwork[MAXNCG];
5290Sstevel@tonic-gate 	int upper;
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate 	rcount += (long)cnt;
5320Sstevel@tonic-gate 	cmin = -1;
5330Sstevel@tonic-gate 	cval = ncg;
5340Sstevel@tonic-gate 	ast = tst;
5350Sstevel@tonic-gate 	ach = tch;
5360Sstevel@tonic-gate 	/* try to pack transitions using ccl's */
5370Sstevel@tonic-gate 	if (!optim)
5380Sstevel@tonic-gate 		goto nopack; /* skip all compaction */
5390Sstevel@tonic-gate 	if (tryit) { /* ccl's used */
5400Sstevel@tonic-gate 		for (i = 1; i < ncg; i++) {
5410Sstevel@tonic-gate 			go[i] = temp[i] = -1;
5420Sstevel@tonic-gate 			symbol[i] = 1;
5430Sstevel@tonic-gate 		}
5440Sstevel@tonic-gate 		for (i = 0; i < cnt; i++) {
5450Sstevel@tonic-gate 			index = (unsigned char) tch[i];
5460Sstevel@tonic-gate 			if ((index >= 0) && (index < NCH)) {
5470Sstevel@tonic-gate 				go[index] = tst[i];
5480Sstevel@tonic-gate 				symbol[index] = 0;
5490Sstevel@tonic-gate 			} else {
550*6951Sab196087 				(void) fprintf(stderr,
5510Sstevel@tonic-gate "lex`sub2`packtran: tch[%d] out of bounds (%d)\n",
552*6951Sab196087 				    i, (int)tch[i]);
5530Sstevel@tonic-gate 			}
5540Sstevel@tonic-gate 		}
5550Sstevel@tonic-gate 		for (i = 0; i < cnt; i++) {
5560Sstevel@tonic-gate 			c = match[tch[i]];
5570Sstevel@tonic-gate 			if (go[c] != tst[i] || c == tch[i])
5580Sstevel@tonic-gate 				temp[tch[i]] = tst[i];
5590Sstevel@tonic-gate 		}
5600Sstevel@tonic-gate 		/* fill in error entries */
5610Sstevel@tonic-gate 		for (i = 1; i < ncg; i++)
5620Sstevel@tonic-gate 			if (symbol[i])
5630Sstevel@tonic-gate 				temp[i] = -2;	/* error trans */
5640Sstevel@tonic-gate 		/* count them */
5650Sstevel@tonic-gate 		k = 0;
5660Sstevel@tonic-gate 		for (i = 1; i < ncg; i++)
5670Sstevel@tonic-gate 			if (temp[i] != -1)
5680Sstevel@tonic-gate 				k++;
5690Sstevel@tonic-gate 		if (k < cnt) { /* compress by char */
5700Sstevel@tonic-gate #ifdef DEBUG
5710Sstevel@tonic-gate 			if (debug)
5720Sstevel@tonic-gate 				(void) printf(
5730Sstevel@tonic-gate 				"use compression  %d,  %d vs %d\n", st, k, cnt);
5740Sstevel@tonic-gate #endif
5750Sstevel@tonic-gate 			k = 0;
5760Sstevel@tonic-gate 			for (i = 1; i < ncg; i++)
5770Sstevel@tonic-gate 				if (temp[i] != -1) {
5780Sstevel@tonic-gate 					cwork[k] = i;
5790Sstevel@tonic-gate 					swork[k++] =
5804538Sdamico 					    (temp[i] == -2 ? -1 : temp[i]);
5810Sstevel@tonic-gate 				}
5820Sstevel@tonic-gate 			cwork[k] = 0;
5830Sstevel@tonic-gate #ifdef PC
5840Sstevel@tonic-gate 			ach = cwork;
5850Sstevel@tonic-gate 			ast = swork;
5860Sstevel@tonic-gate 			cnt = k;
5870Sstevel@tonic-gate 			cpackflg[st] = TRUE;
5880Sstevel@tonic-gate #endif
5890Sstevel@tonic-gate 		}
5900Sstevel@tonic-gate 	}
5910Sstevel@tonic-gate 	/*
5920Sstevel@tonic-gate 	 * get most similar state
5930Sstevel@tonic-gate 	 * reject state with more transitions,
5940Sstevel@tonic-gate 	 * state already represented by a third state,
5950Sstevel@tonic-gate 	 * and state which is compressed by char if ours is not to be
5960Sstevel@tonic-gate 	 */
5970Sstevel@tonic-gate 	for (i = 0; i < st; i++) {
5980Sstevel@tonic-gate 		if (sfall[i] != -1)
5990Sstevel@tonic-gate 			continue;
6000Sstevel@tonic-gate 		if (cpackflg[st] == 1)
6010Sstevel@tonic-gate 			if (!(cpackflg[i] == 1))
6020Sstevel@tonic-gate 				continue;
6030Sstevel@tonic-gate 		p = gotof[i];
6040Sstevel@tonic-gate 		if (p == -1) /* no transitions */
6050Sstevel@tonic-gate 			continue;
6060Sstevel@tonic-gate 		tcnt = nexts[p];
6070Sstevel@tonic-gate 		if (tcnt > cnt)
6080Sstevel@tonic-gate 			continue;
6090Sstevel@tonic-gate 		diff = 0;
6100Sstevel@tonic-gate 		k = 0;
6110Sstevel@tonic-gate 		j = 0;
6120Sstevel@tonic-gate 		upper = p + tcnt;
6130Sstevel@tonic-gate 		while (ach[j] && p < upper) {
6140Sstevel@tonic-gate 			while (ach[j] < nchar[p] && ach[j]) {
6150Sstevel@tonic-gate 				diff++;
6160Sstevel@tonic-gate 				j++;
6170Sstevel@tonic-gate 			}
6180Sstevel@tonic-gate 			if (ach[j] == 0)
6190Sstevel@tonic-gate 				break;
6200Sstevel@tonic-gate 			if (ach[j] > nchar[p]) {
6210Sstevel@tonic-gate 				diff = ncg;
6220Sstevel@tonic-gate 				break;
6230Sstevel@tonic-gate 			}
6240Sstevel@tonic-gate 			/* ach[j] == nchar[p] */
6250Sstevel@tonic-gate 			if (ast[j] != nexts[++p] ||
6264538Sdamico 			    ast[j] == -1 ||
6274538Sdamico 			    (cpackflg[st] && ach[j] != match[ach[j]]))
6280Sstevel@tonic-gate 				diff++;
6290Sstevel@tonic-gate 			j++;
6300Sstevel@tonic-gate 		}
6310Sstevel@tonic-gate 		while (ach[j]) {
6320Sstevel@tonic-gate 			diff++;
6330Sstevel@tonic-gate 			j++;
6340Sstevel@tonic-gate 		}
6350Sstevel@tonic-gate 		if (p < upper)
6360Sstevel@tonic-gate 			diff = ncg;
6370Sstevel@tonic-gate 		if (diff < cval && diff < tcnt) {
6380Sstevel@tonic-gate 			cval = diff;
6390Sstevel@tonic-gate 			cmin = i;
6400Sstevel@tonic-gate 			if (cval == 0)
6410Sstevel@tonic-gate 				break;
6420Sstevel@tonic-gate 		}
6430Sstevel@tonic-gate 	}
6440Sstevel@tonic-gate 	/* cmin = state "most like" state st */
6450Sstevel@tonic-gate #ifdef DEBUG
6460Sstevel@tonic-gate 	if (debug)
6470Sstevel@tonic-gate 		(void) printf("select st %d for st %d diff %d\n",
6484538Sdamico 		    cmin, st, cval);
6490Sstevel@tonic-gate #endif
6500Sstevel@tonic-gate #ifdef PS
6510Sstevel@tonic-gate 	if (cmin != -1) { /* if we can use st cmin */
6520Sstevel@tonic-gate 		gotof[st] = nptr;
6530Sstevel@tonic-gate 		k = 0;
6540Sstevel@tonic-gate 		sfall[st] = cmin;
6550Sstevel@tonic-gate 		p = gotof[cmin] + 1;
6560Sstevel@tonic-gate 		j = 0;
6570Sstevel@tonic-gate 		while (ach[j]) {
6580Sstevel@tonic-gate 			/* if cmin has a transition on c, then so will st */
6590Sstevel@tonic-gate 			/* st may be "larger" than cmin, however */
6600Sstevel@tonic-gate 			while (ach[j] < nchar[p-1] && ach[j]) {
6610Sstevel@tonic-gate 				k++;
6620Sstevel@tonic-gate 				nchar[nptr] = ach[j];
6630Sstevel@tonic-gate 				nexts[++nptr] = ast[j];
6640Sstevel@tonic-gate 				j++;
6650Sstevel@tonic-gate 			}
6660Sstevel@tonic-gate 			if (nchar[p-1] == 0)
6670Sstevel@tonic-gate 				break;
6680Sstevel@tonic-gate 			if (ach[j] > nchar[p-1]) {
6690Sstevel@tonic-gate 				warning("bad transition %d %d", st, cmin);
6700Sstevel@tonic-gate 				goto nopack;
6710Sstevel@tonic-gate 			}
6720Sstevel@tonic-gate 			/* ach[j] == nchar[p-1] */
6730Sstevel@tonic-gate 			if (ast[j] != nexts[p] ||
6744538Sdamico 			    ast[j] == -1 ||
6754538Sdamico 			    (cpackflg[st] && ach[j] != match[ach[j]])) {
6760Sstevel@tonic-gate 				k++;
6770Sstevel@tonic-gate 				nchar[nptr] = ach[j];
6780Sstevel@tonic-gate 				nexts[++nptr] = ast[j];
6790Sstevel@tonic-gate 			}
6800Sstevel@tonic-gate 			p++;
6810Sstevel@tonic-gate 			j++;
6820Sstevel@tonic-gate 		}
6830Sstevel@tonic-gate 		while (ach[j]) {
6840Sstevel@tonic-gate 			nchar[nptr] = ach[j];
6850Sstevel@tonic-gate 			nexts[++nptr] = ast[j++];
6860Sstevel@tonic-gate 			k++;
6870Sstevel@tonic-gate 		}
6880Sstevel@tonic-gate 		nexts[gotof[st]] = cnt = k;
6890Sstevel@tonic-gate 		nchar[nptr++] = 0;
6900Sstevel@tonic-gate 	} else {
6910Sstevel@tonic-gate #endif
6920Sstevel@tonic-gate nopack:
6930Sstevel@tonic-gate 	/* stick it in */
6940Sstevel@tonic-gate 		gotof[st] = nptr;
6950Sstevel@tonic-gate 		nexts[nptr] = cnt;
6960Sstevel@tonic-gate 		for (i = 0; i < cnt; i++) {
6970Sstevel@tonic-gate 			nchar[nptr] = ach[i];
6980Sstevel@tonic-gate 			nexts[++nptr] = ast[i];
6990Sstevel@tonic-gate 		}
7000Sstevel@tonic-gate 		nchar[nptr++] = 0;
7010Sstevel@tonic-gate #ifdef PS
7020Sstevel@tonic-gate 	}
7030Sstevel@tonic-gate #endif
7040Sstevel@tonic-gate 	if (cnt < 1) {
7050Sstevel@tonic-gate 		gotof[st] = -1;
7060Sstevel@tonic-gate 		nptr--;
7070Sstevel@tonic-gate 	} else
7080Sstevel@tonic-gate 		if (nptr > ntrans)
7090Sstevel@tonic-gate 			error(
7100Sstevel@tonic-gate 			"Too many transitions %s",
7114538Sdamico 			    (ntrans == NTRANS ? "\nTry using %a num" : ""));
7120Sstevel@tonic-gate }
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate #ifdef DEBUG
7150Sstevel@tonic-gate void
pstate(int s)7160Sstevel@tonic-gate pstate(int s)
7170Sstevel@tonic-gate {
7180Sstevel@tonic-gate 	int *p, i, j;
7190Sstevel@tonic-gate 	(void) printf("State %d:\n", s);
7200Sstevel@tonic-gate 	p = state[s];
7210Sstevel@tonic-gate 	i = *p++;
7220Sstevel@tonic-gate 	if (i == 0)
7230Sstevel@tonic-gate 		return;
7240Sstevel@tonic-gate 	(void) printf("%4d", *p++);
7250Sstevel@tonic-gate 	for (j = 1; j < i; j++) {
7260Sstevel@tonic-gate 		(void) printf(", %4d", *p++);
7270Sstevel@tonic-gate 		if (j%30 == 0)
7280Sstevel@tonic-gate 			(void) putchar('\n');
7290Sstevel@tonic-gate 	}
7300Sstevel@tonic-gate 	(void) putchar('\n');
7310Sstevel@tonic-gate }
7320Sstevel@tonic-gate #endif
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate static int
member(int d,CHR * t)7350Sstevel@tonic-gate member(int d, CHR *t)
7360Sstevel@tonic-gate {
7370Sstevel@tonic-gate 	int c;
7380Sstevel@tonic-gate 	CHR *s;
7390Sstevel@tonic-gate 	c = d;
7400Sstevel@tonic-gate 	s = t;
7410Sstevel@tonic-gate 	c = cindex[c];
7420Sstevel@tonic-gate 	while (*s)
7430Sstevel@tonic-gate 		if (*s++ == c)
7440Sstevel@tonic-gate 			return (1);
7450Sstevel@tonic-gate 	return (0);
7460Sstevel@tonic-gate }
7470Sstevel@tonic-gate 
7480Sstevel@tonic-gate #ifdef DEBUG
7490Sstevel@tonic-gate void
stprt(int i)7500Sstevel@tonic-gate stprt(int i)
7510Sstevel@tonic-gate {
7520Sstevel@tonic-gate 	int p, t;
7530Sstevel@tonic-gate 	(void) printf("State %d:", i);
7540Sstevel@tonic-gate 	/* print actions, if any */
7550Sstevel@tonic-gate 	t = atable[i];
7560Sstevel@tonic-gate 	if (t != -1)
7570Sstevel@tonic-gate 		(void) printf(" final");
7580Sstevel@tonic-gate 	(void) putchar('\n');
7590Sstevel@tonic-gate 	if (cpackflg[i] == TRUE)
7600Sstevel@tonic-gate 		(void) printf("backup char in use\n");
7610Sstevel@tonic-gate 	if (sfall[i] != -1)
7620Sstevel@tonic-gate 		(void) printf("fall back state %d\n", sfall[i]);
7630Sstevel@tonic-gate 	p = gotof[i];
7640Sstevel@tonic-gate 	if (p == -1)
7650Sstevel@tonic-gate 		return;
7660Sstevel@tonic-gate 	(void) printf("(%d transitions)\n", nexts[p]);
7670Sstevel@tonic-gate 	while (nchar[p]) {
7680Sstevel@tonic-gate 		charc = 0;
7690Sstevel@tonic-gate 		if (nexts[p+1] >= 0)
7700Sstevel@tonic-gate 			(void) printf("%d\t", nexts[p+1]);
7710Sstevel@tonic-gate 		else
7720Sstevel@tonic-gate 			(void) printf("err\t");
7730Sstevel@tonic-gate 		allprint(nchar[p++]);
7740Sstevel@tonic-gate 		while (nexts[p] == nexts[p+1] && nchar[p]) {
7750Sstevel@tonic-gate 			if (charc > LINESIZE) {
7760Sstevel@tonic-gate 				charc = 0;
7770Sstevel@tonic-gate 				(void) printf("\n\t");
7780Sstevel@tonic-gate 			}
7790Sstevel@tonic-gate 			allprint(nchar[p++]);
7800Sstevel@tonic-gate 		}
7810Sstevel@tonic-gate 		(void) putchar('\n');
7820Sstevel@tonic-gate 	}
7830Sstevel@tonic-gate 	(void) putchar('\n');
7840Sstevel@tonic-gate }
7850Sstevel@tonic-gate #endif
7860Sstevel@tonic-gate 
7870Sstevel@tonic-gate /* compute action list = set of poss. actions */
7880Sstevel@tonic-gate static void
acompute(int s)7890Sstevel@tonic-gate acompute(int s)
7900Sstevel@tonic-gate {
7910Sstevel@tonic-gate 	int *p, i, j;
7920Sstevel@tonic-gate 	int q, r;
7930Sstevel@tonic-gate 	int cnt, m;
7940Sstevel@tonic-gate 	int temp[MAXPOSSTATE], k, neg[MAXPOSSTATE], n;
7950Sstevel@tonic-gate 	k = 0;
7960Sstevel@tonic-gate 	n = 0;
7970Sstevel@tonic-gate 	p = state[s];
7980Sstevel@tonic-gate 	cnt = *p++;
7990Sstevel@tonic-gate 	if (cnt > MAXPOSSTATE)
8000Sstevel@tonic-gate 		error("Too many positions for one state - acompute");
8010Sstevel@tonic-gate 	for (i = 0; i < cnt; i++) {
8020Sstevel@tonic-gate 		q = *p;
8030Sstevel@tonic-gate 		if (name[q] == FINAL)
8040Sstevel@tonic-gate 			temp[k++] = left[q];
8050Sstevel@tonic-gate 		else if (name[q] == S1FINAL) {
8060Sstevel@tonic-gate 			temp[k++] = left[q];
8070Sstevel@tonic-gate 			if ((r = left[q]) >= NACTIONS)
8080Sstevel@tonic-gate 				error(
8090Sstevel@tonic-gate 				"INTERNAL ERROR:left[%d]==%d>=NACTIONS", q, r);
8100Sstevel@tonic-gate 			extra[r] = 1;
8110Sstevel@tonic-gate 		} else if (name[q] == S2FINAL)
8120Sstevel@tonic-gate 			neg[n++] = left[q];
8130Sstevel@tonic-gate 		p++;
8140Sstevel@tonic-gate 	}
8150Sstevel@tonic-gate 	atable[s] = -1;
8160Sstevel@tonic-gate 	if (k < 1 && n < 1)
8170Sstevel@tonic-gate 		return;
8180Sstevel@tonic-gate #ifdef DEBUG
8190Sstevel@tonic-gate 	if (debug)
8200Sstevel@tonic-gate 		(void) printf("final %d actions:", s);
8210Sstevel@tonic-gate #endif
8220Sstevel@tonic-gate 	/* sort action list */
8230Sstevel@tonic-gate 	for (i = 0; i < k; i++)
8240Sstevel@tonic-gate 		for (j = i+1; j < k; j++)
8250Sstevel@tonic-gate 			if (temp[j] < temp[i]) {
8260Sstevel@tonic-gate 				m = temp[j];
8270Sstevel@tonic-gate 				temp[j] = temp[i];
8280Sstevel@tonic-gate 				temp[i] = m;
8290Sstevel@tonic-gate 			}
8300Sstevel@tonic-gate 	/* remove dups */
8310Sstevel@tonic-gate 	for (i = 0; i < k-1; i++)
8320Sstevel@tonic-gate 		if (temp[i] == temp[i+1])
8330Sstevel@tonic-gate 			temp[i] = 0;
8340Sstevel@tonic-gate 	/* copy to permanent quarters */
8350Sstevel@tonic-gate 	atable[s] = aptr;
8360Sstevel@tonic-gate #ifdef DEBUG
8370Sstevel@tonic-gate 	if (!ratfor)
8380Sstevel@tonic-gate 		(void) fprintf(fout, "/* actions for state %d */", s);
8390Sstevel@tonic-gate #endif
8400Sstevel@tonic-gate 	(void) putc('\n', fout);
8410Sstevel@tonic-gate 	for (i = 0; i < k; i++)
8420Sstevel@tonic-gate 		if (temp[i] != 0) {
843*6951Sab196087 			(void) (ratfor ?
8444538Sdamico 			    fprintf(fout, "data vstop(%d)/%d/\n",
8454538Sdamico 			    aptr, temp[i]) :
846*6951Sab196087 			    fprintf(fout, "%d,\n", temp[i]));
8470Sstevel@tonic-gate #ifdef DEBUG
8480Sstevel@tonic-gate 			if (debug)
8490Sstevel@tonic-gate 				(void) printf("%d ", temp[i]);
8500Sstevel@tonic-gate #endif
8510Sstevel@tonic-gate 			aptr++;
8520Sstevel@tonic-gate 		}
8530Sstevel@tonic-gate 	for (i = 0; i < n; i++) { /* copy fall back actions - all neg */
8540Sstevel@tonic-gate 		ratfor ?
855*6951Sab196087 		    (void) fprintf(fout, "data vstop(%d)/%d/\n", aptr, neg[i]) :
856*6951Sab196087 		    (void) fprintf(fout, "%d,\n", neg[i]);
8570Sstevel@tonic-gate 		aptr++;
8580Sstevel@tonic-gate #ifdef DEBUG
8590Sstevel@tonic-gate 		if (debug)
8600Sstevel@tonic-gate 			(void) printf("%d ", neg[i]);
8610Sstevel@tonic-gate #endif
8620Sstevel@tonic-gate 		}
8630Sstevel@tonic-gate #ifdef DEBUG
8640Sstevel@tonic-gate 	if (debug)
8650Sstevel@tonic-gate 		(void) putchar('\n');
8660Sstevel@tonic-gate #endif
867*6951Sab196087 	(void) (ratfor ? fprintf(fout, "data vstop (%d)/0/\n", aptr) :
868*6951Sab196087 	    fprintf(fout, "0, \n"));
8690Sstevel@tonic-gate 	aptr++;
8700Sstevel@tonic-gate }
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate #ifdef DEBUG
8730Sstevel@tonic-gate void
pccl(void)8740Sstevel@tonic-gate pccl(void)
8750Sstevel@tonic-gate {
8760Sstevel@tonic-gate 	/* print character class sets */
8770Sstevel@tonic-gate 	int i, j;
8780Sstevel@tonic-gate 	(void) printf("char class intersection\n");
8790Sstevel@tonic-gate 	for (i = 0; i < ccount; i++) {
8800Sstevel@tonic-gate 		charc = 0;
8810Sstevel@tonic-gate 		(void) printf("class %d:\n\t", i);
8820Sstevel@tonic-gate 		for (j = 1; j < ncg; j++)
8830Sstevel@tonic-gate 			if (cindex[j] == i) {
8840Sstevel@tonic-gate 				allprint(j);
8850Sstevel@tonic-gate 				if (charc > LINESIZE) {
8860Sstevel@tonic-gate 					(void) printf("\n\t");
8870Sstevel@tonic-gate 					charc = 0;
8880Sstevel@tonic-gate 				}
8890Sstevel@tonic-gate 			}
8900Sstevel@tonic-gate 		(void) putchar('\n');
8910Sstevel@tonic-gate 	}
8920Sstevel@tonic-gate 	charc = 0;
8930Sstevel@tonic-gate 	(void) printf("match:\n");
8940Sstevel@tonic-gate 	for (i = 0; i < ncg; i++) {
8950Sstevel@tonic-gate 		allprint(match[i]);
8960Sstevel@tonic-gate 		if (charc > LINESIZE) {
8970Sstevel@tonic-gate 			(void) putchar('\n');
8980Sstevel@tonic-gate 			charc = 0;
8990Sstevel@tonic-gate 		}
9000Sstevel@tonic-gate 	}
9010Sstevel@tonic-gate 	(void) putchar('\n');
9020Sstevel@tonic-gate }
9030Sstevel@tonic-gate #endif
9040Sstevel@tonic-gate 
9050Sstevel@tonic-gate void
mkmatch(void)9060Sstevel@tonic-gate mkmatch(void)
9070Sstevel@tonic-gate {
9080Sstevel@tonic-gate 	int i;
9090Sstevel@tonic-gate 	CHR tab[MAXNCG];
9100Sstevel@tonic-gate 	for (i = 0; i < ccount; i++)
9110Sstevel@tonic-gate 		tab[i] = 0;
9120Sstevel@tonic-gate 	for (i = 1; i < ncg; i++)
9130Sstevel@tonic-gate 		if (tab[cindex[i]] == 0)
9140Sstevel@tonic-gate 			tab[cindex[i]] = i;
9150Sstevel@tonic-gate 	/* tab[i] = principal char for new ccl i */
9160Sstevel@tonic-gate 	for (i = 1; i < ncg; i++)
9170Sstevel@tonic-gate 		match[i] = tab[cindex[i]];
9180Sstevel@tonic-gate }
9190Sstevel@tonic-gate 
9200Sstevel@tonic-gate void
layout(void)9210Sstevel@tonic-gate layout(void)
9220Sstevel@tonic-gate {
9230Sstevel@tonic-gate 	/* format and output final program's tables */
9240Sstevel@tonic-gate 	int i, j, k;
9250Sstevel@tonic-gate 	int  top, bot, startup, omin;
9260Sstevel@tonic-gate 	startup = 0;
9270Sstevel@tonic-gate 	for (i = 0; i < outsize; i++)
9280Sstevel@tonic-gate 		verify[i] = advance[i] = 0;
9290Sstevel@tonic-gate 	omin = 0;
9300Sstevel@tonic-gate 	yytop = 0;
9310Sstevel@tonic-gate 	for (i = 0; i <= stnum; i++) { /* for each state */
9320Sstevel@tonic-gate 		j = gotof[i];
9330Sstevel@tonic-gate 		if (j == -1) {
9340Sstevel@tonic-gate 			stoff[i] = 0;
9350Sstevel@tonic-gate 			continue;
9360Sstevel@tonic-gate 		}
9370Sstevel@tonic-gate 		bot = j;
9380Sstevel@tonic-gate 		while (nchar[j])
9390Sstevel@tonic-gate 			j++;
9400Sstevel@tonic-gate 		top = j - 1;
9410Sstevel@tonic-gate #if DEBUG
9420Sstevel@tonic-gate 		if (debug) {
9430Sstevel@tonic-gate 			(void) printf("State %d: (layout)\n", i);
9440Sstevel@tonic-gate 			for (j = bot; j <= top; j++) {
9450Sstevel@tonic-gate 				(void) printf("  %o", nchar[j]);
9460Sstevel@tonic-gate 				if (j % 10 == 0)
9470Sstevel@tonic-gate 					(void) putchar('\n');
9480Sstevel@tonic-gate 			}
9490Sstevel@tonic-gate 			(void) putchar('\n');
9500Sstevel@tonic-gate 		}
9510Sstevel@tonic-gate #endif
9520Sstevel@tonic-gate 		while (verify[omin+ZCH])
9530Sstevel@tonic-gate 			omin++;
9540Sstevel@tonic-gate 		startup = omin;
9550Sstevel@tonic-gate #if DEBUG
9560Sstevel@tonic-gate 		if (debug)
9570Sstevel@tonic-gate 			(void) printf(
9580Sstevel@tonic-gate 			"bot,top %d, %d startup begins %d\n",
9594538Sdamico 			    bot, top, startup);
9600Sstevel@tonic-gate #endif
9610Sstevel@tonic-gate 		if (chset) {
9620Sstevel@tonic-gate 			do {
9630Sstevel@tonic-gate 				startup += 1;
9640Sstevel@tonic-gate 				if (startup > outsize - ZCH)
9650Sstevel@tonic-gate 					error("output table overflow");
9660Sstevel@tonic-gate 				for (j = bot; j <= top; j++) {
9670Sstevel@tonic-gate 					k = startup+ctable[nchar[j]];
9680Sstevel@tonic-gate 					if (verify[k])
9690Sstevel@tonic-gate 						break;
9700Sstevel@tonic-gate 				}
9710Sstevel@tonic-gate 			} while (j <= top);
9720Sstevel@tonic-gate #if DEBUG
9730Sstevel@tonic-gate 			if (debug)
9740Sstevel@tonic-gate 				(void) printf(" startup will be %d\n",
9754538Sdamico 				    startup);
9760Sstevel@tonic-gate #endif
9770Sstevel@tonic-gate 			/* have found place */
9780Sstevel@tonic-gate 			for (j = bot; j <= top; j++) {
9790Sstevel@tonic-gate 				k = startup + ctable[nchar[j]];
9800Sstevel@tonic-gate 				if (ctable[nchar[j]] <= 0)
9810Sstevel@tonic-gate 					(void) printf(
9820Sstevel@tonic-gate 					"j %d nchar %d ctable.nch %d\n",
983*6951Sab196087 					    j, (int)nchar[j], ctable[nchar[k]]);
9840Sstevel@tonic-gate 				verify[k] = i + 1;	/* state number + 1 */
9850Sstevel@tonic-gate 				advance[k] = nexts[j+1]+1;
9860Sstevel@tonic-gate 				if (yytop < k)
9870Sstevel@tonic-gate 					yytop = k;
9880Sstevel@tonic-gate 			}
9890Sstevel@tonic-gate 		} else {
9900Sstevel@tonic-gate 			do {
9910Sstevel@tonic-gate 				startup += 1;
9920Sstevel@tonic-gate 				if (startup > outsize - ZCH)
9930Sstevel@tonic-gate 					error("output table overflow");
9940Sstevel@tonic-gate 				for (j = bot; j <= top; j++) {
9950Sstevel@tonic-gate 					k = startup + nchar[j];
9960Sstevel@tonic-gate 					if (verify[k])
9970Sstevel@tonic-gate 						break;
9980Sstevel@tonic-gate 				}
9990Sstevel@tonic-gate 			} while (j <= top);
10000Sstevel@tonic-gate 			/* have found place */
10010Sstevel@tonic-gate #if DEBUG
10020Sstevel@tonic-gate 	if (debug)
10030Sstevel@tonic-gate 		(void) printf(" startup going to be %d\n", startup);
10040Sstevel@tonic-gate #endif
10050Sstevel@tonic-gate 			for (j = bot; j <= top; j++) {
10060Sstevel@tonic-gate 				k = startup + nchar[j];
10070Sstevel@tonic-gate 				verify[k] = i+1; /* state number + 1 */
10080Sstevel@tonic-gate 				advance[k] = nexts[j+1] + 1;
10090Sstevel@tonic-gate 				if (yytop < k)
10100Sstevel@tonic-gate 					yytop = k;
10110Sstevel@tonic-gate 			}
10120Sstevel@tonic-gate 		}
10130Sstevel@tonic-gate 		stoff[i] = startup;
10140Sstevel@tonic-gate 	}
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate 	/* stoff[i] = offset into verify, advance for trans for state i */
10170Sstevel@tonic-gate 	/* put out yywork */
10180Sstevel@tonic-gate 	if (ratfor) {
10190Sstevel@tonic-gate 		(void) fprintf(fout, "define YYTOPVAL %d\n", yytop);
10200Sstevel@tonic-gate 		rprint(verify, "verif", yytop+1);
10210Sstevel@tonic-gate 		rprint(advance, "advan", yytop+1);
10220Sstevel@tonic-gate 		shiftr(stoff, stnum);
10230Sstevel@tonic-gate 		rprint(stoff, "stoff", stnum+1);
10240Sstevel@tonic-gate 		shiftr(sfall, stnum);
10250Sstevel@tonic-gate 		upone(sfall, stnum+1);
10260Sstevel@tonic-gate 		rprint(sfall, "fall", stnum+1);
10270Sstevel@tonic-gate 		bprint(extra, "extra", casecount+1);
10280Sstevel@tonic-gate 		bprint((char *)match, "match", ncg);
10290Sstevel@tonic-gate 		shiftr(atable, stnum);
10300Sstevel@tonic-gate 		rprint(atable, "atable", stnum+1);
10310Sstevel@tonic-gate 	}
10320Sstevel@tonic-gate 	(void) fprintf(fout,
10330Sstevel@tonic-gate 	"# define YYTYPE %s\n", stnum+1 >= NCH ? "int" : "unsigned char");
10340Sstevel@tonic-gate 	(void) fprintf(fout,
10350Sstevel@tonic-gate 	"struct yywork { YYTYPE verify, advance; } yycrank[] = {\n");
10360Sstevel@tonic-gate 	for (i = 0; i <= yytop; i += 4) {
10370Sstevel@tonic-gate 		for (j = 0; j < 4; j++) {
10380Sstevel@tonic-gate 			k = i+j;
10390Sstevel@tonic-gate 			if (verify[k])
10400Sstevel@tonic-gate 				(void) fprintf(fout,
10410Sstevel@tonic-gate 				"%d,%d,\t", verify[k], advance[k]);
10420Sstevel@tonic-gate 			else
10430Sstevel@tonic-gate 				(void) fprintf(fout, "0,0,\t");
10440Sstevel@tonic-gate 		}
10450Sstevel@tonic-gate 		(void) putc('\n', fout);
10460Sstevel@tonic-gate 	}
10470Sstevel@tonic-gate 	(void) fprintf(fout, "0,0};\n");
10480Sstevel@tonic-gate 
10490Sstevel@tonic-gate 	/* put out yysvec */
10500Sstevel@tonic-gate 
10510Sstevel@tonic-gate 	(void) fprintf(fout, "struct yysvf yysvec[] = {\n");
10520Sstevel@tonic-gate 	(void) fprintf(fout, "0,\t0,\t0,\n");
10530Sstevel@tonic-gate 	for (i = 0; i <= stnum; i++) {	/* for each state */
10540Sstevel@tonic-gate 		if (cpackflg[i])
10550Sstevel@tonic-gate 			stoff[i] = -stoff[i];
10560Sstevel@tonic-gate 		(void) fprintf(fout, "yycrank+%d,\t", stoff[i]);
10570Sstevel@tonic-gate 		if (sfall[i] != -1)
10580Sstevel@tonic-gate 			(void) fprintf(fout,
10590Sstevel@tonic-gate 			"yysvec+%d,\t", sfall[i]+1); /* state + 1 */
10600Sstevel@tonic-gate 		else
10610Sstevel@tonic-gate 			(void) fprintf(fout, "0,\t\t");
10620Sstevel@tonic-gate 		if (atable[i] != -1)
10630Sstevel@tonic-gate 			(void) fprintf(fout, "yyvstop+%d,", atable[i]);
10640Sstevel@tonic-gate 		else
10650Sstevel@tonic-gate 			(void) fprintf(fout, "0,\t");
10660Sstevel@tonic-gate #ifdef DEBUG
10670Sstevel@tonic-gate 		(void) fprintf(fout, "\t\t/* state %d */", i);
10680Sstevel@tonic-gate #endif
10690Sstevel@tonic-gate 		(void) putc('\n', fout);
10700Sstevel@tonic-gate 	}
10710Sstevel@tonic-gate 	(void) fprintf(fout, "0,\t0,\t0};\n");
10720Sstevel@tonic-gate 
10730Sstevel@tonic-gate 	/* put out yymatch */
10740Sstevel@tonic-gate 
10750Sstevel@tonic-gate 	(void) fprintf(fout, "struct yywork *yytop = yycrank+%d;\n", yytop);
10760Sstevel@tonic-gate 	(void) fprintf(fout, "struct yysvf *yybgin = yysvec+1;\n");
10770Sstevel@tonic-gate 	if (optim) {
10780Sstevel@tonic-gate 		if (handleeuc) {
10790Sstevel@tonic-gate 			(void) fprintf(fout, "int yymatch[] = {\n");
10800Sstevel@tonic-gate 		} else {
10810Sstevel@tonic-gate 			(void) fprintf(fout, "char yymatch[] = {\n");
10820Sstevel@tonic-gate 		}
10830Sstevel@tonic-gate 		if (chset == 0) { /* no chset, put out in normal order */
10840Sstevel@tonic-gate 			for (i = 0; i < ncg; i += 8) {
10850Sstevel@tonic-gate 				for (j = 0; j < 8; j++) {
10860Sstevel@tonic-gate 					int fbch;
10870Sstevel@tonic-gate 					fbch = match[i+j];
1088*6951Sab196087 					(void) fprintf(fout, "%3d, ", fbch);
10890Sstevel@tonic-gate 				}
10900Sstevel@tonic-gate 				(void) putc('\n', fout);
10910Sstevel@tonic-gate 			}
10920Sstevel@tonic-gate 		} else {
10930Sstevel@tonic-gate 			int *fbarr;
1094*6951Sab196087 			/*LINTED: E_BAD_PTR_CAST_ALIGN*/
10950Sstevel@tonic-gate 			fbarr = (int *)myalloc(2*MAXNCG, sizeof (*fbarr));
10960Sstevel@tonic-gate 			if (fbarr == 0)
10970Sstevel@tonic-gate 				error("No space for char table reverse", 0);
10980Sstevel@tonic-gate 			for (i = 0; i < MAXNCG; i++)
10990Sstevel@tonic-gate 				fbarr[i] = 0;
11000Sstevel@tonic-gate 			for (i = 0; i < ncg; i++)
11010Sstevel@tonic-gate 				fbarr[ctable[i]] = ctable[match[i]];
11020Sstevel@tonic-gate 			for (i = 0; i < ncg; i += 8) {
11030Sstevel@tonic-gate 				for (j = 0; j < 8; j++)
1104*6951Sab196087 					(void) fprintf(fout, "0%-3o,",
1105*6951Sab196087 					    fbarr[i+j]);
1106*6951Sab196087 				(void) putc('\n', fout);
11070Sstevel@tonic-gate 			}
11080Sstevel@tonic-gate 			free(fbarr);
11090Sstevel@tonic-gate 		}
11100Sstevel@tonic-gate 		(void) fprintf(fout, "0};\n");
11110Sstevel@tonic-gate 	}
11120Sstevel@tonic-gate 	/* put out yyextra */
11130Sstevel@tonic-gate 	(void) fprintf(fout, "char yyextra[] = {\n");
11140Sstevel@tonic-gate 	for (i = 0; i < casecount; i += 8) {
11150Sstevel@tonic-gate 		for (j = 0; j < 8; j++)
11160Sstevel@tonic-gate 			(void) fprintf(fout, "%d,", i+j < NACTIONS ?
11174538Sdamico 			    extra[i+j] : 0);
11180Sstevel@tonic-gate 		(void) putc('\n', fout);
11190Sstevel@tonic-gate 	}
11200Sstevel@tonic-gate 	(void) fprintf(fout, "0};\n");
11210Sstevel@tonic-gate 	if (handleeuc) {
11220Sstevel@tonic-gate 		/* Put out yycgidtbl */
1123*6951Sab196087 		(void) fprintf(fout, "#define YYNCGIDTBL %d\n", ncgidtbl);
1124*6951Sab196087 		(void) fprintf(fout, "\tunsigned long yycgidtbl[]={");
11250Sstevel@tonic-gate 		/*
11260Sstevel@tonic-gate 		 * Use "unsigned long" instead of "lchar" to minimize
11270Sstevel@tonic-gate 		 * the name-space polution for the application program.
11280Sstevel@tonic-gate 		 */
11290Sstevel@tonic-gate 		for (i = 0; i < ncgidtbl; ++i) {
11300Sstevel@tonic-gate 			if (i%8 == 0)
1131*6951Sab196087 				(void) fprintf(fout, "\n\t\t");
1132*6951Sab196087 			(void) fprintf(fout, "0x%08x, ",  (int)yycgidtbl[i]);
11330Sstevel@tonic-gate 		}
1134*6951Sab196087 		(void) fprintf(fout, "\n\t0};\n");
11350Sstevel@tonic-gate 	}
11360Sstevel@tonic-gate }
11370Sstevel@tonic-gate 
11380Sstevel@tonic-gate static void
rprint(int * a,char * s,int n)11390Sstevel@tonic-gate rprint(int *a, char *s, int n)
11400Sstevel@tonic-gate {
11410Sstevel@tonic-gate 	int i;
11420Sstevel@tonic-gate 	(void) fprintf(fout, "block data\n");
11430Sstevel@tonic-gate 	(void) fprintf(fout, "common /L%s/ %s\n", s, s);
11440Sstevel@tonic-gate 	(void) fprintf(fout, "define S%s %d\n", s, n);
11450Sstevel@tonic-gate 	(void) fprintf(fout, "integer %s (S%s)\n", s, s);
11460Sstevel@tonic-gate 	for (i = 1; i <= n; i++) {
11470Sstevel@tonic-gate 		if (i%8 == 1)
11480Sstevel@tonic-gate 			(void) fprintf(fout, "data ");
11490Sstevel@tonic-gate 		(void) fprintf(fout, "%s (%d)/%d/", s, i, a[i]);
11500Sstevel@tonic-gate 		(void) fprintf(fout, (i%8 && i < n) ? ", " : "\n");
11510Sstevel@tonic-gate 	}
11520Sstevel@tonic-gate 	(void) fprintf(fout, "end\n");
11530Sstevel@tonic-gate }
11540Sstevel@tonic-gate 
11550Sstevel@tonic-gate static void
shiftr(int * a,int n)11560Sstevel@tonic-gate shiftr(int *a, int n)
11570Sstevel@tonic-gate {
11580Sstevel@tonic-gate 	int i;
11590Sstevel@tonic-gate 	for (i = n; i >= 0; i--)
11600Sstevel@tonic-gate 		a[i+1] = a[i];
11610Sstevel@tonic-gate }
11620Sstevel@tonic-gate 
11630Sstevel@tonic-gate static void
upone(int * a,int n)11640Sstevel@tonic-gate upone(int *a, int n)
11650Sstevel@tonic-gate {
11660Sstevel@tonic-gate 	int i;
11670Sstevel@tonic-gate 	for (i = 0; i <= n; i++)
11680Sstevel@tonic-gate 		a[i]++;
11690Sstevel@tonic-gate }
11700Sstevel@tonic-gate 
11710Sstevel@tonic-gate static void
bprint(char * a,char * s,int n)11720Sstevel@tonic-gate bprint(char *a, char *s, int n)
11730Sstevel@tonic-gate {
11740Sstevel@tonic-gate 	int i, j, k;
11750Sstevel@tonic-gate 	(void) fprintf(fout, "block data\n");
11760Sstevel@tonic-gate 	(void) fprintf(fout, "common /L%s/ %s\n", s, s);
11770Sstevel@tonic-gate 	(void) fprintf(fout, "define S%s %d\n", s, n);
11780Sstevel@tonic-gate 	(void) fprintf(fout, "integer %s (S%s)\n", s, s);
11790Sstevel@tonic-gate 	for (i = 1; i < n; i += 8) {
11800Sstevel@tonic-gate 		(void) fprintf(fout, "data %s (%d)/%d/", s, i, a[i]);
11810Sstevel@tonic-gate 		for (j = 1; j < 8; j++) {
11820Sstevel@tonic-gate 			k = i+j;
11830Sstevel@tonic-gate 			if (k < n)
11840Sstevel@tonic-gate 				(void) fprintf(fout,
11854538Sdamico 				    ", %s (%d)/%d/", s, k, a[k]);
11860Sstevel@tonic-gate 		}
11870Sstevel@tonic-gate 		(void) putc('\n', fout);
11880Sstevel@tonic-gate 	}
11890Sstevel@tonic-gate 	(void) fprintf(fout, "end\n");
11900Sstevel@tonic-gate }
11910Sstevel@tonic-gate 
11920Sstevel@tonic-gate #ifdef PP
11930Sstevel@tonic-gate static void
padd(int ** array,int n)11940Sstevel@tonic-gate padd(int **array, int n)
11950Sstevel@tonic-gate {
11960Sstevel@tonic-gate 	int i, *j, k;
11970Sstevel@tonic-gate 	array[n] = nxtpos;
11980Sstevel@tonic-gate 	if (count == 0) {
11990Sstevel@tonic-gate 		*nxtpos++ = 0;
12000Sstevel@tonic-gate 		return;
12010Sstevel@tonic-gate 	}
12020Sstevel@tonic-gate 	for (i = tptr-1; i >= 0; i--) {
12030Sstevel@tonic-gate 		j = array[i];
12040Sstevel@tonic-gate 		if (j && *j++ == count) {
12050Sstevel@tonic-gate 			for (k = 0; k < count; k++)
12060Sstevel@tonic-gate 				if (!tmpstat[*j++])
12070Sstevel@tonic-gate 					break;
12080Sstevel@tonic-gate 			if (k >= count) {
12090Sstevel@tonic-gate 				array[n] = array[i];
12100Sstevel@tonic-gate 				return;
12110Sstevel@tonic-gate 			}
12120Sstevel@tonic-gate 		}
12130Sstevel@tonic-gate 	}
12140Sstevel@tonic-gate 	add(array, n);
12150Sstevel@tonic-gate }
12160Sstevel@tonic-gate #endif
1217