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