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