+# include "ldefs.c"
+cfoll(v)
+ int v;
+ {
+ register int i,j,k;
+ char *p;
+ i = name[v];
+ if(i < NCH) i = 1; /* character */
+ switch(i){
+ case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:
+ for(j=0;j<tptr;j++)
+ tmpstat[j] = FALSE;
+ count = 0;
+ follow(v);
+# ifdef PP
+ padd(foll,v); /* packing version */
+# endif
+# ifndef PP
+ add(foll,v); /* no packing version */
+# endif
+ if(i == RSTR) cfoll(left[v]);
+ else if(i == RCCL || i == RNCCL){ /* compress ccl list */
+ for(j=1; j<NCH;j++)
+ symbol[j] = (i==RNCCL);
+ p = left[v];
+ while(*p)
+ symbol[*p++] = (i == RCCL);
+ p = pcptr;
+ for(j=1;j<NCH;j++)
+ if(symbol[j]){
+ for(k=0;p+k < pcptr; k++)
+ if(cindex[j] == *(p+k))
+ break;
+ if(p+k >= pcptr)*pcptr++ = cindex[j];
+ }
+ *pcptr++ = 0;
+ if(pcptr > pchar + pchlen)
+ error("Too many packed character classes");
+ left[v] = p;
+ name[v] = RCCL; /* RNCCL eliminated */
+# ifdef DEBUG
+ if(debug && *p){
+ printf("ccl %d: %d",v,*p++);
+ while(*p)
+ printf(", %d",*p++);
+ putchar('\n');
+ }
+# endif
+ }
+ break;
+ case CARAT:
+ cfoll(left[v]);
+ break;
+ case STAR: case PLUS: case QUEST: case RSCON:
+ cfoll(left[v]);
+ break;
+ case BAR: case RCAT: case DIV: case RNEWE:
+ cfoll(left[v]);
+ cfoll(right[v]);
+ break;
+# ifdef DEBUG
+ case FINAL:
+ case S1FINAL:
+ case S2FINAL:
+ break;
+ default:
+ warning("bad switch cfoll %d",v);
+# endif
+ }
+ return;
+ }
+# ifdef DEBUG
+pfoll()
+ {
+ register int i,k,*p;
+ int j;
+ /* print sets of chars which may follow positions */
+ printf("pos\tchars\n");
+ for(i=0;i<tptr;i++)
+ if(p=foll[i]){
+ j = *p++;
+ if(j >= 1){
+ printf("%d:\t%d",i,*p++);
+ for(k=2;k<=j;k++)
+ printf(", %d",*p++);
+ putchar('\n');
+ }
+ }
+ return;
+ }
+# endif
+add(array,n)
+ int **array;
+ int n; {
+ register int i, *temp;
+ register char *ctemp;
+ temp = nxtpos;
+ ctemp = tmpstat;
+ array[n] = nxtpos; /* note no packing is done in positions */
+ *temp++ = count;
+ for(i=0;i<tptr;i++)
+ if(ctemp[i] == TRUE)
+ *temp++ = i;
+ nxtpos = temp;
+ if(nxtpos >= positions+maxpos)
+ error("Too many positions %s",(maxpos== MAXPOS?"\nTry using %p num":""));
+ return;
+ }
+follow(v)
+ int v;
+ {
+ register int p;
+ if(v >= tptr-1)return;
+ p = parent[v];
+ if(p == 0) return;
+ switch(name[p]){
+ /* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
+ case RSTR:
+ if(tmpstat[p] == FALSE){
+ count++;
+ tmpstat[p] = TRUE;
+ }
+ break;
+ case STAR: case PLUS:
+ first(v);
+ follow(p);
+ break;
+ case BAR: case QUEST: case RNEWE:
+ follow(p);
+ break;
+ case RCAT: case DIV:
+ if(v == left[p]){
+ if(nullstr[right[p]])
+ follow(p);
+ first(right[p]);
+ }
+ else follow(p);
+ break;
+ case RSCON: case CARAT:
+ follow(p);
+ break;
+# ifdef DEBUG
+ default:
+ warning("bad switch follow %d",p);
+# endif
+ }
+ return;
+ }
+first(v) /* calculate set of positions with v as root which can be active initially */
+ int v; {
+ register int i;
+ register char *p;
+ i = name[v];
+ if(i < NCH)i = 1;
+ switch(i){
+ case 1: case RCCL: case RNCCL: case RNULLS: case FINAL: case S1FINAL: case S2FINAL:
+ if(tmpstat[v] == FALSE){
+ count++;
+ tmpstat[v] = TRUE;
+ }
+ break;
+ case BAR: case RNEWE:
+ first(left[v]);
+ first(right[v]);
+ break;
+ case CARAT:
+ if(stnum % 2 == 1)
+ first(left[v]);
+ break;
+ case RSCON:
+ i = stnum/2 +1;
+ p = right[v];
+ while(*p)
+ if(*p++ == i){
+ first(left[v]);
+ break;
+ }
+ break;
+ case STAR: case QUEST: case PLUS: case RSTR:
+ first(left[v]);
+ break;
+ case RCAT: case DIV:
+ first(left[v]);
+ if(nullstr[left[v]])
+ first(right[v]);
+ break;
+# ifdef DEBUG
+ default:
+ warning("bad switch first %d",v);
+# endif
+ }
+ return;
+ }
+cgoto(){
+ register int i, j, s;
+ int npos, curpos, n;
+ int tryit;
+ char tch[NCH];
+ int tst[NCH];
+ char *q;
+ /* generate initial state, for each start condition */
+ if(ratfor){
+ fprintf(fout,"blockdata\n");
+ fprintf(fout,"common /Lvstop/ vstop\n");
+ fprintf(fout,"define Svstop %d\n",nstates+1);
+ fprintf(fout,"integer vstop(Svstop)\n");
+ }
+ else fprintf(fout,"int yyvstop[] ={\n0,\n");
+ while(stnum < 2 || stnum/2 < sptr){
+ for(i = 0; i<tptr; i++) tmpstat[i] = 0;
+ count = 0;
+ if(tptr > 0)first(tptr-1);
+ add(state,stnum);
+# ifdef DEBUG
+ if(debug){
+ if(stnum > 1)
+ printf("%s:\n",sname[stnum/2]);
+ pstate(stnum);
+ }
+# endif
+ stnum++;
+ }
+ stnum--;
+ /* even stnum = might not be at line begin */
+ /* odd stnum = must be at line begin */
+ /* even states can occur anywhere, odd states only at line begin */
+ for(s = 0; s <= stnum; s++){
+ tryit = FALSE;
+ cpackflg[s] = FALSE;
+ sfall[s] = -1;
+ acompute(s);
+ for(i=0;i<NCH;i++) symbol[i] = 0;
+ npos = *state[s];
+ for(i = 1; i<=npos; i++){
+ curpos = *(state[s]+i);
+ if(name[curpos] < NCH) symbol[name[curpos]] = TRUE;
+ else switch(name[curpos]){
+ case RCCL:
+ tryit = TRUE;
+ q = left[curpos];
+ while(*q){
+ for(j=1;j<NCH;j++)
+ if(cindex[j] == *q)
+ symbol[j] = TRUE;
+ q++;
+ }
+ break;
+ case RSTR:
+ symbol[right[curpos]] = TRUE;
+ break;
+# ifdef DEBUG
+ case RNULLS:
+ case FINAL:
+ case S1FINAL:
+ case S2FINAL:
+ break;
+ default:
+ warning("bad switch cgoto %d state %d",curpos,s);
+ break;
+# endif
+ }
+ }
+# ifdef DEBUG
+ if(debug){
+ printf("State %d transitions on:\n\t",s);
+ charc = 0;
+ for(i = 1; i<NCH; i++){
+ if(symbol[i]) allprint(i);
+ if(charc > LINESIZE){
+ charc = 0;
+ printf("\n\t");
+ }
+ }
+ putchar('\n');
+ }
+# endif
+ /* for each char, calculate next state */
+ n = 0;
+ for(i = 1; i<NCH; i++){
+ if(symbol[i]){
+ nextstate(s,i); /* executed for each state, transition pair */
+ xstate = notin(stnum);
+ if(xstate == -2) warning("bad state %d %o",s,i);
+ else if(xstate == -1){
+ if(stnum >= nstates)
+ error("Too many states %s",(nstates == NSTATES ? "\nTry using %n num":""));
+ add(state,++stnum);
+# ifdef DEBUG
+ if(debug)pstate(stnum);
+# endif
+ tch[n] = i;
+ tst[n++] = stnum;
+ }
+ else { /* xstate >= 0 ==> state exists */
+ tch[n] = i;
+ tst[n++] = xstate;
+ }
+ }
+ }
+ tch[n] = 0;
+ tst[n] = -1;
+ /* pack transitions into permanent array */
+ if(n > 0) packtrans(s,tch,tst,n,tryit);
+ else gotof[s] = -1;
+ }
+ ratfor ? fprintf(fout,"end\n") : fprintf(fout,"0};\n");
+ return;
+ }
+ /* Beware -- 70% of total CPU time is spent in this subroutine -
+ if you don't believe me - try it yourself ! */
+nextstate(s,c)
+ int s,c; {
+ register int j, *newpos;
+ register char *temp, *tz;
+ int *pos, i, *f, num, curpos, number;
+ /* state to goto from state s on char c */
+ num = *state[s];
+ temp = tmpstat;
+ pos = state[s] + 1;
+ for(i = 0; i<num; i++){
+ curpos = *pos++;
+ j = name[curpos];
+ if(j < NCH && j == c
+ || j == RSTR && c == right[curpos]
+ || j == RCCL && member(c,left[curpos])){
+ f = foll[curpos];
+ number = *f;
+ newpos = f+1;
+ for(j=0;j<number;j++)
+ temp[*newpos++] = 2;
+ }
+ }
+ j = 0;
+ tz = temp + tptr;
+ while(temp < tz){
+ if(*temp == 2){
+ j++;
+ *temp++ = 1;
+ }
+ else *temp++ = 0;
+ }
+ count = j;
+ return;
+ }
+notin(n)
+ int n; { /* see if tmpstat occurs previously */
+ register int *j,k;
+ register char *temp;
+ int i;
+ if(count == 0)
+ return(-2);
+ temp = tmpstat;
+ for(i=n;i>=0;i--){ /* for each state */
+ j = state[i];
+ if(count == *j++){
+ for(k=0;k<count;k++)
+ if(!temp[*j++])break;
+ if(k >= count)
+ return(i);
+ }
+ }
+ return(-1);
+ }
+packtrans(st,tch,tst,cnt,tryit)
+ int st, *tst, cnt,tryit;
+ char *tch; {
+ /* pack transitions into nchar, nexts */
+ /* nchar is terminated by '\0', nexts uses cnt, followed by elements */
+ /* gotof[st] = index into nchr, nexts for state st */
+
+ /* sfall[st] = t implies t is fall back state for st */
+ /* == -1 implies no fall back */
+
+ int cmin, cval, tcnt, diff, p, *ast;
+ register int i,j,k;
+ char *ach;
+ int go[NCH], temp[NCH], c;
+ int swork[NCH];
+ char cwork[NCH];
+ int upper;
+
+ rcount += cnt;
+ cmin = -1;
+ cval = NCH;
+ ast = tst;
+ ach = tch;
+ /* try to pack transitions using ccl's */
+ if(!optim)goto nopack; /* skip all compaction */
+ if(tryit){ /* ccl's used */
+ for(i=1;i<NCH;i++){
+ go[i] = temp[i] = -1;
+ symbol[i] = 1;
+ }
+ for(i=0;i<cnt;i++){
+ go[tch[i]] = tst[i];
+ symbol[tch[i]] = 0;
+ }
+ for(i=0; i<cnt;i++){
+ c = match[tch[i]];
+ if(go[c] != tst[i] || c == tch[i])
+ temp[tch[i]] = tst[i];
+ }
+ /* fill in error entries */
+ for(i=1;i<NCH;i++)
+ if(symbol[i]) temp[i] = -2; /* error trans */
+ /* count them */
+ k = 0;
+ for(i=1;i<NCH;i++)
+ if(temp[i] != -1)k++;
+ if(k <cnt){ /* compress by char */
+# ifdef DEBUG
+ if(debug) printf("use compression %d, %d vs %d\n",st,k,cnt);
+# endif
+ k = 0;
+ for(i=1;i<NCH;i++)
+ if(temp[i] != -1){
+ cwork[k] = i;
+ swork[k++] = (temp[i] == -2 ? -1 : temp[i]);
+ }
+ cwork[k] = 0;
+# ifdef PC
+ ach = cwork;
+ ast = swork;
+ cnt = k;
+ cpackflg[st] = TRUE;
+# endif
+ }
+ }
+ for(i=0; i<st; i++){ /* get most similar state */
+ /* reject state with more transitions, state already represented by a third state,
+ and state which is compressed by char if ours is not to be */
+ if(sfall[i] != -1) continue;
+ if(cpackflg[st] == 1) if(!(cpackflg[i] == 1)) continue;
+ p = gotof[i];
+ if(p == -1) /* no transitions */ continue;
+ tcnt = nexts[p];
+ if(tcnt > cnt) continue;
+ diff = 0;
+ k = 0;
+ j = 0;
+ upper = p + tcnt;
+ while(ach[j] && p < upper){
+ while(ach[j] < nchar[p] && ach[j]){diff++; j++; }
+ if(ach[j] == 0)break;
+ if(ach[j] > nchar[p]){diff=NCH;break;}
+ /* ach[j] == nchar[p] */
+ if(ast[j] != nexts[++p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]]))diff++;
+ j++;
+ }
+ while(ach[j]){
+ diff++;
+ j++;
+ }
+ if(p < upper)diff = NCH;
+ if(diff < cval && diff < tcnt){
+ cval = diff;
+ cmin = i;
+ if(cval == 0)break;
+ }
+ }
+ /* cmin = state "most like" state st */
+# ifdef DEBUG
+ if(debug)printf("select st %d for st %d diff %d\n",cmin,st,cval);
+# endif
+# ifdef PS
+ if(cmin != -1){ /* if we can use st cmin */
+ gotof[st] = nptr;
+ k = 0;
+ sfall[st] = cmin;
+ p = gotof[cmin]+1;
+ j = 0;
+ while(ach[j]){
+ /* if cmin has a transition on c, then so will st */
+ /* st may be "larger" than cmin, however */
+ while(ach[j] < nchar[p-1] && ach[j]){
+ k++;
+ nchar[nptr] = ach[j];
+ nexts[++nptr] = ast[j];
+ j++;
+ }
+ if(nchar[p-1] == 0)break;
+ if(ach[j] > nchar[p-1]){
+ warning("bad transition %d %d",st,cmin);
+ goto nopack;
+ }
+ /* ach[j] == nchar[p-1] */
+ if(ast[j] != nexts[p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]])){
+ k++;
+ nchar[nptr] = ach[j];
+ nexts[++nptr] = ast[j];
+ }
+ p++;
+ j++;
+ }
+ while(ach[j]){
+ nchar[nptr] = ach[j];
+ nexts[++nptr] = ast[j++];
+ k++;
+ }
+ nexts[gotof[st]] = cnt = k;
+ nchar[nptr++] = 0;
+ }
+ else {
+# endif
+nopack:
+ /* stick it in */
+ gotof[st] = nptr;
+ nexts[nptr] = cnt;
+ for(i=0;i<cnt;i++){
+ nchar[nptr] = ach[i];
+ nexts[++nptr] = ast[i];
+ }
+ nchar[nptr++] = 0;
+# ifdef PS
+ }
+# endif
+ if(cnt < 1){
+ gotof[st] = -1;
+ nptr--;
+ }
+ else
+ if(nptr > ntrans)
+ error("Too many transitions %s",(ntrans==NTRANS?"\nTry using %a num":""));
+ return;
+ }
+# ifdef DEBUG
+pstate(s)
+ int s; {
+ register int *p,i,j;
+ printf("State %d:\n",s);
+ p = state[s];
+ i = *p++;
+ if(i == 0) return;
+ printf("%4d",*p++);
+ for(j = 1; j<i; j++){
+ printf(", %4d",*p++);
+ if(j%30 == 0)putchar('\n');
+ }
+ putchar('\n');
+ return;
+ }
+# endif
+member(d,t)
+ int d;
+ char *t; {
+ register int c;
+ register char *s;
+ c = d;
+ s = t;
+ c = cindex[c];
+ while(*s)
+ if(*s++ == c) return(1);
+ return(0);
+ }
+# ifdef DEBUG
+stprt(i)
+ int i; {
+ register int p, t;
+ printf("State %d:",i);
+ /* print actions, if any */
+ t = atable[i];
+ if(t != -1)printf(" final");
+ putchar('\n');
+ if(cpackflg[i] == TRUE)printf("backup char in use\n");
+ if(sfall[i] != -1)printf("fall back state %d\n",sfall[i]);
+ p = gotof[i];
+ if(p == -1) return;
+ printf("(%d transitions)\n",nexts[p]);
+ while(nchar[p]){
+ charc = 0;
+ if(nexts[p+1] >= 0)
+ printf("%d\t",nexts[p+1]);
+ else printf("err\t");
+ allprint(nchar[p++]);
+ while(nexts[p] == nexts[p+1] && nchar[p]){
+ if(charc > LINESIZE){
+ charc = 0;
+ printf("\n\t");
+ }
+ allprint(nchar[p++]);
+ }
+ putchar('\n');
+ }
+ putchar('\n');
+ return;
+ }
+# endif
+acompute(s) /* compute action list = set of poss. actions */
+ int s; {
+ register int *p, i, j;
+ int cnt, m;
+ int temp[300], k, neg[300], n;
+ k = 0;
+ n = 0;
+ p = state[s];
+ cnt = *p++;
+ if(cnt > 300)
+ error("Too many positions for one state - acompute");
+ for(i=0;i<cnt;i++){
+ if(name[*p] == FINAL)temp[k++] = left[*p];
+ else if(name[*p] == S1FINAL){temp[k++] = left[*p];
+ if (left[*p] >NACTIONS) error("Too many right contexts");
+ extra[left[*p]] = 1;
+ }
+ else if(name[*p] == S2FINAL)neg[n++] = left[*p];
+ p++;
+ }
+ atable[s] = -1;
+ if(k < 1 && n < 1) return;
+# ifdef DEBUG
+ if(debug) printf("final %d actions:",s);
+# endif
+ /* sort action list */
+ for(i=0; i<k; i++)
+ for(j=i+1;j<k;j++)
+ if(temp[j] < temp[i]){
+ m = temp[j];
+ temp[j] = temp[i];
+ temp[i] = m;
+ }
+ /* remove dups */
+ for(i=0;i<k-1;i++)
+ if(temp[i] == temp[i+1]) temp[i] = 0;
+ /* copy to permanent quarters */
+ atable[s] = aptr;
+# ifdef DEBUG
+ if(!ratfor)fprintf(fout,"/* actions for state %d */",s);
+# endif
+ putc('\n',fout);
+ for(i=0;i<k;i++)
+ if(temp[i] != 0){
+ ratfor ? fprintf(fout,"data vstop(%d)/%d/\n",aptr,temp[i]) : fprintf(fout,"%d,\n",temp[i]);
+# ifdef DEBUG
+ if(debug)
+ printf("%d ",temp[i]);
+# endif
+ aptr++;
+ }
+ for(i=0;i<n;i++){ /* copy fall back actions - all neg */
+ ratfor ? fprintf(fout,"data vstop(%d)/%d/\n",aptr,neg[i]) : fprintf(fout,"%d,\n",neg[i]);
+ aptr++;
+# ifdef DEBUG
+ if(debug)printf("%d ",neg[i]);
+# endif
+ }
+# ifdef DEBUG
+ if(debug)putchar('\n');
+# endif
+ ratfor ? fprintf(fout,"data vstop (%d)/0/\n",aptr) : fprintf(fout,"0,\n");
+ aptr++;
+ return;
+ }
+# ifdef DEBUG
+pccl() {
+ /* print character class sets */
+ register int i, j;
+ printf("char class intersection\n");
+ for(i=0; i< ccount; i++){
+ charc = 0;
+ printf("class %d:\n\t",i);
+ for(j=1;j<NCH;j++)
+ if(cindex[j] == i){
+ allprint(j);
+ if(charc > LINESIZE){
+ printf("\n\t");
+ charc = 0;
+ }
+ }
+ putchar('\n');
+ }
+ charc = 0;
+ printf("match:\n");
+ for(i=0;i<NCH;i++){
+ allprint(match[i]);
+ if(charc > LINESIZE){
+ putchar('\n');
+ charc = 0;
+ }
+ }
+ putchar('\n');
+ return;
+ }
+# endif
+mkmatch(){
+ register int i;
+ char tab[NCH];
+ for(i=0; i<ccount; i++)
+ tab[i] = 0;
+ for(i=1;i<NCH;i++)
+ if(tab[cindex[i]] == 0)
+ tab[cindex[i]] = i;
+ /* tab[i] = principal char for new ccl i */
+ for(i = 1; i<NCH; i++)
+ match[i] = tab[cindex[i]];
+ return;
+ }
+layout(){
+ /* format and output final program's tables */
+ register int i, j, k;
+ int top, bot, startup, omin;
+ startup = 0;
+ for(i=0; i<outsize;i++)
+ verify[i] = advance[i] = 0;
+ omin = 0;
+ yytop = 0;
+ for(i=0; i<= stnum; i++){ /* for each state */
+ j = gotof[i];
+ if(j == -1){
+ stoff[i] = 0;
+ continue;
+ }
+ bot = j;
+ while(nchar[j])j++;
+ top = j - 1;
+# if DEBUG
+ if (debug)
+ {
+ printf("State %d: (layout)\n", i);
+ for(j=bot; j<=top;j++)
+ {
+ printf(" %o", nchar[j]);
+ if (j%10==0) putchar('\n');
+ }
+ putchar('\n');
+ }
+# endif
+ while(verify[omin+ZCH]) omin++;
+ startup = omin;
+# if DEBUG
+ if (debug) printf("bot,top %d, %d startup begins %d\n",bot,top,startup);
+# endif
+ if(chset){
+ do {
+ ++startup;
+ if(startup > outsize - ZCH)
+ error("output table overflow");
+ for(j = bot; j<= top; j++){
+ k=startup+ctable[nchar[j]];
+ if(verify[k])break;
+ }
+ } while (j <= top);
+# if DEBUG
+ if (debug) printf(" startup will be %d\n",startup);
+# endif
+ /* have found place */
+ for(j = bot; j<= top; j++){
+ k = startup + ctable[nchar[j]];
+ if (ctable[nchar[j]]<=0)
+ printf("j %d nchar %d ctable.nch %d\n",j,nchar[j],ctable[nchar[k]]);
+ verify[k] = i+1; /* state number + 1*/
+ advance[k] = nexts[j+1]+1; /* state number + 1*/
+ if(yytop < k) yytop = k;
+ }
+ }
+ else {
+ do {
+ ++startup;
+ if(startup > outsize - ZCH)
+ error("output table overflow");
+ for(j = bot; j<= top; j++){
+ k = startup + nchar[j];
+ if(verify[k])break;
+ }
+ } while (j <= top);
+ /* have found place */
+# if DEBUG
+ if (debug) printf(" startup going to be %d\n", startup);
+# endif
+ for(j = bot; j<= top; j++){
+ k = startup + nchar[j];
+ verify[k] = i+1; /* state number + 1*/
+ advance[k] = nexts[j+1]+1; /* state number + 1*/
+ if(yytop < k) yytop = k;
+ }
+ }
+ stoff[i] = startup;
+ }
+
+ /* stoff[i] = offset into verify, advance for trans for state i */
+ /* put out yywork */
+ if(ratfor){
+ fprintf(fout, "define YYTOPVAL %d\n", yytop);
+ rprint(verify,"verif",yytop+1);
+ rprint(advance,"advan",yytop+1);
+ shiftr(stoff, stnum);
+ rprint(stoff,"stoff",stnum+1);
+ shiftr(sfall, stnum); upone(sfall, stnum+1);
+ rprint(sfall,"sfall",stnum+1);
+ bprint(extra,"extra",casecount+1);
+ bprint(match,"match",NCH);
+ shiftr(atable, stnum);
+ rprint(atable,"atable",stnum+1);
+ return;
+ }
+ fprintf(fout,"# define YYTYPE %s\n",stnum+1 > NCH ? "int" : "char");
+ fprintf(fout,"struct yywork { YYTYPE verify, advance; } yycrank[] ={\n");
+ for(i=0;i<=yytop;i+=4){
+ for(j=0;j<4;j++){
+ k = i+j;
+ if(verify[k])
+ fprintf(fout,"%d,%d,\t",verify[k],advance[k]);
+ else
+ fprintf(fout,"0,0,\t");
+ }
+ putc('\n',fout);
+ }
+ fprintf(fout,"0,0};\n");
+
+ /* put out yysvec */
+
+ fprintf(fout,"struct yysvf yysvec[] ={\n");
+ fprintf(fout,"0,\t0,\t0,\n");
+ for(i=0;i<=stnum;i++){ /* for each state */
+ if(cpackflg[i])stoff[i] = -stoff[i];
+ fprintf(fout,"yycrank+%d,\t",stoff[i]);
+ if(sfall[i] != -1)
+ fprintf(fout,"yysvec+%d,\t", sfall[i]+1); /* state + 1 */
+ else fprintf(fout,"0,\t\t");
+ if(atable[i] != -1)
+ fprintf(fout,"yyvstop+%d,",atable[i]);
+ else fprintf(fout,"0,\t");
+# ifdef DEBUG
+ fprintf(fout,"\t\t/* state %d */",i);
+# endif
+ putc('\n',fout);
+ }
+ fprintf(fout,"0,\t0,\t0};\n");
+
+ /* put out yymatch */
+
+ fprintf(fout,"struct yywork *yytop = yycrank+%d;\n",yytop);
+ fprintf(fout,"struct yysvf *yybgin = yysvec+1;\n");
+ if(optim){
+ fprintf(fout,"char yymatch[] ={\n");
+ if (chset==0) /* no chset, put out in normal order */
+ {
+ for(i=0; i<NCH; i+=8){
+ for(j=0; j<8; j++){
+ int fbch;
+ fbch = match[i+j];
+ if(printable(fbch) && fbch != '\'' && fbch != '\\')
+ fprintf(fout,"'%c' ,",fbch);
+ else fprintf(fout,"0%-3o,",fbch);
+ }
+ putc('\n',fout);
+ }
+ }
+ else
+ {
+ int *fbarr;
+ fbarr = myalloc(2*NCH, sizeof(*fbarr));
+ if (fbarr==0)
+ error("No space for char table reverse",0);
+ for(i=0; i<ZCH; i++)
+ fbarr[i]=0;
+ for(i=0; i<NCH; i++)
+ fbarr[ctable[i]] = ctable[match[i]];
+ for(i=0; i<ZCH; i+=8)
+ {
+ for(j=0; j<8; j++)
+ fprintf(fout, "0%-3o,",fbarr[i+j]);
+ putc('\n',fout);
+ }
+ cfree(fbarr, 2*NCH, 1);
+ }
+ fprintf(fout,"0};\n");
+ }
+ /* put out yyextra */
+ fprintf(fout,"char yyextra[] ={\n");
+ for(i=0;i<casecount;i+=8){
+ for(j=0;j<8;j++)
+ fprintf(fout, "%d,", i+j<NACTIONS ?
+ extra[i+j] : 0);
+ putc('\n',fout);
+ }
+ fprintf(fout,"0};\n");
+ return;
+ }
+rprint(a,s,n)
+ char *s;
+ int *a, n; {
+ register int i;
+ fprintf(fout,"block data\n");
+ fprintf(fout,"common /L%s/ %s\n",s,s);
+ fprintf(fout,"define S%s %d\n",s,n);
+ fprintf(fout,"integer %s (S%s)\n",s,s);
+ for(i=1; i<=n; i++)
+ {
+ if (i%8==1) fprintf(fout, "data ");
+ fprintf(fout, "%s (%d)/%d/",s,i,a[i]);
+ fprintf(fout, (i%8 && i<n) ? ", " : "\n");
+ }
+ fprintf(fout,"end\n");
+ }
+shiftr(a, n)
+ int *a;
+{
+int i;
+for(i=n; i>=0; i--)
+ a[i+1]=a[i];
+}
+upone(a,n)
+ int *a;
+{
+int i;
+for(i=0; i<=n ; i++)
+ a[i]++;
+}
+bprint(a,s,n)
+ char *s, *a;
+ int n; {
+ register int i, j, k;
+ fprintf(fout,"block data\n");
+ fprintf(fout,"common /L%s/ %s\n",s,s);
+ fprintf(fout,"define S%s %d\n",s,n);
+ fprintf(fout,"integer %s (S%s)\n",s,s);
+ for(i=1;i<n;i+=8){
+ fprintf(fout,"data %s (%d)/%d/",s,i,a[i]);
+ for(j=1;j<8;j++){
+ k = i+j;
+ if(k < n)fprintf(fout,", %s (%d)/%d/",s,k,a[k]);
+ }
+ putc('\n',fout);
+ }
+ fprintf(fout,"end\n");
+ }
+# ifdef PP
+padd(array,n)
+ int **array;
+ int n; {
+ register int i, *j, k;
+ array[n] = nxtpos;
+ if(count == 0){
+ *nxtpos++ = 0;
+ return;
+ }
+ for(i=tptr-1;i>=0;i--){
+ j = array[i];
+ if(j && *j++ == count){
+ for(k=0;k<count;k++)
+ if(!tmpstat[*j++])break;
+ if(k >= count){
+ array[n] = array[i];
+ return;
+ }
+ }
+ }
+ add(array,n);
+ return;
+ }
+# endif