URI:
       tsub2.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tsub2.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