xref: /plan9-contrib/sys/src/cmd/lex/sub2.c (revision 43af371b8d63420d32d0cb0b58914db16dcd7715)
13e12c5d1SDavid du Colombier # include "ldefs.h"
23e12c5d1SDavid du Colombier void
cfoll(int v)33e12c5d1SDavid du Colombier cfoll(int v)
43e12c5d1SDavid du Colombier {
53e12c5d1SDavid du Colombier 	int i,j,k;
63e12c5d1SDavid du Colombier 	uchar *p;
73e12c5d1SDavid du Colombier 	i = name[v];
83e12c5d1SDavid du Colombier 	if(i < NCH) i = 1;	/* character */
93e12c5d1SDavid du Colombier 	switch(i){
103e12c5d1SDavid du Colombier 		case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:
113e12c5d1SDavid du Colombier 			for(j=0;j<tptr;j++)
123e12c5d1SDavid du Colombier 				tmpstat[j] = FALSE;
133e12c5d1SDavid du Colombier 			count = 0;
143e12c5d1SDavid du Colombier 			follow(v);
153e12c5d1SDavid du Colombier # ifdef PP
163e12c5d1SDavid du Colombier 			padd(foll,v);		/* packing version */
173e12c5d1SDavid du Colombier # endif
183e12c5d1SDavid du Colombier # ifndef PP
193e12c5d1SDavid du Colombier 			add(foll,v);		/* no packing version */
203e12c5d1SDavid du Colombier # endif
213e12c5d1SDavid du Colombier 			if(i == RSTR) cfoll(left[v]);
223e12c5d1SDavid du Colombier 			else if(i == RCCL || i == RNCCL){	/* compress ccl list */
233e12c5d1SDavid du Colombier 				for(j=1; j<NCH;j++)
243e12c5d1SDavid du Colombier 					symbol[j] = (i==RNCCL);
2574f16c81SDavid du Colombier 				p = ptr[v];
263e12c5d1SDavid du Colombier 				while(*p)
273e12c5d1SDavid du Colombier 					symbol[*p++] = (i == RCCL);
283e12c5d1SDavid du Colombier 				p = pcptr;
293e12c5d1SDavid du Colombier 				for(j=1;j<NCH;j++)
303e12c5d1SDavid du Colombier 					if(symbol[j]){
313e12c5d1SDavid du Colombier 						for(k=0;p+k < pcptr; k++)
323e12c5d1SDavid du Colombier 							if(cindex[j] == *(p+k))
333e12c5d1SDavid du Colombier 								break;
343e12c5d1SDavid du Colombier 						if(p+k >= pcptr)*pcptr++ = cindex[j];
353e12c5d1SDavid du Colombier 					}
363e12c5d1SDavid du Colombier 				*pcptr++ = 0;
373e12c5d1SDavid du Colombier 				if(pcptr > pchar + pchlen)
383e12c5d1SDavid du Colombier 					error("Too many packed character classes");
3974f16c81SDavid du Colombier 				ptr[v] = p;
403e12c5d1SDavid du Colombier 				name[v] = RCCL;	/* RNCCL eliminated */
413e12c5d1SDavid du Colombier # ifdef DEBUG
423e12c5d1SDavid du Colombier 				if(debug && *p){
43219b2ee8SDavid du Colombier 					print("ccl %d: %d",v,*p++);
443e12c5d1SDavid du Colombier 					while(*p)
45219b2ee8SDavid du Colombier 						print(", %d",*p++);
46219b2ee8SDavid du Colombier 					print("\n");
473e12c5d1SDavid du Colombier 				}
483e12c5d1SDavid du Colombier # endif
493e12c5d1SDavid du Colombier 			}
503e12c5d1SDavid du Colombier 			break;
513e12c5d1SDavid du Colombier 		case CARAT:
523e12c5d1SDavid du Colombier 			cfoll(left[v]);
533e12c5d1SDavid du Colombier 			break;
543e12c5d1SDavid du Colombier 		case STAR: case PLUS: case QUEST: case RSCON:
553e12c5d1SDavid du Colombier 			cfoll(left[v]);
563e12c5d1SDavid du Colombier 			break;
573e12c5d1SDavid du Colombier 		case BAR: case RCAT: case DIV: case RNEWE:
583e12c5d1SDavid du Colombier 			cfoll(left[v]);
593e12c5d1SDavid du Colombier 			cfoll(right[v]);
603e12c5d1SDavid du Colombier 			break;
613e12c5d1SDavid du Colombier # ifdef DEBUG
623e12c5d1SDavid du Colombier 		case FINAL:
633e12c5d1SDavid du Colombier 		case S1FINAL:
643e12c5d1SDavid du Colombier 		case S2FINAL:
653e12c5d1SDavid du Colombier 			break;
663e12c5d1SDavid du Colombier 		default:
673e12c5d1SDavid du Colombier 			warning("bad switch cfoll %d",v);
683e12c5d1SDavid du Colombier # endif
693e12c5d1SDavid du Colombier 	}
703e12c5d1SDavid du Colombier }
713e12c5d1SDavid du Colombier 
723e12c5d1SDavid du Colombier # ifdef DEBUG
733e12c5d1SDavid du Colombier void
pfoll(void)743e12c5d1SDavid du Colombier pfoll(void)
753e12c5d1SDavid du Colombier 	{
763e12c5d1SDavid du Colombier 	int i,k,*p;
773e12c5d1SDavid du Colombier 	int j;
783e12c5d1SDavid du Colombier 	/* print sets of chars which may follow positions */
79219b2ee8SDavid du Colombier 	print("pos\tchars\n");
803e12c5d1SDavid du Colombier 	for(i=0;i<tptr;i++)
813e12c5d1SDavid du Colombier 		if(p=foll[i]){
823e12c5d1SDavid du Colombier 			j = *p++;
833e12c5d1SDavid du Colombier 			if(j >= 1){
84219b2ee8SDavid du Colombier 				print("%d:\t%d",i,*p++);
853e12c5d1SDavid du Colombier 				for(k=2;k<=j;k++)
86219b2ee8SDavid du Colombier 					print(", %d",*p++);
87219b2ee8SDavid du Colombier 				print("\n");
883e12c5d1SDavid du Colombier 			}
893e12c5d1SDavid du Colombier 		}
903e12c5d1SDavid du Colombier }
913e12c5d1SDavid du Colombier # endif
923e12c5d1SDavid du Colombier 
933e12c5d1SDavid du Colombier void
add(int ** array,int n)943e12c5d1SDavid du Colombier add(int **array, int n)
953e12c5d1SDavid du Colombier {
963e12c5d1SDavid du Colombier 	int i, *temp;
973e12c5d1SDavid du Colombier 	uchar *ctemp;
983e12c5d1SDavid du Colombier 
993e12c5d1SDavid du Colombier 	temp = nxtpos;
1003e12c5d1SDavid du Colombier 	ctemp = tmpstat;
1013e12c5d1SDavid du Colombier 	array[n] = nxtpos;		/* note no packing is done in positions */
1023e12c5d1SDavid du Colombier 	*temp++ = count;
1033e12c5d1SDavid du Colombier 	for(i=0;i<tptr;i++)
1043e12c5d1SDavid du Colombier 		if(ctemp[i] == TRUE)
1053e12c5d1SDavid du Colombier 			*temp++ = i;
1063e12c5d1SDavid du Colombier 	nxtpos = temp;
1073e12c5d1SDavid du Colombier 	if(nxtpos >= positions+maxpos)
1083e12c5d1SDavid du Colombier 		error("Too many positions %s",(maxpos== MAXPOS?"\nTry using %p num":""));
1093e12c5d1SDavid du Colombier }
1103e12c5d1SDavid du Colombier 
1113e12c5d1SDavid du Colombier void
follow(int v)1123e12c5d1SDavid du Colombier follow(int v)
1133e12c5d1SDavid du Colombier {
1143e12c5d1SDavid du Colombier 	int p;
1153e12c5d1SDavid du Colombier 	if(v >= tptr-1)return;
1163e12c5d1SDavid du Colombier 	p = parent[v];
1173e12c5d1SDavid du Colombier 	if(p == 0) return;
1183e12c5d1SDavid du Colombier 	switch(name[p]){
1193e12c5d1SDavid du Colombier 			/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
1203e12c5d1SDavid du Colombier 		case RSTR:
1213e12c5d1SDavid du Colombier 			if(tmpstat[p] == FALSE){
1223e12c5d1SDavid du Colombier 				count++;
1233e12c5d1SDavid du Colombier 				tmpstat[p] = TRUE;
1243e12c5d1SDavid du Colombier 			}
1253e12c5d1SDavid du Colombier 			break;
1263e12c5d1SDavid du Colombier 		case STAR: case PLUS:
1273e12c5d1SDavid du Colombier 			first(v);
1283e12c5d1SDavid du Colombier 			follow(p);
1293e12c5d1SDavid du Colombier 			break;
1303e12c5d1SDavid du Colombier 		case BAR: case QUEST: case RNEWE:
1313e12c5d1SDavid du Colombier 			follow(p);
1323e12c5d1SDavid du Colombier 			break;
1333e12c5d1SDavid du Colombier 		case RCAT: case DIV:
1343e12c5d1SDavid du Colombier 			if(v == left[p]){
1353e12c5d1SDavid du Colombier 				if(nullstr[right[p]])
1363e12c5d1SDavid du Colombier 					follow(p);
1373e12c5d1SDavid du Colombier 				first(right[p]);
1383e12c5d1SDavid du Colombier 			}
1393e12c5d1SDavid du Colombier 			else follow(p);
1403e12c5d1SDavid du Colombier 			break;
1413e12c5d1SDavid du Colombier 		case RSCON: case CARAT:
1423e12c5d1SDavid du Colombier 			follow(p);
1433e12c5d1SDavid du Colombier 			break;
1443e12c5d1SDavid du Colombier # ifdef DEBUG
1453e12c5d1SDavid du Colombier 		default:
1463e12c5d1SDavid du Colombier 			warning("bad switch follow %d",p);
1473e12c5d1SDavid du Colombier # endif
1483e12c5d1SDavid du Colombier 	}
1493e12c5d1SDavid du Colombier }
1503e12c5d1SDavid du Colombier 
1513e12c5d1SDavid du Colombier void
first(int v)1523e12c5d1SDavid du Colombier first(int v)	/* calculate set of positions with v as root which can be active initially */
1533e12c5d1SDavid du Colombier {
1543e12c5d1SDavid du Colombier 	int i;
1553e12c5d1SDavid du Colombier 	uchar *p;
1563e12c5d1SDavid du Colombier 	i = name[v];
1573e12c5d1SDavid du Colombier 	if(i < NCH)i = 1;
1583e12c5d1SDavid du Colombier 	switch(i){
1593e12c5d1SDavid du Colombier 		case 1: case RCCL: case RNCCL: case RNULLS: case FINAL: case S1FINAL: case S2FINAL:
1603e12c5d1SDavid du Colombier 			if(tmpstat[v] == FALSE){
1613e12c5d1SDavid du Colombier 				count++;
1623e12c5d1SDavid du Colombier 				tmpstat[v] = TRUE;
1633e12c5d1SDavid du Colombier 			}
1643e12c5d1SDavid du Colombier 			break;
1653e12c5d1SDavid du Colombier 		case BAR: case RNEWE:
1663e12c5d1SDavid du Colombier 			first(left[v]);
1673e12c5d1SDavid du Colombier 			first(right[v]);
1683e12c5d1SDavid du Colombier 			break;
1693e12c5d1SDavid du Colombier 		case CARAT:
1703e12c5d1SDavid du Colombier 			if(stnum % 2 == 1)
1713e12c5d1SDavid du Colombier 				first(left[v]);
1723e12c5d1SDavid du Colombier 			break;
1733e12c5d1SDavid du Colombier 		case RSCON:
1743e12c5d1SDavid du Colombier 			i = stnum/2 +1;
1753e12c5d1SDavid du Colombier 			p = (uchar *)right[v];
1763e12c5d1SDavid du Colombier 			while(*p)
1773e12c5d1SDavid du Colombier 				if(*p++ == i){
1783e12c5d1SDavid du Colombier 					first(left[v]);
1793e12c5d1SDavid du Colombier 					break;
1803e12c5d1SDavid du Colombier 				}
1813e12c5d1SDavid du Colombier 			break;
1823e12c5d1SDavid du Colombier 		case STAR: case QUEST: case PLUS:  case RSTR:
1833e12c5d1SDavid du Colombier 			first(left[v]);
1843e12c5d1SDavid du Colombier 			break;
1853e12c5d1SDavid du Colombier 		case RCAT: case DIV:
1863e12c5d1SDavid du Colombier 			first(left[v]);
1873e12c5d1SDavid du Colombier 			if(nullstr[left[v]])
1883e12c5d1SDavid du Colombier 				first(right[v]);
1893e12c5d1SDavid du Colombier 			break;
1903e12c5d1SDavid du Colombier # ifdef DEBUG
1913e12c5d1SDavid du Colombier 		default:
1923e12c5d1SDavid du Colombier 			warning("bad switch first %d",v);
1933e12c5d1SDavid du Colombier # endif
1943e12c5d1SDavid du Colombier 	}
1953e12c5d1SDavid du Colombier }
1963e12c5d1SDavid du Colombier 
1973e12c5d1SDavid du Colombier void
cgoto(void)1983e12c5d1SDavid du Colombier cgoto(void)
1993e12c5d1SDavid du Colombier {
2003e12c5d1SDavid du Colombier 	int i, j, s;
2013e12c5d1SDavid du Colombier 	int npos, curpos, n;
2023e12c5d1SDavid du Colombier 	int tryit;
2033e12c5d1SDavid du Colombier 	uchar tch[NCH];
2043e12c5d1SDavid du Colombier 	int tst[NCH];
2053e12c5d1SDavid du Colombier 	uchar *q;
2063e12c5d1SDavid du Colombier 
2073e12c5d1SDavid du Colombier 	/* generate initial state, for each start condition */
208219b2ee8SDavid du Colombier 	Bprint(&fout,"int yyvstop[] = {\n0,\n");
2093e12c5d1SDavid du Colombier 	while(stnum < 2 || stnum/2 < sptr){
2103e12c5d1SDavid du Colombier 		for(i = 0; i<tptr; i++) tmpstat[i] = 0;
2113e12c5d1SDavid du Colombier 		count = 0;
2123e12c5d1SDavid du Colombier 		if(tptr > 0)first(tptr-1);
2133e12c5d1SDavid du Colombier 		add(state,stnum);
2143e12c5d1SDavid du Colombier # ifdef DEBUG
2153e12c5d1SDavid du Colombier 		if(debug){
2163e12c5d1SDavid du Colombier 			if(stnum > 1)
217219b2ee8SDavid du Colombier 				print("%s:\n",sname[stnum/2]);
2183e12c5d1SDavid du Colombier 			pstate(stnum);
2193e12c5d1SDavid du Colombier 		}
2203e12c5d1SDavid du Colombier # endif
2213e12c5d1SDavid du Colombier 		stnum++;
2223e12c5d1SDavid du Colombier 	}
2233e12c5d1SDavid du Colombier 	stnum--;
2243e12c5d1SDavid du Colombier 	/* even stnum = might not be at line begin */
2253e12c5d1SDavid du Colombier 	/* odd stnum  = must be at line begin */
2263e12c5d1SDavid du Colombier 	/* even states can occur anywhere, odd states only at line begin */
2273e12c5d1SDavid du Colombier 	for(s = 0; s <= stnum; s++){
2283e12c5d1SDavid du Colombier 		tryit = FALSE;
2293e12c5d1SDavid du Colombier 		cpackflg[s] = FALSE;
2303e12c5d1SDavid du Colombier 		sfall[s] = -1;
2313e12c5d1SDavid du Colombier 		acompute(s);
2323e12c5d1SDavid du Colombier 		for(i=0;i<NCH;i++) symbol[i] = 0;
2333e12c5d1SDavid du Colombier 		npos = *state[s];
2343e12c5d1SDavid du Colombier 		for(i = 1; i<=npos; i++){
2353e12c5d1SDavid du Colombier 			curpos = *(state[s]+i);
2363e12c5d1SDavid du Colombier 			if(name[curpos] < NCH) symbol[name[curpos]] = TRUE;
2373e12c5d1SDavid du Colombier 			else switch(name[curpos]){
2383e12c5d1SDavid du Colombier 			case RCCL:
2393e12c5d1SDavid du Colombier 				tryit = TRUE;
240*1fa40b8eSDavid du Colombier 				q = ptr[curpos];
2413e12c5d1SDavid du Colombier 				while(*q){
2423e12c5d1SDavid du Colombier 					for(j=1;j<NCH;j++)
2433e12c5d1SDavid du Colombier 						if(cindex[j] == *q)
2443e12c5d1SDavid du Colombier 							symbol[j] = TRUE;
2453e12c5d1SDavid du Colombier 					q++;
2463e12c5d1SDavid du Colombier 				}
2473e12c5d1SDavid du Colombier 				break;
2483e12c5d1SDavid du Colombier 			case RSTR:
2493e12c5d1SDavid du Colombier 				symbol[right[curpos]] = TRUE;
2503e12c5d1SDavid du Colombier 				break;
2513e12c5d1SDavid du Colombier # ifdef DEBUG
2523e12c5d1SDavid du Colombier 			case RNULLS:
2533e12c5d1SDavid du Colombier 			case FINAL:
2543e12c5d1SDavid du Colombier 			case S1FINAL:
2553e12c5d1SDavid du Colombier 			case S2FINAL:
2563e12c5d1SDavid du Colombier 				break;
2573e12c5d1SDavid du Colombier 			default:
2583e12c5d1SDavid du Colombier 				warning("bad switch cgoto %d state %d",curpos,s);
2593e12c5d1SDavid du Colombier 				break;
2603e12c5d1SDavid du Colombier # endif
2613e12c5d1SDavid du Colombier 			}
2623e12c5d1SDavid du Colombier 		}
2633e12c5d1SDavid du Colombier # ifdef DEBUG
2643e12c5d1SDavid du Colombier 		if(debug){
265219b2ee8SDavid du Colombier 			print("State %d transitions on:\n\t",s);
2663e12c5d1SDavid du Colombier 			charc = 0;
2673e12c5d1SDavid du Colombier 			for(i = 1; i<NCH; i++){
2683e12c5d1SDavid du Colombier 				if(symbol[i]) allprint(i);
2693e12c5d1SDavid du Colombier 				if(charc > LINESIZE){
2703e12c5d1SDavid du Colombier 					charc = 0;
271219b2ee8SDavid du Colombier 					print("\n\t");
2723e12c5d1SDavid du Colombier 				}
2733e12c5d1SDavid du Colombier 			}
274219b2ee8SDavid du Colombier 			print("\n");
2753e12c5d1SDavid du Colombier 		}
2763e12c5d1SDavid du Colombier # endif
2773e12c5d1SDavid du Colombier 		/* for each char, calculate next state */
2783e12c5d1SDavid du Colombier 		n = 0;
2793e12c5d1SDavid du Colombier 		for(i = 1; i<NCH; i++){
2803e12c5d1SDavid du Colombier 			if(symbol[i]){
2813e12c5d1SDavid du Colombier 				nextstate(s,i);		/* executed for each state, transition pair */
2823e12c5d1SDavid du Colombier 				xstate = notin(stnum);
2833e12c5d1SDavid du Colombier 				if(xstate == -2) warning("bad state  %d %o",s,i);
2843e12c5d1SDavid du Colombier 				else if(xstate == -1){
2853e12c5d1SDavid du Colombier 					if(stnum >= nstates)
2863e12c5d1SDavid du Colombier 						error("Too many states %s",(nstates == NSTATES ? "\nTry using %n num":""));
2873e12c5d1SDavid du Colombier 					add(state,++stnum);
2883e12c5d1SDavid du Colombier # ifdef DEBUG
2893e12c5d1SDavid du Colombier 					if(debug)pstate(stnum);
2903e12c5d1SDavid du Colombier # endif
2913e12c5d1SDavid du Colombier 					tch[n] = i;
2923e12c5d1SDavid du Colombier 					tst[n++] = stnum;
2933e12c5d1SDavid du Colombier 				} else {		/* xstate >= 0 ==> state exists */
2943e12c5d1SDavid du Colombier 					tch[n] = i;
2953e12c5d1SDavid du Colombier 					tst[n++] = xstate;
2963e12c5d1SDavid du Colombier 				}
2973e12c5d1SDavid du Colombier 			}
2983e12c5d1SDavid du Colombier 		}
2993e12c5d1SDavid du Colombier 		tch[n] = 0;
3003e12c5d1SDavid du Colombier 		tst[n] = -1;
3013e12c5d1SDavid du Colombier 		/* pack transitions into permanent array */
3023e12c5d1SDavid du Colombier 		if(n > 0) packtrans(s,tch,tst,n,tryit);
3033e12c5d1SDavid du Colombier 		else gotof[s] = -1;
3043e12c5d1SDavid du Colombier 	}
305219b2ee8SDavid du Colombier 	Bprint(&fout,"0};\n");
3063e12c5d1SDavid du Colombier }
3073e12c5d1SDavid du Colombier 
3083e12c5d1SDavid du Colombier /*	Beware -- 70% of total CPU time is spent in this subroutine -
3093e12c5d1SDavid du Colombier 	if you don't believe me - try it yourself ! */
3103e12c5d1SDavid du Colombier void
nextstate(int s,int c)3113e12c5d1SDavid du Colombier nextstate(int s, int c)
3123e12c5d1SDavid du Colombier {
3133e12c5d1SDavid du Colombier 	int j, *newpos;
3143e12c5d1SDavid du Colombier 	uchar *temp, *tz;
3153e12c5d1SDavid du Colombier 	int *pos, i, *f, num, curpos, number;
3163e12c5d1SDavid du Colombier 	/* state to goto from state s on char c */
3173e12c5d1SDavid du Colombier 	num = *state[s];
3183e12c5d1SDavid du Colombier 	temp = tmpstat;
3193e12c5d1SDavid du Colombier 	pos = state[s] + 1;
3203e12c5d1SDavid du Colombier 	for(i = 0; i<num; i++){
3213e12c5d1SDavid du Colombier 		curpos = *pos++;
3223e12c5d1SDavid du Colombier 		j = name[curpos];
3233e12c5d1SDavid du Colombier 		if(j < NCH && j == c
3243e12c5d1SDavid du Colombier 		|| j == RSTR && c == right[curpos]
325*1fa40b8eSDavid du Colombier 		|| j == RCCL && member(c, ptr[curpos])){
3263e12c5d1SDavid du Colombier 			f = foll[curpos];
3273e12c5d1SDavid du Colombier 			number = *f;
3283e12c5d1SDavid du Colombier 			newpos = f+1;
3293e12c5d1SDavid du Colombier 			for(j=0;j<number;j++)
3303e12c5d1SDavid du Colombier 				temp[*newpos++] = 2;
3313e12c5d1SDavid du Colombier 		}
3323e12c5d1SDavid du Colombier 	}
3333e12c5d1SDavid du Colombier 	j = 0;
3343e12c5d1SDavid du Colombier 	tz = temp + tptr;
3353e12c5d1SDavid du Colombier 	while(temp < tz){
3363e12c5d1SDavid du Colombier 		if(*temp == 2){
3373e12c5d1SDavid du Colombier 			j++;
3383e12c5d1SDavid du Colombier 			*temp++ = 1;
3393e12c5d1SDavid du Colombier 		}
3403e12c5d1SDavid du Colombier 		else *temp++ = 0;
3413e12c5d1SDavid du Colombier 	}
3423e12c5d1SDavid du Colombier 	count = j;
3433e12c5d1SDavid du Colombier }
3443e12c5d1SDavid du Colombier 
3453e12c5d1SDavid du Colombier int
notin(int n)3463e12c5d1SDavid du Colombier notin(int n)
3473e12c5d1SDavid du Colombier {	/* see if tmpstat occurs previously */
3483e12c5d1SDavid du Colombier 	int *j,k;
3493e12c5d1SDavid du Colombier 	uchar *temp;
3503e12c5d1SDavid du Colombier 	int i;
3513e12c5d1SDavid du Colombier 
3523e12c5d1SDavid du Colombier 	if(count == 0)
3533e12c5d1SDavid du Colombier 		return(-2);
3543e12c5d1SDavid du Colombier 	temp = tmpstat;
3553e12c5d1SDavid du Colombier 	for(i=n;i>=0;i--){	/* for each state */
3563e12c5d1SDavid du Colombier 		j = state[i];
3573e12c5d1SDavid du Colombier 		if(count == *j++){
3583e12c5d1SDavid du Colombier 			for(k=0;k<count;k++)
3593e12c5d1SDavid du Colombier 				if(!temp[*j++])break;
3603e12c5d1SDavid du Colombier 			if(k >= count)
3613e12c5d1SDavid du Colombier 				return(i);
3623e12c5d1SDavid du Colombier 		}
3633e12c5d1SDavid du Colombier 	}
3643e12c5d1SDavid du Colombier 	return(-1);
3653e12c5d1SDavid du Colombier }
3663e12c5d1SDavid du Colombier 
3673e12c5d1SDavid du Colombier void
packtrans(int st,uchar * tch,int * tst,int cnt,int tryit)3683e12c5d1SDavid du Colombier packtrans(int st, uchar *tch, int *tst, int cnt, int tryit)
3693e12c5d1SDavid du Colombier {
3703e12c5d1SDavid du Colombier 	/* pack transitions into nchar, nexts */
3713e12c5d1SDavid du Colombier 	/* nchar is terminated by '\0', nexts uses cnt, followed by elements */
3723e12c5d1SDavid du Colombier 	/* gotof[st] = index into nchr, nexts for state st */
3733e12c5d1SDavid du Colombier 
3743e12c5d1SDavid du Colombier 	/* sfall[st] =  t implies t is fall back state for st */
3753e12c5d1SDavid du Colombier 	/*	        == -1 implies no fall back */
3763e12c5d1SDavid du Colombier 
3773e12c5d1SDavid du Colombier 	int i,j,k;
3783e12c5d1SDavid du Colombier 	int cmin, cval, tcnt, diff, p, *ast;
3793e12c5d1SDavid du Colombier 	uchar *ach;
3803e12c5d1SDavid du Colombier 	int go[NCH], temp[NCH], c;
3813e12c5d1SDavid du Colombier 	int swork[NCH];
3823e12c5d1SDavid du Colombier 	uchar cwork[NCH];
3833e12c5d1SDavid du Colombier 	int upper;
3843e12c5d1SDavid du Colombier 
3853e12c5d1SDavid du Colombier 	rcount += cnt;
3863e12c5d1SDavid du Colombier 	cmin = -1;
3873e12c5d1SDavid du Colombier 	cval = NCH;
3883e12c5d1SDavid du Colombier 	ast = tst;
3893e12c5d1SDavid du Colombier 	ach = tch;
3903e12c5d1SDavid du Colombier 	/* try to pack transitions using ccl's */
3913e12c5d1SDavid du Colombier 	if(tryit){	/* ccl's used */
3923e12c5d1SDavid du Colombier 		for(i=1;i<NCH;i++){
3933e12c5d1SDavid du Colombier 			go[i] = temp[i] = -1;
3943e12c5d1SDavid du Colombier 			symbol[i] = 1;
3953e12c5d1SDavid du Colombier 		}
3963e12c5d1SDavid du Colombier 		for(i=0;i<cnt;i++){
3973e12c5d1SDavid du Colombier 			go[tch[i]] = tst[i];
3983e12c5d1SDavid du Colombier 			symbol[tch[i]] = 0;
3993e12c5d1SDavid du Colombier 		}
4003e12c5d1SDavid du Colombier 		for(i=0; i<cnt;i++){
4013e12c5d1SDavid du Colombier 			c = match[tch[i]];
4023e12c5d1SDavid du Colombier 			if(go[c] != tst[i] || c == tch[i])
4033e12c5d1SDavid du Colombier 				temp[tch[i]] = tst[i];
4043e12c5d1SDavid du Colombier 		}
4053e12c5d1SDavid du Colombier 		/* fill in error entries */
4063e12c5d1SDavid du Colombier 		for(i=1;i<NCH;i++)
4073e12c5d1SDavid du Colombier 			if(symbol[i]) temp[i] = -2;	/* error trans */
4083e12c5d1SDavid du Colombier 		/* count them */
4093e12c5d1SDavid du Colombier 		k = 0;
4103e12c5d1SDavid du Colombier 		for(i=1;i<NCH;i++)
4113e12c5d1SDavid du Colombier 			if(temp[i] != -1)k++;
4123e12c5d1SDavid du Colombier 		if(k <cnt){	/* compress by char */
4133e12c5d1SDavid du Colombier # ifdef DEBUG
414219b2ee8SDavid du Colombier 			if(debug) print("use compression  %d,  %d vs %d\n",st,k,cnt);
4153e12c5d1SDavid du Colombier # endif
4163e12c5d1SDavid du Colombier 			k = 0;
4173e12c5d1SDavid du Colombier 			for(i=1;i<NCH;i++)
4183e12c5d1SDavid du Colombier 				if(temp[i] != -1){
4193e12c5d1SDavid du Colombier 					cwork[k] = i;
4203e12c5d1SDavid du Colombier 					swork[k++] = (temp[i] == -2 ? -1 : temp[i]);
4213e12c5d1SDavid du Colombier 				}
4223e12c5d1SDavid du Colombier 			cwork[k] = 0;
4233e12c5d1SDavid du Colombier # ifdef PC
4243e12c5d1SDavid du Colombier 			ach = cwork;
4253e12c5d1SDavid du Colombier 			ast = swork;
4263e12c5d1SDavid du Colombier 			cnt = k;
4273e12c5d1SDavid du Colombier 			cpackflg[st] = TRUE;
4283e12c5d1SDavid du Colombier # endif
4293e12c5d1SDavid du Colombier 		}
4303e12c5d1SDavid du Colombier 	}
4313e12c5d1SDavid du Colombier 	for(i=0; i<st; i++){	/* get most similar state */
4323e12c5d1SDavid du Colombier 				/* reject state with more transitions, state already represented by a third state,
4333e12c5d1SDavid du Colombier 					and state which is compressed by char if ours is not to be */
4343e12c5d1SDavid du Colombier 		if(sfall[i] != -1) continue;
4353e12c5d1SDavid du Colombier 		if(cpackflg[st] == 1) if(!(cpackflg[i] == 1)) continue;
4363e12c5d1SDavid du Colombier 		p = gotof[i];
4373e12c5d1SDavid du Colombier 		if(p == -1) /* no transitions */ continue;
4383e12c5d1SDavid du Colombier 		tcnt = nexts[p];
4393e12c5d1SDavid du Colombier 		if(tcnt > cnt) continue;
4403e12c5d1SDavid du Colombier 		diff = 0;
4413e12c5d1SDavid du Colombier 		j = 0;
4423e12c5d1SDavid du Colombier 		upper = p + tcnt;
4433e12c5d1SDavid du Colombier 		while(ach[j] && p < upper){
4443e12c5d1SDavid du Colombier 			while(ach[j] < nchar[p] && ach[j]){diff++; j++; }
4453e12c5d1SDavid du Colombier 			if(ach[j] == 0)break;
4463e12c5d1SDavid du Colombier 			if(ach[j] > nchar[p]){diff=NCH;break;}
4473e12c5d1SDavid du Colombier 			/* ach[j] == nchar[p] */
4483e12c5d1SDavid du Colombier 			if(ast[j] != nexts[++p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]]))diff++;
4493e12c5d1SDavid du Colombier 			j++;
4503e12c5d1SDavid du Colombier 		}
4513e12c5d1SDavid du Colombier 		while(ach[j]){
4523e12c5d1SDavid du Colombier 			diff++;
4533e12c5d1SDavid du Colombier 			j++;
4543e12c5d1SDavid du Colombier 		}
4553e12c5d1SDavid du Colombier 		if(p < upper)diff = NCH;
4563e12c5d1SDavid du Colombier 		if(diff < cval && diff < tcnt){
4573e12c5d1SDavid du Colombier 			cval = diff;
4583e12c5d1SDavid du Colombier 			cmin = i;
4593e12c5d1SDavid du Colombier 			if(cval == 0)break;
4603e12c5d1SDavid du Colombier 		}
4613e12c5d1SDavid du Colombier 	}
4623e12c5d1SDavid du Colombier 	/* cmin = state "most like" state st */
4633e12c5d1SDavid du Colombier # ifdef DEBUG
464219b2ee8SDavid du Colombier 	if(debug)print("select st %d for st %d diff %d\n",cmin,st,cval);
4653e12c5d1SDavid du Colombier # endif
4663e12c5d1SDavid du Colombier # ifdef PS
4673e12c5d1SDavid du Colombier 	if(cmin != -1){ /* if we can use st cmin */
4683e12c5d1SDavid du Colombier 		gotof[st] = nptr;
4693e12c5d1SDavid du Colombier 		k = 0;
4703e12c5d1SDavid du Colombier 		sfall[st] = cmin;
4713e12c5d1SDavid du Colombier 		p = gotof[cmin]+1;
4723e12c5d1SDavid du Colombier 		j = 0;
4733e12c5d1SDavid du Colombier 		while(ach[j]){
4743e12c5d1SDavid du Colombier 			/* if cmin has a transition on c, then so will st */
4753e12c5d1SDavid du Colombier 			/* st may be "larger" than cmin, however */
4763e12c5d1SDavid du Colombier 			while(ach[j] < nchar[p-1] && ach[j]){
4773e12c5d1SDavid du Colombier 				k++;
4783e12c5d1SDavid du Colombier 				nchar[nptr] = ach[j];
4793e12c5d1SDavid du Colombier 				nexts[++nptr] = ast[j];
4803e12c5d1SDavid du Colombier 				j++;
4813e12c5d1SDavid du Colombier 			}
4823e12c5d1SDavid du Colombier 			if(nchar[p-1] == 0)break;
4833e12c5d1SDavid du Colombier 			if(ach[j] > nchar[p-1]){
4843e12c5d1SDavid du Colombier 				warning("bad transition %d %d",st,cmin);
4853e12c5d1SDavid du Colombier 				goto nopack;
4863e12c5d1SDavid du Colombier 			}
4873e12c5d1SDavid du Colombier 			/* ach[j] == nchar[p-1] */
4883e12c5d1SDavid du Colombier 			if(ast[j] != nexts[p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]])){
4893e12c5d1SDavid du Colombier 				k++;
4903e12c5d1SDavid du Colombier 				nchar[nptr] = ach[j];
4913e12c5d1SDavid du Colombier 				nexts[++nptr] = ast[j];
4923e12c5d1SDavid du Colombier 			}
4933e12c5d1SDavid du Colombier 			p++;
4943e12c5d1SDavid du Colombier 			j++;
4953e12c5d1SDavid du Colombier 		}
4963e12c5d1SDavid du Colombier 		while(ach[j]){
4973e12c5d1SDavid du Colombier 			nchar[nptr] = ach[j];
4983e12c5d1SDavid du Colombier 			nexts[++nptr] = ast[j++];
4993e12c5d1SDavid du Colombier 			k++;
5003e12c5d1SDavid du Colombier 		}
5013e12c5d1SDavid du Colombier 		nexts[gotof[st]] = cnt = k;
5023e12c5d1SDavid du Colombier 		nchar[nptr++] = 0;
5033e12c5d1SDavid du Colombier 	} else {
5043e12c5d1SDavid du Colombier # endif
5053e12c5d1SDavid du Colombier nopack:
5063e12c5d1SDavid du Colombier 	/* stick it in */
5073e12c5d1SDavid du Colombier 		gotof[st] = nptr;
5083e12c5d1SDavid du Colombier 		nexts[nptr] = cnt;
5093e12c5d1SDavid du Colombier 		for(i=0;i<cnt;i++){
5103e12c5d1SDavid du Colombier 			nchar[nptr] = ach[i];
5113e12c5d1SDavid du Colombier 			nexts[++nptr] = ast[i];
5123e12c5d1SDavid du Colombier 		}
5133e12c5d1SDavid du Colombier 		nchar[nptr++] = 0;
5143e12c5d1SDavid du Colombier # ifdef PS
5153e12c5d1SDavid du Colombier 	}
5163e12c5d1SDavid du Colombier # endif
5173e12c5d1SDavid du Colombier 	if(cnt < 1){
5183e12c5d1SDavid du Colombier 		gotof[st] = -1;
5193e12c5d1SDavid du Colombier 		nptr--;
5203e12c5d1SDavid du Colombier 	} else
5213e12c5d1SDavid du Colombier 		if(nptr > ntrans)
5223e12c5d1SDavid du Colombier 			error("Too many transitions %s",(ntrans==NTRANS?"\nTry using %a num":""));
5233e12c5d1SDavid du Colombier }
5243e12c5d1SDavid du Colombier 
5253e12c5d1SDavid du Colombier # ifdef DEBUG
5263e12c5d1SDavid du Colombier void
pstate(int s)5273e12c5d1SDavid du Colombier pstate(int s)
5283e12c5d1SDavid du Colombier {
5293e12c5d1SDavid du Colombier 	int *p,i,j;
530219b2ee8SDavid du Colombier 	print("State %d:\n",s);
5313e12c5d1SDavid du Colombier 	p = state[s];
5323e12c5d1SDavid du Colombier 	i = *p++;
5333e12c5d1SDavid du Colombier 	if(i == 0) return;
534219b2ee8SDavid du Colombier 	print("%4d",*p++);
5353e12c5d1SDavid du Colombier 	for(j = 1; j<i; j++){
536219b2ee8SDavid du Colombier 		print(", %4d",*p++);
537219b2ee8SDavid du Colombier 		if(j%30 == 0)print("\n");
5383e12c5d1SDavid du Colombier 	}
539219b2ee8SDavid du Colombier 	print("\n");
5403e12c5d1SDavid du Colombier }
5413e12c5d1SDavid du Colombier # endif
5423e12c5d1SDavid du Colombier 
5433e12c5d1SDavid du Colombier int
member(int d,uchar * t)5443e12c5d1SDavid du Colombier member(int d, uchar *t)
5453e12c5d1SDavid du Colombier {
5463e12c5d1SDavid du Colombier 	int c;
5473e12c5d1SDavid du Colombier 	uchar *s;
5483e12c5d1SDavid du Colombier 
5493e12c5d1SDavid du Colombier 	c = d;
5503e12c5d1SDavid du Colombier 	s = t;
5513e12c5d1SDavid du Colombier 	c = cindex[c];
5523e12c5d1SDavid du Colombier 	while(*s)
5533e12c5d1SDavid du Colombier 		if(*s++ == c) return(1);
5543e12c5d1SDavid du Colombier 	return(0);
5553e12c5d1SDavid du Colombier }
5563e12c5d1SDavid du Colombier 
5573e12c5d1SDavid du Colombier # ifdef DEBUG
5583e12c5d1SDavid du Colombier void
stprt(int i)5593e12c5d1SDavid du Colombier stprt(int i)
5603e12c5d1SDavid du Colombier {
5613e12c5d1SDavid du Colombier 	int p, t;
5623e12c5d1SDavid du Colombier 
563219b2ee8SDavid du Colombier 	print("State %d:",i);
5643e12c5d1SDavid du Colombier 	/* print actions, if any */
5653e12c5d1SDavid du Colombier 	t = atable[i];
566219b2ee8SDavid du Colombier 	if(t != -1)print(" final");
567219b2ee8SDavid du Colombier 	print("\n");
568219b2ee8SDavid du Colombier 	if(cpackflg[i] == TRUE)print("backup char in use\n");
569219b2ee8SDavid du Colombier 	if(sfall[i] != -1)print("fall back state %d\n",sfall[i]);
5703e12c5d1SDavid du Colombier 	p = gotof[i];
5713e12c5d1SDavid du Colombier 	if(p == -1) return;
572219b2ee8SDavid du Colombier 	print("(%d transitions)\n",nexts[p]);
5733e12c5d1SDavid du Colombier 	while(nchar[p]){
5743e12c5d1SDavid du Colombier 		charc = 0;
5753e12c5d1SDavid du Colombier 		if(nexts[p+1] >= 0)
576219b2ee8SDavid du Colombier 			print("%d\t",nexts[p+1]);
577219b2ee8SDavid du Colombier 		else print("err\t");
5783e12c5d1SDavid du Colombier 		allprint(nchar[p++]);
5793e12c5d1SDavid du Colombier 		while(nexts[p] == nexts[p+1] && nchar[p]){
5803e12c5d1SDavid du Colombier 			if(charc > LINESIZE){
5813e12c5d1SDavid du Colombier 				charc = 0;
582219b2ee8SDavid du Colombier 				print("\n\t");
5833e12c5d1SDavid du Colombier 			}
5843e12c5d1SDavid du Colombier 			allprint(nchar[p++]);
5853e12c5d1SDavid du Colombier 		}
586219b2ee8SDavid du Colombier 		print("\n");
5873e12c5d1SDavid du Colombier 	}
588219b2ee8SDavid du Colombier 	print("\n");
5893e12c5d1SDavid du Colombier }
5903e12c5d1SDavid du Colombier # endif
5913e12c5d1SDavid du Colombier 
5923e12c5d1SDavid du Colombier void
acompute(int s)5933e12c5d1SDavid du Colombier acompute(int s)	/* compute action list = set of poss. actions */
5943e12c5d1SDavid du Colombier {
5953e12c5d1SDavid du Colombier 	int *p, i, j;
5963e12c5d1SDavid du Colombier 	int cnt, m;
5973e12c5d1SDavid du Colombier 	int temp[300], k, neg[300], n;
5983e12c5d1SDavid du Colombier 
5993e12c5d1SDavid du Colombier 	k = 0;
6003e12c5d1SDavid du Colombier 	n = 0;
6013e12c5d1SDavid du Colombier 	p = state[s];
6023e12c5d1SDavid du Colombier 	cnt = *p++;
6033e12c5d1SDavid du Colombier 	if(cnt > 300)
6043e12c5d1SDavid du Colombier 		error("Too many positions for one state - acompute");
6053e12c5d1SDavid du Colombier 	for(i=0;i<cnt;i++){
6063e12c5d1SDavid du Colombier 		if(name[*p] == FINAL)temp[k++] = left[*p];
6073e12c5d1SDavid du Colombier 		else if(name[*p] == S1FINAL){temp[k++] = left[*p];
6083e12c5d1SDavid du Colombier 			if (left[*p] >= NACTIONS) error("Too many right contexts");
6093e12c5d1SDavid du Colombier 			extra[left[*p]] = 1;
6103e12c5d1SDavid du Colombier 		} else if(name[*p] == S2FINAL)neg[n++] = left[*p];
6113e12c5d1SDavid du Colombier 		p++;
6123e12c5d1SDavid du Colombier 	}
6133e12c5d1SDavid du Colombier 	atable[s] = -1;
6143e12c5d1SDavid du Colombier 	if(k < 1 && n < 1) return;
6153e12c5d1SDavid du Colombier # ifdef DEBUG
616219b2ee8SDavid du Colombier 	if(debug) print("final %d actions:",s);
6173e12c5d1SDavid du Colombier # endif
6183e12c5d1SDavid du Colombier 	/* sort action list */
6193e12c5d1SDavid du Colombier 	for(i=0; i<k; i++)
6203e12c5d1SDavid du Colombier 		for(j=i+1;j<k;j++)
6213e12c5d1SDavid du Colombier 			if(temp[j] < temp[i]){
6223e12c5d1SDavid du Colombier 				m = temp[j];
6233e12c5d1SDavid du Colombier 				temp[j] = temp[i];
6243e12c5d1SDavid du Colombier 				temp[i] = m;
6253e12c5d1SDavid du Colombier 			}
6263e12c5d1SDavid du Colombier 	/* remove dups */
6273e12c5d1SDavid du Colombier 	for(i=0;i<k-1;i++)
6283e12c5d1SDavid du Colombier 		if(temp[i] == temp[i+1]) temp[i] = 0;
6293e12c5d1SDavid du Colombier 	/* copy to permanent quarters */
6303e12c5d1SDavid du Colombier 	atable[s] = aptr;
6313e12c5d1SDavid du Colombier # ifdef DEBUG
632219b2ee8SDavid du Colombier 	Bprint(&fout,"/* actions for state %d */",s);
6333e12c5d1SDavid du Colombier # endif
634219b2ee8SDavid du Colombier 	Bputc(&fout, '\n');
6353e12c5d1SDavid du Colombier 	for(i=0;i<k;i++)
6363e12c5d1SDavid du Colombier 		if(temp[i] != 0){
637219b2ee8SDavid du Colombier 			Bprint(&fout,"%d,\n",temp[i]);
6383e12c5d1SDavid du Colombier # ifdef DEBUG
6393e12c5d1SDavid du Colombier 			if(debug)
640219b2ee8SDavid du Colombier 				print("%d ",temp[i]);
6413e12c5d1SDavid du Colombier # endif
6423e12c5d1SDavid du Colombier 			aptr++;
6433e12c5d1SDavid du Colombier 		}
6443e12c5d1SDavid du Colombier 	for(i=0;i<n;i++){		/* copy fall back actions - all neg */
645219b2ee8SDavid du Colombier 		Bprint(&fout,"%d,\n",neg[i]);
6463e12c5d1SDavid du Colombier 		aptr++;
6473e12c5d1SDavid du Colombier # ifdef DEBUG
648219b2ee8SDavid du Colombier 		if(debug)print("%d ",neg[i]);
6493e12c5d1SDavid du Colombier # endif
6503e12c5d1SDavid du Colombier 	}
6513e12c5d1SDavid du Colombier # ifdef DEBUG
652219b2ee8SDavid du Colombier 	if(debug)print("\n");
6533e12c5d1SDavid du Colombier # endif
654219b2ee8SDavid du Colombier 	Bprint(&fout,"0,\n");
6553e12c5d1SDavid du Colombier 	aptr++;
6563e12c5d1SDavid du Colombier }
6573e12c5d1SDavid du Colombier 
6583e12c5d1SDavid du Colombier # ifdef DEBUG
6593e12c5d1SDavid du Colombier void
pccl(void)6603e12c5d1SDavid du Colombier pccl(void) {
6613e12c5d1SDavid du Colombier 	/* print character class sets */
6623e12c5d1SDavid du Colombier 	int i, j;
6633e12c5d1SDavid du Colombier 
664219b2ee8SDavid du Colombier 	print("char class intersection\n");
6653e12c5d1SDavid du Colombier 	for(i=0; i< ccount; i++){
6663e12c5d1SDavid du Colombier 		charc = 0;
667219b2ee8SDavid du Colombier 		print("class %d:\n\t",i);
6683e12c5d1SDavid du Colombier 		for(j=1;j<NCH;j++)
6693e12c5d1SDavid du Colombier 			if(cindex[j] == i){
6703e12c5d1SDavid du Colombier 				allprint(j);
6713e12c5d1SDavid du Colombier 				if(charc > LINESIZE){
672219b2ee8SDavid du Colombier 					print("\n\t");
6733e12c5d1SDavid du Colombier 					charc = 0;
6743e12c5d1SDavid du Colombier 				}
6753e12c5d1SDavid du Colombier 			}
676219b2ee8SDavid du Colombier 		print("\n");
6773e12c5d1SDavid du Colombier 	}
6783e12c5d1SDavid du Colombier 	charc = 0;
679219b2ee8SDavid du Colombier 	print("match:\n");
6803e12c5d1SDavid du Colombier 	for(i=0;i<NCH;i++){
6813e12c5d1SDavid du Colombier 		allprint(match[i]);
6823e12c5d1SDavid du Colombier 		if(charc > LINESIZE){
683219b2ee8SDavid du Colombier 			print("\n");
6843e12c5d1SDavid du Colombier 			charc = 0;
6853e12c5d1SDavid du Colombier 		}
6863e12c5d1SDavid du Colombier 	}
687219b2ee8SDavid du Colombier 	print("\n");
6883e12c5d1SDavid du Colombier }
6893e12c5d1SDavid du Colombier # endif
6903e12c5d1SDavid du Colombier 
6913e12c5d1SDavid du Colombier void
mkmatch(void)6923e12c5d1SDavid du Colombier mkmatch(void)
6933e12c5d1SDavid du Colombier {
6943e12c5d1SDavid du Colombier 	int i;
6953e12c5d1SDavid du Colombier 	uchar tab[NCH];
6963e12c5d1SDavid du Colombier 
6973e12c5d1SDavid du Colombier 	for(i=0; i<ccount; i++)
6983e12c5d1SDavid du Colombier 		tab[i] = 0;
6993e12c5d1SDavid du Colombier 	for(i=1;i<NCH;i++)
7003e12c5d1SDavid du Colombier 		if(tab[cindex[i]] == 0)
7013e12c5d1SDavid du Colombier 			tab[cindex[i]] = i;
7023e12c5d1SDavid du Colombier 	/* tab[i] = principal char for new ccl i */
7033e12c5d1SDavid du Colombier 	for(i = 1; i<NCH; i++)
7043e12c5d1SDavid du Colombier 		match[i] = tab[cindex[i]];
7053e12c5d1SDavid du Colombier }
7063e12c5d1SDavid du Colombier 
7073e12c5d1SDavid du Colombier void
layout(void)7083e12c5d1SDavid du Colombier layout(void)
7093e12c5d1SDavid du Colombier {
7103e12c5d1SDavid du Colombier 	/* format and output final program's tables */
7113e12c5d1SDavid du Colombier 	int i, j, k;
7123e12c5d1SDavid du Colombier 	int  top, bot, startup, omin;
7133e12c5d1SDavid du Colombier 
7143e12c5d1SDavid du Colombier 	for(i=0; i<outsize;i++)
7153e12c5d1SDavid du Colombier 		verify[i] = advance[i] = 0;
7163e12c5d1SDavid du Colombier 	omin = 0;
7173e12c5d1SDavid du Colombier 	yytop = 0;
7183e12c5d1SDavid du Colombier 	for(i=0; i<= stnum; i++){	/* for each state */
7193e12c5d1SDavid du Colombier 		j = gotof[i];
7203e12c5d1SDavid du Colombier 		if(j == -1){
7213e12c5d1SDavid du Colombier 			stoff[i] = 0;
7223e12c5d1SDavid du Colombier 			continue;
7233e12c5d1SDavid du Colombier 			}
7243e12c5d1SDavid du Colombier 		bot = j;
7253e12c5d1SDavid du Colombier 		while(nchar[j])j++;
7263e12c5d1SDavid du Colombier 		top = j - 1;
7273e12c5d1SDavid du Colombier # ifdef DEBUG
7283e12c5d1SDavid du Colombier 		if (debug) {
729219b2ee8SDavid du Colombier 			print("State %d: (layout)\n", i);
7303e12c5d1SDavid du Colombier 			for(j=bot; j<=top;j++) {
731219b2ee8SDavid du Colombier 				print("  %o", nchar[j]);
732219b2ee8SDavid du Colombier 				if (j%10==0) print("\n");
7333e12c5d1SDavid du Colombier 			}
734219b2ee8SDavid du Colombier 			print("\n");
7353e12c5d1SDavid du Colombier 		}
7363e12c5d1SDavid du Colombier # endif
7373e12c5d1SDavid du Colombier 		while(verify[omin+NCH]) omin++;
7383e12c5d1SDavid du Colombier 		startup = omin;
7393e12c5d1SDavid du Colombier # ifdef DEBUG
740219b2ee8SDavid du Colombier 		if (debug) print("bot,top %d, %d startup begins %d\n",bot,top,startup);
7413e12c5d1SDavid du Colombier # endif
7423e12c5d1SDavid du Colombier 		do {
7433e12c5d1SDavid du Colombier 			startup += 1;
7443e12c5d1SDavid du Colombier 			if(startup > outsize - NCH)
7453e12c5d1SDavid du Colombier 				error("output table overflow");
7463e12c5d1SDavid du Colombier 			for(j = bot; j<= top; j++){
7473e12c5d1SDavid du Colombier 				k = startup + nchar[j];
7483e12c5d1SDavid du Colombier 				if(verify[k])break;
7493e12c5d1SDavid du Colombier 			}
7503e12c5d1SDavid du Colombier 		} while (j <= top);
7513e12c5d1SDavid du Colombier 		/* have found place */
7523e12c5d1SDavid du Colombier # ifdef DEBUG
753219b2ee8SDavid du Colombier 		if (debug) print(" startup going to be %d\n", startup);
7543e12c5d1SDavid du Colombier # endif
7553e12c5d1SDavid du Colombier 		for(j = bot; j<= top; j++){
7563e12c5d1SDavid du Colombier 			k = startup + nchar[j];
7573e12c5d1SDavid du Colombier 			verify[k] = i+1;			/* state number + 1*/
7583e12c5d1SDavid du Colombier 			advance[k] = nexts[j+1]+1;		/* state number + 1*/
7593e12c5d1SDavid du Colombier 			if(yytop < k) yytop = k;
7603e12c5d1SDavid du Colombier 		}
7613e12c5d1SDavid du Colombier 		stoff[i] = startup;
7623e12c5d1SDavid du Colombier 	}
7633e12c5d1SDavid du Colombier 
7643e12c5d1SDavid du Colombier 	/* stoff[i] = offset into verify, advance for trans for state i */
7653e12c5d1SDavid du Colombier 	/* put out yywork */
766219b2ee8SDavid du Colombier 	Bprint(&fout,"# define YYTYPE %s\n",stnum+1 >= NCH ? "int" : "Uchar");
767219b2ee8SDavid du Colombier 	Bprint(&fout,"struct yywork { YYTYPE verify, advance; } yycrank[] = {\n");
7683e12c5d1SDavid du Colombier 	for(i=0;i<=yytop;i+=4){
7693e12c5d1SDavid du Colombier 		for(j=0;j<4;j++){
7703e12c5d1SDavid du Colombier 			k = i+j;
7713e12c5d1SDavid du Colombier 			if(verify[k])
772219b2ee8SDavid du Colombier 				Bprint(&fout,"%d,%d,\t",verify[k],advance[k]);
7733e12c5d1SDavid du Colombier 			else
774219b2ee8SDavid du Colombier 				Bprint(&fout,"0,0,\t");
7753e12c5d1SDavid du Colombier 		}
776219b2ee8SDavid du Colombier 		Bputc(&fout, '\n');
7773e12c5d1SDavid du Colombier 	}
778219b2ee8SDavid du Colombier 	Bprint(&fout,"0,0};\n");
7793e12c5d1SDavid du Colombier 
7803e12c5d1SDavid du Colombier 	/* put out yysvec */
7813e12c5d1SDavid du Colombier 
782219b2ee8SDavid du Colombier 	Bprint(&fout,"struct yysvf yysvec[] = {\n");
783219b2ee8SDavid du Colombier 	Bprint(&fout,"0,\t0,\t0,\n");
7843e12c5d1SDavid du Colombier 	for(i=0;i<=stnum;i++){	/* for each state */
7853e12c5d1SDavid du Colombier 		if(cpackflg[i])stoff[i] = -stoff[i];
786219b2ee8SDavid du Colombier 		Bprint(&fout,"yycrank+%d,\t",stoff[i]);
7873e12c5d1SDavid du Colombier 		if(sfall[i] != -1)
788219b2ee8SDavid du Colombier 			Bprint(&fout,"yysvec+%d,\t", sfall[i]+1);	/* state + 1 */
789219b2ee8SDavid du Colombier 		else Bprint(&fout,"0,\t\t");
7903e12c5d1SDavid du Colombier 		if(atable[i] != -1)
791219b2ee8SDavid du Colombier 			Bprint(&fout,"yyvstop+%d,",atable[i]);
792219b2ee8SDavid du Colombier 		else Bprint(&fout,"0,\t");
7933e12c5d1SDavid du Colombier # ifdef DEBUG
794219b2ee8SDavid du Colombier 		Bprint(&fout,"\t\t/* state %d */",i);
7953e12c5d1SDavid du Colombier # endif
796219b2ee8SDavid du Colombier 		Bputc(&fout, '\n');
7973e12c5d1SDavid du Colombier 	}
798219b2ee8SDavid du Colombier 	Bprint(&fout,"0,\t0,\t0};\n");
7993e12c5d1SDavid du Colombier 
8003e12c5d1SDavid du Colombier 	/* put out yymatch */
8013e12c5d1SDavid du Colombier 
802219b2ee8SDavid du Colombier 	Bprint(&fout,"struct yywork *yytop = yycrank+%d;\n",yytop);
803219b2ee8SDavid du Colombier 	Bprint(&fout,"struct yysvf *yybgin = yysvec+1;\n");
804219b2ee8SDavid du Colombier 	Bprint(&fout,"Uchar yymatch[] = {\n");
8053e12c5d1SDavid du Colombier 	for(i=0; i<NCH; i+=8){
8063e12c5d1SDavid du Colombier 		for(j=0; j<8; j++){
8073e12c5d1SDavid du Colombier 			int fbch;
8083e12c5d1SDavid du Colombier 			fbch = match[i+j];
8093e12c5d1SDavid du Colombier 			if(isprint(fbch) && fbch != '\'' && fbch != '\\')
810219b2ee8SDavid du Colombier 				Bprint(&fout,"'%c' ,",fbch);
811219b2ee8SDavid du Colombier 			else Bprint(&fout,"0%-3o,",fbch);
8123e12c5d1SDavid du Colombier 		}
813219b2ee8SDavid du Colombier 		Bputc(&fout, '\n');
8143e12c5d1SDavid du Colombier 	}
815219b2ee8SDavid du Colombier 	Bprint(&fout,"0};\n");
8163e12c5d1SDavid du Colombier 	/* put out yyextra */
817219b2ee8SDavid du Colombier 	Bprint(&fout,"Uchar yyextra[] = {\n");
8183e12c5d1SDavid du Colombier 	for(i=0;i<casecount;i+=8){
8193e12c5d1SDavid du Colombier 		for(j=0;j<8;j++)
820219b2ee8SDavid du Colombier 			Bprint(&fout, "%d,", i+j<NACTIONS ?
8213e12c5d1SDavid du Colombier 				extra[i+j] : 0);
822219b2ee8SDavid du Colombier 		Bputc(&fout, '\n');
8233e12c5d1SDavid du Colombier 	}
824219b2ee8SDavid du Colombier 	Bprint(&fout,"0};\n");
8253e12c5d1SDavid du Colombier }
8263e12c5d1SDavid du Colombier 
8273e12c5d1SDavid du Colombier # ifdef PP
8283e12c5d1SDavid du Colombier void
padd(int ** array,int n)8293e12c5d1SDavid du Colombier padd(int **array, int n)
8303e12c5d1SDavid du Colombier {
8313e12c5d1SDavid du Colombier 	int i, *j, k;
8323e12c5d1SDavid du Colombier 
8333e12c5d1SDavid du Colombier 	array[n] = nxtpos;
8343e12c5d1SDavid du Colombier 	if(count == 0){
8353e12c5d1SDavid du Colombier 		*nxtpos++ = 0;
8363e12c5d1SDavid du Colombier 		return;
8373e12c5d1SDavid du Colombier 	}
8383e12c5d1SDavid du Colombier 	for(i=tptr-1;i>=0;i--){
8393e12c5d1SDavid du Colombier 		j = array[i];
8403e12c5d1SDavid du Colombier 		if(j && *j++ == count){
8413e12c5d1SDavid du Colombier 			for(k=0;k<count;k++)
8423e12c5d1SDavid du Colombier 				if(!tmpstat[*j++])break;
8433e12c5d1SDavid du Colombier 			if(k >= count){
8443e12c5d1SDavid du Colombier 				array[n] = array[i];
8453e12c5d1SDavid du Colombier 				return;
8463e12c5d1SDavid du Colombier 			}
8473e12c5d1SDavid du Colombier 		}
8483e12c5d1SDavid du Colombier 	}
8493e12c5d1SDavid du Colombier 	add(array,n);
8503e12c5d1SDavid du Colombier }
8513e12c5d1SDavid du Colombier # endif
852