plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

sub2.c (17084B)


      1 # include "ldefs.h"
      2 void
      3 cfoll(int v)
      4 {
      5 	int i,j,k;
      6 	uchar *p;
      7 	i = name[v];
      8 	if(i < NCH) i = 1;	/* character */
      9 	switch(i){
     10 		case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:
     11 			for(j=0;j<tptr;j++)
     12 				tmpstat[j] = FALSE;
     13 			count = 0;
     14 			follow(v);
     15 # ifdef PP
     16 			padd(foll,v);		/* packing version */
     17 # endif
     18 # ifndef PP
     19 			add(foll,v);		/* no packing version */
     20 # endif
     21 			if(i == RSTR) cfoll(left[v]);
     22 			else if(i == RCCL || i == RNCCL){	/* compress ccl list */
     23 				for(j=1; j<NCH;j++)
     24 					symbol[j] = (i==RNCCL);
     25 				p = ptr[v];
     26 				while(*p)
     27 					symbol[*p++] = (i == RCCL);
     28 				p = pcptr;
     29 				for(j=1;j<NCH;j++)
     30 					if(symbol[j]){
     31 						for(k=0;p+k < pcptr; k++)
     32 							if(cindex[j] == *(p+k))
     33 								break;
     34 						if(p+k >= pcptr)*pcptr++ = cindex[j];
     35 					}
     36 				*pcptr++ = 0;
     37 				if(pcptr > pchar + pchlen)
     38 					error("Too many packed character classes");
     39 				ptr[v] = p;
     40 				name[v] = RCCL;	/* RNCCL eliminated */
     41 # ifdef DEBUG
     42 				if(debug && *p){
     43 					print("ccl %d: %d",v,*p++);
     44 					while(*p)
     45 						print(", %d",*p++);
     46 					print("\n");
     47 				}
     48 # endif
     49 			}
     50 			break;
     51 		case CARAT:
     52 			cfoll(left[v]);
     53 			break;
     54 		case STAR: case PLUS: case QUEST: case RSCON:
     55 			cfoll(left[v]);
     56 			break;
     57 		case BAR: case RCAT: case DIV: case RNEWE:
     58 			cfoll(left[v]);
     59 			cfoll(right[v]);
     60 			break;
     61 # ifdef DEBUG
     62 		case FINAL:
     63 		case S1FINAL:
     64 		case S2FINAL:
     65 			break;
     66 		default:
     67 			warning("bad switch cfoll %d",v);
     68 # endif
     69 	}
     70 }
     71 
     72 # ifdef DEBUG
     73 void
     74 pfoll(void)
     75 	{
     76 	int i,k,*p;
     77 	int j;
     78 	/* print sets of chars which may follow positions */
     79 	print("pos\tchars\n");
     80 	for(i=0;i<tptr;i++)
     81 		if(p=foll[i]){
     82 			j = *p++;
     83 			if(j >= 1){
     84 				print("%d:\t%d",i,*p++);
     85 				for(k=2;k<=j;k++)
     86 					print(", %d",*p++);
     87 				print("\n");
     88 			}
     89 		}
     90 }
     91 # endif
     92 
     93 void
     94 add(int **array, int n)
     95 {
     96 	int i, *temp;
     97 	uchar *ctemp;
     98 
     99 	temp = nxtpos;
    100 	ctemp = tmpstat;
    101 	array[n] = nxtpos;		/* note no packing is done in positions */
    102 	*temp++ = count;
    103 	for(i=0;i<tptr;i++)
    104 		if(ctemp[i] == TRUE)
    105 			*temp++ = i;
    106 	nxtpos = temp;
    107 	if(nxtpos >= positions+maxpos)
    108 		error("Too many positions %s",(maxpos== MAXPOS?"\nTry using %p num":""));
    109 	return;
    110 }
    111 
    112 void
    113 follow(int v)
    114 {
    115 	int p;
    116 	if(v >= tptr-1)return;
    117 	p = parent[v];
    118 	if(p == 0) return;
    119 	switch(name[p]){
    120 			/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
    121 		case RSTR:
    122 			if(tmpstat[p] == FALSE){
    123 				count++;
    124 				tmpstat[p] = TRUE;
    125 			}
    126 			break;
    127 		case STAR: case PLUS:
    128 			first(v);
    129 			follow(p);
    130 			break;
    131 		case BAR: case QUEST: case RNEWE:
    132 			follow(p);
    133 			break;
    134 		case RCAT: case DIV:
    135 			if(v == left[p]){
    136 				if(nullstr[right[p]])
    137 					follow(p);
    138 				first(right[p]);
    139 			}
    140 			else follow(p);
    141 			break;
    142 		case RSCON: case CARAT:
    143 			follow(p);
    144 			break;
    145 # ifdef DEBUG
    146 		default:
    147 			warning("bad switch follow %d",p);
    148 # endif
    149 	}
    150 }
    151 
    152 void
    153 first(int v)	/* calculate set of positions with v as root which can be active initially */
    154 {
    155 	int i;
    156 	uchar *p;
    157 	i = name[v];
    158 	if(i < NCH)i = 1;
    159 	switch(i){
    160 		case 1: case RCCL: case RNCCL: case RNULLS: case FINAL: case S1FINAL: case S2FINAL:
    161 			if(tmpstat[v] == FALSE){
    162 				count++;
    163 				tmpstat[v] = TRUE;
    164 			}
    165 			break;
    166 		case BAR: case RNEWE:
    167 			first(left[v]);
    168 			first(right[v]);
    169 			break;
    170 		case CARAT:
    171 			if(stnum % 2 == 1)
    172 				first(left[v]);
    173 			break;
    174 		case RSCON:
    175 			i = stnum/2 +1;
    176 			p = (uchar*)right[v];
    177 			while(*p)
    178 				if(*p++ == i){
    179 					first(left[v]);
    180 					break;
    181 				}
    182 			break;
    183 		case STAR: case QUEST: case PLUS:  case RSTR:
    184 			first(left[v]);
    185 			break;
    186 		case RCAT: case DIV:
    187 			first(left[v]);
    188 			if(nullstr[left[v]])
    189 				first(right[v]);
    190 			break;
    191 # ifdef DEBUG
    192 		default:
    193 			warning("bad switch first %d",v);
    194 # endif
    195 	}
    196 }
    197 
    198 void
    199 cgoto(void)
    200 {
    201 	int i, j, s;
    202 	int npos, curpos, n;
    203 	int tryit;
    204 	uchar tch[NCH];
    205 	int tst[NCH];
    206 	uchar *q;
    207 
    208 	/* generate initial state, for each start condition */
    209 	Bprint(&fout,"int yyvstop[] = {\n0,\n");
    210 	while(stnum < 2 || stnum/2 < sptr){
    211 		for(i = 0; i<tptr; i++) tmpstat[i] = 0;
    212 		count = 0;
    213 		if(tptr > 0)first(tptr-1);
    214 		add(state,stnum);
    215 # ifdef DEBUG
    216 		if(debug){
    217 			if(stnum > 1)
    218 				print("%s:\n",sname[stnum/2]);
    219 			pstate(stnum);
    220 		}
    221 # endif
    222 		stnum++;
    223 	}
    224 	stnum--;
    225 	/* even stnum = might not be at line begin */
    226 	/* odd stnum  = must be at line begin */
    227 	/* even states can occur anywhere, odd states only at line begin */
    228 	for(s = 0; s <= stnum; s++){
    229 		tryit = FALSE;
    230 		cpackflg[s] = FALSE;
    231 		sfall[s] = -1;
    232 		acompute(s);
    233 		for(i=0;i<NCH;i++) symbol[i] = 0;
    234 		npos = *state[s];
    235 		for(i = 1; i<=npos; i++){
    236 			curpos = *(state[s]+i);
    237 			if(name[curpos] < NCH) symbol[name[curpos]] = TRUE;
    238 			else switch(name[curpos]){
    239 			case RCCL:
    240 				tryit = TRUE;
    241 				q = ptr[curpos];
    242 				while(*q){
    243 					for(j=1;j<NCH;j++)
    244 						if(cindex[j] == *q)
    245 							symbol[j] = TRUE;
    246 					q++;
    247 				}
    248 				break;
    249 			case RSTR:
    250 				symbol[right[curpos]] = TRUE;
    251 				break;
    252 # ifdef DEBUG
    253 			case RNULLS:
    254 			case FINAL:
    255 			case S1FINAL:
    256 			case S2FINAL:
    257 				break;
    258 			default:
    259 				warning("bad switch cgoto %d state %d",curpos,s);
    260 				break;
    261 # endif
    262 			}
    263 		}
    264 # ifdef DEBUG
    265 		if(debug){
    266 			print("State %d transitions on:\n\t",s);
    267 			charc = 0;
    268 			for(i = 1; i<NCH; i++){
    269 				if(symbol[i]) allprint(i);
    270 				if(charc > LINESIZE){
    271 					charc = 0;
    272 					print("\n\t");
    273 				}
    274 			}
    275 			print("\n");
    276 		}
    277 # endif
    278 		/* for each char, calculate next state */
    279 		n = 0;
    280 		for(i = 1; i<NCH; i++){
    281 			if(symbol[i]){
    282 				nextstate(s,i);		/* executed for each state, transition pair */
    283 				xstate = notin(stnum);
    284 				if(xstate == -2) warning("bad state  %d %o",s,i);
    285 				else if(xstate == -1){
    286 					if(stnum >= nstates)
    287 						error("Too many states %s",(nstates == NSTATES ? "\nTry using %n num":""));
    288 					add(state,++stnum);
    289 # ifdef DEBUG
    290 					if(debug)pstate(stnum);
    291 # endif
    292 					tch[n] = i;
    293 					tst[n++] = stnum;
    294 				} else {		/* xstate >= 0 ==> state exists */
    295 					tch[n] = i;
    296 					tst[n++] = xstate;
    297 				}
    298 			}
    299 		}
    300 		tch[n] = 0;
    301 		tst[n] = -1;
    302 		/* pack transitions into permanent array */
    303 		if(n > 0) packtrans(s,tch,tst,n,tryit);
    304 		else gotof[s] = -1;
    305 	}
    306 	Bprint(&fout,"0};\n");
    307 }
    308 
    309 /*	Beware -- 70% of total CPU time is spent in this subroutine -
    310 	if you don't believe me - try it yourself ! */
    311 void
    312 nextstate(int s, int c)
    313 {
    314 	int j, *newpos;
    315 	uchar *temp, *tz;
    316 	int *pos, i, *f, num, curpos, number;
    317 	/* state to goto from state s on char c */
    318 	num = *state[s];
    319 	temp = tmpstat;
    320 	pos = state[s] + 1;
    321 	for(i = 0; i<num; i++){
    322 		curpos = *pos++;
    323 		j = name[curpos];
    324 		if(j < NCH && j == c
    325 		|| j == RSTR && c == right[curpos]
    326 		|| j == RCCL && member(c, ptr[curpos])){
    327 			f = foll[curpos];
    328 			number = *f;
    329 			newpos = f+1;
    330 			for(j=0;j<number;j++)
    331 				temp[*newpos++] = 2;
    332 		}
    333 	}
    334 	j = 0;
    335 	tz = temp + tptr;
    336 	while(temp < tz){
    337 		if(*temp == 2){
    338 			j++;
    339 			*temp++ = 1;
    340 		}
    341 		else *temp++ = 0;
    342 	}
    343 	count = j;
    344 }
    345 
    346 int
    347 notin(int n)
    348 {	/* see if tmpstat occurs previously */
    349 	int *j,k;
    350 	uchar *temp;
    351 	int i;
    352 
    353 	if(count == 0)
    354 		return(-2);
    355 	temp = tmpstat;
    356 	for(i=n;i>=0;i--){	/* for each state */
    357 		j = state[i];
    358 		if(count == *j++){
    359 			for(k=0;k<count;k++)
    360 				if(!temp[*j++])break;
    361 			if(k >= count)
    362 				return(i);
    363 		}
    364 	}
    365 	return(-1);
    366 }
    367 
    368 void
    369 packtrans(int st, uchar *tch, int *tst, int cnt, int tryit)
    370 {
    371 	/* pack transitions into nchar, nexts */
    372 	/* nchar is terminated by '\0', nexts uses cnt, followed by elements */
    373 	/* gotof[st] = index into nchr, nexts for state st */
    374 
    375 	/* sfall[st] =  t implies t is fall back state for st */
    376 	/*	        == -1 implies no fall back */
    377 
    378 	int i,j,k;
    379 	int cmin, cval, tcnt, diff, p, *ast;
    380 	uchar *ach;
    381 	int go[NCH], temp[NCH], c;
    382 	int swork[NCH];
    383 	uchar cwork[NCH];
    384 	int upper;
    385 
    386 	rcount += cnt;
    387 	cmin = -1;
    388 	cval = NCH;
    389 	ast = tst;
    390 	ach = tch;
    391 	/* try to pack transitions using ccl's */
    392 	if(tryit){	/* ccl's used */
    393 		for(i=1;i<NCH;i++){
    394 			go[i] = temp[i] = -1;
    395 			symbol[i] = 1;
    396 		}
    397 		for(i=0;i<cnt;i++){
    398 			go[tch[i]] = tst[i];
    399 			symbol[tch[i]] = 0;
    400 		}
    401 		for(i=0; i<cnt;i++){
    402 			c = match[tch[i]];
    403 			if(go[c] != tst[i] || c == tch[i])
    404 				temp[tch[i]] = tst[i];
    405 		}
    406 		/* fill in error entries */
    407 		for(i=1;i<NCH;i++)
    408 			if(symbol[i]) temp[i] = -2;	/* error trans */
    409 		/* count them */
    410 		k = 0;
    411 		for(i=1;i<NCH;i++)
    412 			if(temp[i] != -1)k++;
    413 		if(k <cnt){	/* compress by char */
    414 # ifdef DEBUG
    415 			if(debug) print("use compression  %d,  %d vs %d\n",st,k,cnt);
    416 # endif
    417 			k = 0;
    418 			for(i=1;i<NCH;i++)
    419 				if(temp[i] != -1){
    420 					cwork[k] = i;
    421 					swork[k++] = (temp[i] == -2 ? -1 : temp[i]);
    422 				}
    423 			cwork[k] = 0;
    424 # ifdef PC
    425 			ach = cwork;
    426 			ast = swork;
    427 			cnt = k;
    428 			cpackflg[st] = TRUE;
    429 # endif
    430 		}
    431 	}
    432 	for(i=0; i<st; i++){	/* get most similar state */
    433 				/* reject state with more transitions, state already represented by a third state,
    434 					and state which is compressed by char if ours is not to be */
    435 		if(sfall[i] != -1) continue;
    436 		if(cpackflg[st] == 1) if(!(cpackflg[i] == 1)) continue;
    437 		p = gotof[i];
    438 		if(p == -1) /* no transitions */ continue;
    439 		tcnt = nexts[p];
    440 		if(tcnt > cnt) continue;
    441 		diff = 0;
    442 		j = 0;
    443 		upper = p + tcnt;
    444 		while(ach[j] && p < upper){
    445 			while(ach[j] < nchar[p] && ach[j]){diff++; j++; }
    446 			if(ach[j] == 0)break;
    447 			if(ach[j] > nchar[p]){diff=NCH;break;}
    448 			/* ach[j] == nchar[p] */
    449 			if(ast[j] != nexts[++p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]]))diff++;
    450 			j++;
    451 		}
    452 		while(ach[j]){
    453 			diff++;
    454 			j++;
    455 		}
    456 		if(p < upper)diff = NCH;
    457 		if(diff < cval && diff < tcnt){
    458 			cval = diff;
    459 			cmin = i;
    460 			if(cval == 0)break;
    461 		}
    462 	}
    463 	/* cmin = state "most like" state st */
    464 # ifdef DEBUG
    465 	if(debug)print("select st %d for st %d diff %d\n",cmin,st,cval);
    466 # endif
    467 # ifdef PS
    468 	if(cmin != -1){ /* if we can use st cmin */
    469 		gotof[st] = nptr;
    470 		k = 0;
    471 		sfall[st] = cmin;
    472 		p = gotof[cmin]+1;
    473 		j = 0;
    474 		while(ach[j]){
    475 			/* if cmin has a transition on c, then so will st */
    476 			/* st may be "larger" than cmin, however */
    477 			while(ach[j] < nchar[p-1] && ach[j]){
    478 				k++;
    479 				nchar[nptr] = ach[j];
    480 				nexts[++nptr] = ast[j];
    481 				j++;
    482 			}
    483 			if(nchar[p-1] == 0)break;
    484 			if(ach[j] > nchar[p-1]){
    485 				warning("bad transition %d %d",st,cmin);
    486 				goto nopack;
    487 			}
    488 			/* ach[j] == nchar[p-1] */
    489 			if(ast[j] != nexts[p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]])){
    490 				k++;
    491 				nchar[nptr] = ach[j];
    492 				nexts[++nptr] = ast[j];
    493 			}
    494 			p++;
    495 			j++;
    496 		}
    497 		while(ach[j]){
    498 			nchar[nptr] = ach[j];
    499 			nexts[++nptr] = ast[j++];
    500 			k++;
    501 		}
    502 		nexts[gotof[st]] = cnt = k;
    503 		nchar[nptr++] = 0;
    504 	} else {
    505 # endif
    506 nopack:
    507 	/* stick it in */
    508 		gotof[st] = nptr;
    509 		nexts[nptr] = cnt;
    510 		for(i=0;i<cnt;i++){
    511 			nchar[nptr] = ach[i];
    512 			nexts[++nptr] = ast[i];
    513 		}
    514 		nchar[nptr++] = 0;
    515 # ifdef PS
    516 	}
    517 # endif
    518 	if(cnt < 1){
    519 		gotof[st] = -1;
    520 		nptr--;
    521 	} else
    522 		if(nptr > ntrans)
    523 			error("Too many transitions %s",(ntrans==NTRANS?"\nTry using %a num":""));
    524 }
    525 
    526 # ifdef DEBUG
    527 void
    528 pstate(int s)
    529 {
    530 	int *p,i,j;
    531 	print("State %d:\n",s);
    532 	p = state[s];
    533 	i = *p++;
    534 	if(i == 0) return;
    535 	print("%4d",*p++);
    536 	for(j = 1; j<i; j++){
    537 		print(", %4d",*p++);
    538 		if(j%30 == 0)print("\n");
    539 	}
    540 	print("\n");
    541 	return;
    542 }
    543 # endif
    544 
    545 int
    546 member(int d, uchar *t)
    547 {
    548 	int c;
    549 	uchar *s;
    550 
    551 	c = d;
    552 	s = t;
    553 	c = cindex[c];
    554 	while(*s)
    555 		if(*s++ == c) return(1);
    556 	return(0);
    557 }
    558 
    559 # ifdef DEBUG
    560 void
    561 stprt(int i)
    562 {
    563 	int p, t;
    564 
    565 	print("State %d:",i);
    566 	/* print actions, if any */
    567 	t = atable[i];
    568 	if(t != -1)print(" final");
    569 	print("\n");
    570 	if(cpackflg[i] == TRUE)print("backup char in use\n");
    571 	if(sfall[i] != -1)print("fall back state %d\n",sfall[i]);
    572 	p = gotof[i];
    573 	if(p == -1) return;
    574 	print("(%d transitions)\n",nexts[p]);
    575 	while(nchar[p]){
    576 		charc = 0;
    577 		if(nexts[p+1] >= 0)
    578 			print("%d\t",nexts[p+1]);
    579 		else print("err\t");
    580 		allprint(nchar[p++]);
    581 		while(nexts[p] == nexts[p+1] && nchar[p]){
    582 			if(charc > LINESIZE){
    583 				charc = 0;
    584 				print("\n\t");
    585 			}
    586 			allprint(nchar[p++]);
    587 		}
    588 		print("\n");
    589 	}
    590 	print("\n");
    591 }
    592 # endif
    593 
    594 void
    595 acompute(int s)	/* compute action list = set of poss. actions */
    596 {
    597 	int *p, i, j;
    598 	int cnt, m;
    599 	int temp[300], k, neg[300], n;
    600 
    601 	k = 0;
    602 	n = 0;
    603 	p = state[s];
    604 	cnt = *p++;
    605 	if(cnt > 300)
    606 		error("Too many positions for one state - acompute");
    607 	for(i=0;i<cnt;i++){
    608 		if(name[*p] == FINAL)temp[k++] = left[*p];
    609 		else if(name[*p] == S1FINAL){temp[k++] = left[*p];
    610 			if (left[*p] >= NACTIONS) error("Too many right contexts");
    611 			extra[left[*p]] = 1;
    612 		} else if(name[*p] == S2FINAL)neg[n++] = left[*p];
    613 		p++;
    614 	}
    615 	atable[s] = -1;
    616 	if(k < 1 && n < 1) return;
    617 # ifdef DEBUG
    618 	if(debug) print("final %d actions:",s);
    619 # endif
    620 	/* sort action list */
    621 	for(i=0; i<k; i++)
    622 		for(j=i+1;j<k;j++)
    623 			if(temp[j] < temp[i]){
    624 				m = temp[j];
    625 				temp[j] = temp[i];
    626 				temp[i] = m;
    627 			}
    628 	/* remove dups */
    629 	for(i=0;i<k-1;i++)
    630 		if(temp[i] == temp[i+1]) temp[i] = 0;
    631 	/* copy to permanent quarters */
    632 	atable[s] = aptr;
    633 # ifdef DEBUG
    634 	Bprint(&fout,"/* actions for state %d */",s);
    635 # endif
    636 	Bputc(&fout, '\n');
    637 	for(i=0;i<k;i++)
    638 		if(temp[i] != 0){
    639 			Bprint(&fout,"%d,\n",temp[i]);
    640 # ifdef DEBUG
    641 			if(debug)
    642 				print("%d ",temp[i]);
    643 # endif
    644 			aptr++;
    645 		}
    646 	for(i=0;i<n;i++){		/* copy fall back actions - all neg */
    647 		Bprint(&fout,"%d,\n",neg[i]);
    648 		aptr++;
    649 # ifdef DEBUG
    650 		if(debug)print("%d ",neg[i]);
    651 # endif
    652 	}
    653 # ifdef DEBUG
    654 	if(debug)print("\n");
    655 # endif
    656 	Bprint(&fout,"0,\n");
    657 	aptr++;
    658 	return;
    659 }
    660 
    661 # ifdef DEBUG
    662 void
    663 pccl(void) {
    664 	/* print character class sets */
    665 	int i, j;
    666 
    667 	print("char class intersection\n");
    668 	for(i=0; i< ccount; i++){
    669 		charc = 0;
    670 		print("class %d:\n\t",i);
    671 		for(j=1;j<NCH;j++)
    672 			if(cindex[j] == i){
    673 				allprint(j);
    674 				if(charc > LINESIZE){
    675 					print("\n\t");
    676 					charc = 0;
    677 				}
    678 			}
    679 		print("\n");
    680 	}
    681 	charc = 0;
    682 	print("match:\n");
    683 	for(i=0;i<NCH;i++){
    684 		allprint(match[i]);
    685 		if(charc > LINESIZE){
    686 			print("\n");
    687 			charc = 0;
    688 		}
    689 	}
    690 	print("\n");
    691 	return;
    692 }
    693 # endif
    694 
    695 void
    696 mkmatch(void)
    697 {
    698 	int i;
    699 	uchar tab[NCH];
    700 
    701 	for(i=0; i<ccount; i++)
    702 		tab[i] = 0;
    703 	for(i=1;i<NCH;i++)
    704 		if(tab[cindex[i]] == 0)
    705 			tab[cindex[i]] = i;
    706 	/* tab[i] = principal char for new ccl i */
    707 	for(i = 1; i<NCH; i++)
    708 		match[i] = tab[cindex[i]];
    709 	return;
    710 }
    711 
    712 void
    713 layout(void)
    714 {
    715 	/* format and output final program's tables */
    716 	int i, j, k;
    717 	int  top, bot, startup, omin;
    718 
    719 	for(i=0; i<outsize;i++)
    720 		verify[i] = advance[i] = 0;
    721 	omin = 0;
    722 	yytop = 0;
    723 	for(i=0; i<= stnum; i++){	/* for each state */
    724 		j = gotof[i];
    725 		if(j == -1){
    726 			stoff[i] = 0;
    727 			continue;
    728 			}
    729 		bot = j;
    730 		while(nchar[j])j++;
    731 		top = j - 1;
    732 # ifdef DEBUG
    733 		if (debug) {
    734 			print("State %d: (layout)\n", i);
    735 			for(j=bot; j<=top;j++) {
    736 				print("  %o", nchar[j]);
    737 				if (j%10==0) print("\n");
    738 			}
    739 			print("\n");
    740 		}
    741 # endif
    742 		while(verify[omin+NCH]) omin++;
    743 		startup = omin;
    744 # ifdef DEBUG
    745 		if (debug) print("bot,top %d, %d startup begins %d\n",bot,top,startup);
    746 # endif
    747 		do {
    748 			startup += 1;
    749 			if(startup > outsize - NCH)
    750 				error("output table overflow");
    751 			for(j = bot; j<= top; j++){
    752 				k = startup + nchar[j];
    753 				if(verify[k])break;
    754 			}
    755 		} while (j <= top);
    756 		/* have found place */
    757 # ifdef DEBUG
    758 		if (debug) print(" startup going to be %d\n", startup);
    759 # endif
    760 		for(j = bot; j<= top; j++){
    761 			k = startup + nchar[j];
    762 			verify[k] = i+1;			/* state number + 1*/
    763 			advance[k] = nexts[j+1]+1;		/* state number + 1*/
    764 			if(yytop < k) yytop = k;
    765 		}
    766 		stoff[i] = startup;
    767 	}
    768 
    769 	/* stoff[i] = offset into verify, advance for trans for state i */
    770 	/* put out yywork */
    771 	Bprint(&fout,"# define YYTYPE %s\n",stnum+1 >= NCH ? "int" : "Uchar");
    772 	Bprint(&fout,"struct yywork { YYTYPE verify, advance; } yycrank[] = {\n");
    773 	for(i=0;i<=yytop;i+=4){
    774 		for(j=0;j<4;j++){
    775 			k = i+j;
    776 			if(verify[k])
    777 				Bprint(&fout,"%d,%d,\t",verify[k],advance[k]);
    778 			else
    779 				Bprint(&fout,"0,0,\t");
    780 		}
    781 		Bputc(&fout, '\n');
    782 	}
    783 	Bprint(&fout,"0,0};\n");
    784 
    785 	/* put out yysvec */
    786 
    787 	Bprint(&fout,"struct yysvf yysvec[] = {\n");
    788 	Bprint(&fout,"0,\t0,\t0,\n");
    789 	for(i=0;i<=stnum;i++){	/* for each state */
    790 		if(cpackflg[i])stoff[i] = -stoff[i];
    791 		Bprint(&fout,"yycrank+%d,\t",stoff[i]);
    792 		if(sfall[i] != -1)
    793 			Bprint(&fout,"yysvec+%d,\t", sfall[i]+1);	/* state + 1 */
    794 		else Bprint(&fout,"0,\t\t");
    795 		if(atable[i] != -1)
    796 			Bprint(&fout,"yyvstop+%d,",atable[i]);
    797 		else Bprint(&fout,"0,\t");
    798 # ifdef DEBUG
    799 		Bprint(&fout,"\t\t/* state %d */",i);
    800 # endif
    801 		Bputc(&fout, '\n');
    802 	}
    803 	Bprint(&fout,"0,\t0,\t0};\n");
    804 
    805 	/* put out yymatch */
    806 
    807 	Bprint(&fout,"struct yywork *yytop = yycrank+%d;\n",yytop);
    808 	Bprint(&fout,"struct yysvf *yybgin = yysvec+1;\n");
    809 	Bprint(&fout,"Uchar yymatch[] = {\n");
    810 	for(i=0; i<NCH; i+=8){
    811 		for(j=0; j<8; j++){
    812 			int fbch;
    813 			fbch = match[i+j];
    814 			if(isprint(fbch) && fbch != '\'' && fbch != '\\')
    815 				Bprint(&fout,"'%c' ,",fbch);
    816 			else Bprint(&fout,"0%-3o,",fbch);
    817 		}
    818 		Bputc(&fout, '\n');
    819 	}
    820 	Bprint(&fout,"0};\n");
    821 	/* put out yyextra */
    822 	Bprint(&fout,"Uchar yyextra[] = {\n");
    823 	for(i=0;i<casecount;i+=8){
    824 		for(j=0;j<8;j++)
    825 			Bprint(&fout, "%d,", i+j<NACTIONS ?
    826 				extra[i+j] : 0);
    827 		Bputc(&fout, '\n');
    828 	}
    829 	Bprint(&fout,"0};\n");
    830 }
    831 
    832 # ifdef PP
    833 void
    834 padd(int **array, int n)
    835 {
    836 	int i, *j, k;
    837 
    838 	array[n] = nxtpos;
    839 	if(count == 0){
    840 		*nxtpos++ = 0;
    841 		return;
    842 	}
    843 	for(i=tptr-1;i>=0;i--){
    844 		j = array[i];
    845 		if(j && *j++ == count){
    846 			for(k=0;k<count;k++)
    847 				if(!tmpstat[*j++])break;
    848 			if(k >= count){
    849 				array[n] = array[i];
    850 				return;
    851 			}
    852 		}
    853 	}
    854 	add(array,n);
    855 }
    856 # endif