114494Ssam #ifndef lint 2*33343Sbostic static char sccsid[] = "@(#)sub2.c 4.2 (Berkeley) 01/12/88"; 314494Ssam #endif 414494Ssam 514494Ssam # include "ldefs.c" 614494Ssam cfoll(v) 714494Ssam int v; 814494Ssam { 914494Ssam register int i,j,k; 1014494Ssam char *p; 1114494Ssam i = name[v]; 1214494Ssam if(i < NCH) i = 1; /* character */ 1314494Ssam switch(i){ 1414494Ssam case 1: case RSTR: case RCCL: case RNCCL: case RNULLS: 1514494Ssam for(j=0;j<tptr;j++) 1614494Ssam tmpstat[j] = FALSE; 1714494Ssam count = 0; 1814494Ssam follow(v); 1914494Ssam # ifdef PP 2014494Ssam padd(foll,v); /* packing version */ 2114494Ssam # endif 2214494Ssam # ifndef PP 2314494Ssam add(foll,v); /* no packing version */ 2414494Ssam # endif 2514494Ssam if(i == RSTR) cfoll(left[v]); 2614494Ssam else if(i == RCCL || i == RNCCL){ /* compress ccl list */ 2714494Ssam for(j=1; j<NCH;j++) 2814494Ssam symbol[j] = (i==RNCCL); 29*33343Sbostic p = (char *)left[v]; 3014494Ssam while(*p) 3114494Ssam symbol[*p++] = (i == RCCL); 3214494Ssam p = pcptr; 3314494Ssam for(j=1;j<NCH;j++) 3414494Ssam if(symbol[j]){ 3514494Ssam for(k=0;p+k < pcptr; k++) 3614494Ssam if(cindex[j] == *(p+k)) 3714494Ssam break; 3814494Ssam if(p+k >= pcptr)*pcptr++ = cindex[j]; 3914494Ssam } 4014494Ssam *pcptr++ = 0; 4114494Ssam if(pcptr > pchar + pchlen) 4214494Ssam error("Too many packed character classes"); 43*33343Sbostic left[v] = (int)p; 4414494Ssam name[v] = RCCL; /* RNCCL eliminated */ 4514494Ssam # ifdef DEBUG 4614494Ssam if(debug && *p){ 4714494Ssam printf("ccl %d: %d",v,*p++); 4814494Ssam while(*p) 4914494Ssam printf(", %d",*p++); 5014494Ssam putchar('\n'); 5114494Ssam } 5214494Ssam # endif 5314494Ssam } 5414494Ssam break; 5514494Ssam case CARAT: 5614494Ssam cfoll(left[v]); 5714494Ssam break; 5814494Ssam case STAR: case PLUS: case QUEST: case RSCON: 5914494Ssam cfoll(left[v]); 6014494Ssam break; 6114494Ssam case BAR: case RCAT: case DIV: case RNEWE: 6214494Ssam cfoll(left[v]); 6314494Ssam cfoll(right[v]); 6414494Ssam break; 6514494Ssam # ifdef DEBUG 6614494Ssam case FINAL: 6714494Ssam case S1FINAL: 6814494Ssam case S2FINAL: 6914494Ssam break; 7014494Ssam default: 7114494Ssam warning("bad switch cfoll %d",v); 7214494Ssam # endif 7314494Ssam } 7414494Ssam return; 7514494Ssam } 7614494Ssam # ifdef DEBUG 7714494Ssam pfoll() 7814494Ssam { 7914494Ssam register int i,k,*p; 8014494Ssam int j; 8114494Ssam /* print sets of chars which may follow positions */ 8214494Ssam printf("pos\tchars\n"); 8314494Ssam for(i=0;i<tptr;i++) 8414494Ssam if(p=foll[i]){ 8514494Ssam j = *p++; 8614494Ssam if(j >= 1){ 8714494Ssam printf("%d:\t%d",i,*p++); 8814494Ssam for(k=2;k<=j;k++) 8914494Ssam printf(", %d",*p++); 9014494Ssam putchar('\n'); 9114494Ssam } 9214494Ssam } 9314494Ssam return; 9414494Ssam } 9514494Ssam # endif 9614494Ssam add(array,n) 9714494Ssam int **array; 9814494Ssam int n; { 9914494Ssam register int i, *temp; 10014494Ssam register char *ctemp; 10114494Ssam temp = nxtpos; 10214494Ssam ctemp = tmpstat; 10314494Ssam array[n] = nxtpos; /* note no packing is done in positions */ 10414494Ssam *temp++ = count; 10514494Ssam for(i=0;i<tptr;i++) 10614494Ssam if(ctemp[i] == TRUE) 10714494Ssam *temp++ = i; 10814494Ssam nxtpos = temp; 10914494Ssam if(nxtpos >= positions+maxpos) 11014494Ssam error("Too many positions %s",(maxpos== MAXPOS?"\nTry using %p num":"")); 11114494Ssam return; 11214494Ssam } 11314494Ssam follow(v) 11414494Ssam int v; 11514494Ssam { 11614494Ssam register int p; 11714494Ssam if(v >= tptr-1)return; 11814494Ssam p = parent[v]; 11914494Ssam if(p == 0) return; 12014494Ssam switch(name[p]){ 12114494Ssam /* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */ 12214494Ssam case RSTR: 12314494Ssam if(tmpstat[p] == FALSE){ 12414494Ssam count++; 12514494Ssam tmpstat[p] = TRUE; 12614494Ssam } 12714494Ssam break; 12814494Ssam case STAR: case PLUS: 12914494Ssam first(v); 13014494Ssam follow(p); 13114494Ssam break; 13214494Ssam case BAR: case QUEST: case RNEWE: 13314494Ssam follow(p); 13414494Ssam break; 13514494Ssam case RCAT: case DIV: 13614494Ssam if(v == left[p]){ 13714494Ssam if(nullstr[right[p]]) 13814494Ssam follow(p); 13914494Ssam first(right[p]); 14014494Ssam } 14114494Ssam else follow(p); 14214494Ssam break; 14314494Ssam case RSCON: case CARAT: 14414494Ssam follow(p); 14514494Ssam break; 14614494Ssam # ifdef DEBUG 14714494Ssam default: 14814494Ssam warning("bad switch follow %d",p); 14914494Ssam # endif 15014494Ssam } 15114494Ssam return; 15214494Ssam } 15314494Ssam first(v) /* calculate set of positions with v as root which can be active initially */ 15414494Ssam int v; { 15514494Ssam register int i; 15614494Ssam register char *p; 15714494Ssam i = name[v]; 15814494Ssam if(i < NCH)i = 1; 15914494Ssam switch(i){ 16014494Ssam case 1: case RCCL: case RNCCL: case RNULLS: case FINAL: case S1FINAL: case S2FINAL: 16114494Ssam if(tmpstat[v] == FALSE){ 16214494Ssam count++; 16314494Ssam tmpstat[v] = TRUE; 16414494Ssam } 16514494Ssam break; 16614494Ssam case BAR: case RNEWE: 16714494Ssam first(left[v]); 16814494Ssam first(right[v]); 16914494Ssam break; 17014494Ssam case CARAT: 17114494Ssam if(stnum % 2 == 1) 17214494Ssam first(left[v]); 17314494Ssam break; 17414494Ssam case RSCON: 17514494Ssam i = stnum/2 +1; 176*33343Sbostic p = (char *)right[v]; 17714494Ssam while(*p) 17814494Ssam if(*p++ == i){ 17914494Ssam first(left[v]); 18014494Ssam break; 18114494Ssam } 18214494Ssam break; 18314494Ssam case STAR: case QUEST: case PLUS: case RSTR: 18414494Ssam first(left[v]); 18514494Ssam break; 18614494Ssam case RCAT: case DIV: 18714494Ssam first(left[v]); 18814494Ssam if(nullstr[left[v]]) 18914494Ssam first(right[v]); 19014494Ssam break; 19114494Ssam # ifdef DEBUG 19214494Ssam default: 19314494Ssam warning("bad switch first %d",v); 19414494Ssam # endif 19514494Ssam } 19614494Ssam return; 19714494Ssam } 19814494Ssam cgoto(){ 19914494Ssam register int i, j, s; 20014494Ssam int npos, curpos, n; 20114494Ssam int tryit; 20214494Ssam char tch[NCH]; 20314494Ssam int tst[NCH]; 20414494Ssam char *q; 20514494Ssam /* generate initial state, for each start condition */ 20614494Ssam if(ratfor){ 20714494Ssam fprintf(fout,"blockdata\n"); 20814494Ssam fprintf(fout,"common /Lvstop/ vstop\n"); 20914494Ssam fprintf(fout,"define Svstop %d\n",nstates+1); 21014494Ssam fprintf(fout,"integer vstop(Svstop)\n"); 21114494Ssam } 21214494Ssam else fprintf(fout,"int yyvstop[] ={\n0,\n"); 21314494Ssam while(stnum < 2 || stnum/2 < sptr){ 21414494Ssam for(i = 0; i<tptr; i++) tmpstat[i] = 0; 21514494Ssam count = 0; 21614494Ssam if(tptr > 0)first(tptr-1); 21714494Ssam add(state,stnum); 21814494Ssam # ifdef DEBUG 21914494Ssam if(debug){ 22014494Ssam if(stnum > 1) 22114494Ssam printf("%s:\n",sname[stnum/2]); 22214494Ssam pstate(stnum); 22314494Ssam } 22414494Ssam # endif 22514494Ssam stnum++; 22614494Ssam } 22714494Ssam stnum--; 22814494Ssam /* even stnum = might not be at line begin */ 22914494Ssam /* odd stnum = must be at line begin */ 23014494Ssam /* even states can occur anywhere, odd states only at line begin */ 23114494Ssam for(s = 0; s <= stnum; s++){ 23214494Ssam tryit = FALSE; 23314494Ssam cpackflg[s] = FALSE; 23414494Ssam sfall[s] = -1; 23514494Ssam acompute(s); 23614494Ssam for(i=0;i<NCH;i++) symbol[i] = 0; 23714494Ssam npos = *state[s]; 23814494Ssam for(i = 1; i<=npos; i++){ 23914494Ssam curpos = *(state[s]+i); 24014494Ssam if(name[curpos] < NCH) symbol[name[curpos]] = TRUE; 24114494Ssam else switch(name[curpos]){ 24214494Ssam case RCCL: 24314494Ssam tryit = TRUE; 244*33343Sbostic q = (char *)left[curpos]; 24514494Ssam while(*q){ 24614494Ssam for(j=1;j<NCH;j++) 24714494Ssam if(cindex[j] == *q) 24814494Ssam symbol[j] = TRUE; 24914494Ssam q++; 25014494Ssam } 25114494Ssam break; 25214494Ssam case RSTR: 25314494Ssam symbol[right[curpos]] = TRUE; 25414494Ssam break; 25514494Ssam # ifdef DEBUG 25614494Ssam case RNULLS: 25714494Ssam case FINAL: 25814494Ssam case S1FINAL: 25914494Ssam case S2FINAL: 26014494Ssam break; 26114494Ssam default: 26214494Ssam warning("bad switch cgoto %d state %d",curpos,s); 26314494Ssam break; 26414494Ssam # endif 26514494Ssam } 26614494Ssam } 26714494Ssam # ifdef DEBUG 26814494Ssam if(debug){ 26914494Ssam printf("State %d transitions on:\n\t",s); 27014494Ssam charc = 0; 27114494Ssam for(i = 1; i<NCH; i++){ 27214494Ssam if(symbol[i]) allprint(i); 27314494Ssam if(charc > LINESIZE){ 27414494Ssam charc = 0; 27514494Ssam printf("\n\t"); 27614494Ssam } 27714494Ssam } 27814494Ssam putchar('\n'); 27914494Ssam } 28014494Ssam # endif 28114494Ssam /* for each char, calculate next state */ 28214494Ssam n = 0; 28314494Ssam for(i = 1; i<NCH; i++){ 28414494Ssam if(symbol[i]){ 28514494Ssam nextstate(s,i); /* executed for each state, transition pair */ 28614494Ssam xstate = notin(stnum); 28714494Ssam if(xstate == -2) warning("bad state %d %o",s,i); 28814494Ssam else if(xstate == -1){ 28914494Ssam if(stnum >= nstates) 29014494Ssam error("Too many states %s",(nstates == NSTATES ? "\nTry using %n num":"")); 29114494Ssam add(state,++stnum); 29214494Ssam # ifdef DEBUG 29314494Ssam if(debug)pstate(stnum); 29414494Ssam # endif 29514494Ssam tch[n] = i; 29614494Ssam tst[n++] = stnum; 29714494Ssam } 29814494Ssam else { /* xstate >= 0 ==> state exists */ 29914494Ssam tch[n] = i; 30014494Ssam tst[n++] = xstate; 30114494Ssam } 30214494Ssam } 30314494Ssam } 30414494Ssam tch[n] = 0; 30514494Ssam tst[n] = -1; 30614494Ssam /* pack transitions into permanent array */ 30714494Ssam if(n > 0) packtrans(s,tch,tst,n,tryit); 30814494Ssam else gotof[s] = -1; 30914494Ssam } 31014494Ssam ratfor ? fprintf(fout,"end\n") : fprintf(fout,"0};\n"); 31114494Ssam return; 31214494Ssam } 31314494Ssam /* Beware -- 70% of total CPU time is spent in this subroutine - 31414494Ssam if you don't believe me - try it yourself ! */ 31514494Ssam nextstate(s,c) 31614494Ssam int s,c; { 31714494Ssam register int j, *newpos; 31814494Ssam register char *temp, *tz; 31914494Ssam int *pos, i, *f, num, curpos, number; 32014494Ssam /* state to goto from state s on char c */ 32114494Ssam num = *state[s]; 32214494Ssam temp = tmpstat; 32314494Ssam pos = state[s] + 1; 32414494Ssam for(i = 0; i<num; i++){ 32514494Ssam curpos = *pos++; 32614494Ssam j = name[curpos]; 32714494Ssam if(j < NCH && j == c 32814494Ssam || j == RSTR && c == right[curpos] 32914494Ssam || j == RCCL && member(c,left[curpos])){ 33014494Ssam f = foll[curpos]; 33114494Ssam number = *f; 33214494Ssam newpos = f+1; 33314494Ssam for(j=0;j<number;j++) 33414494Ssam temp[*newpos++] = 2; 33514494Ssam } 33614494Ssam } 33714494Ssam j = 0; 33814494Ssam tz = temp + tptr; 33914494Ssam while(temp < tz){ 34014494Ssam if(*temp == 2){ 34114494Ssam j++; 34214494Ssam *temp++ = 1; 34314494Ssam } 34414494Ssam else *temp++ = 0; 34514494Ssam } 34614494Ssam count = j; 34714494Ssam return; 34814494Ssam } 34914494Ssam notin(n) 35014494Ssam int n; { /* see if tmpstat occurs previously */ 35114494Ssam register int *j,k; 35214494Ssam register char *temp; 35314494Ssam int i; 35414494Ssam if(count == 0) 35514494Ssam return(-2); 35614494Ssam temp = tmpstat; 35714494Ssam for(i=n;i>=0;i--){ /* for each state */ 35814494Ssam j = state[i]; 35914494Ssam if(count == *j++){ 36014494Ssam for(k=0;k<count;k++) 36114494Ssam if(!temp[*j++])break; 36214494Ssam if(k >= count) 36314494Ssam return(i); 36414494Ssam } 36514494Ssam } 36614494Ssam return(-1); 36714494Ssam } 36814494Ssam packtrans(st,tch,tst,cnt,tryit) 36914494Ssam int st, *tst, cnt,tryit; 37014494Ssam char *tch; { 37114494Ssam /* pack transitions into nchar, nexts */ 37214494Ssam /* nchar is terminated by '\0', nexts uses cnt, followed by elements */ 37314494Ssam /* gotof[st] = index into nchr, nexts for state st */ 37414494Ssam 37514494Ssam /* sfall[st] = t implies t is fall back state for st */ 37614494Ssam /* == -1 implies no fall back */ 37714494Ssam 37814494Ssam int cmin, cval, tcnt, diff, p, *ast; 37914494Ssam register int i,j,k; 38014494Ssam char *ach; 38114494Ssam int go[NCH], temp[NCH], c; 38214494Ssam int swork[NCH]; 38314494Ssam char cwork[NCH]; 38414494Ssam int upper; 38514494Ssam 38614494Ssam rcount += cnt; 38714494Ssam cmin = -1; 38814494Ssam cval = NCH; 38914494Ssam ast = tst; 39014494Ssam ach = tch; 39114494Ssam /* try to pack transitions using ccl's */ 39214494Ssam if(!optim)goto nopack; /* skip all compaction */ 39314494Ssam if(tryit){ /* ccl's used */ 39414494Ssam for(i=1;i<NCH;i++){ 39514494Ssam go[i] = temp[i] = -1; 39614494Ssam symbol[i] = 1; 39714494Ssam } 39814494Ssam for(i=0;i<cnt;i++){ 39914494Ssam go[tch[i]] = tst[i]; 40014494Ssam symbol[tch[i]] = 0; 40114494Ssam } 40214494Ssam for(i=0; i<cnt;i++){ 40314494Ssam c = match[tch[i]]; 40414494Ssam if(go[c] != tst[i] || c == tch[i]) 40514494Ssam temp[tch[i]] = tst[i]; 40614494Ssam } 40714494Ssam /* fill in error entries */ 40814494Ssam for(i=1;i<NCH;i++) 40914494Ssam if(symbol[i]) temp[i] = -2; /* error trans */ 41014494Ssam /* count them */ 41114494Ssam k = 0; 41214494Ssam for(i=1;i<NCH;i++) 41314494Ssam if(temp[i] != -1)k++; 41414494Ssam if(k <cnt){ /* compress by char */ 41514494Ssam # ifdef DEBUG 41614494Ssam if(debug) printf("use compression %d, %d vs %d\n",st,k,cnt); 41714494Ssam # endif 41814494Ssam k = 0; 41914494Ssam for(i=1;i<NCH;i++) 42014494Ssam if(temp[i] != -1){ 42114494Ssam cwork[k] = i; 42214494Ssam swork[k++] = (temp[i] == -2 ? -1 : temp[i]); 42314494Ssam } 42414494Ssam cwork[k] = 0; 42514494Ssam # ifdef PC 42614494Ssam ach = cwork; 42714494Ssam ast = swork; 42814494Ssam cnt = k; 42914494Ssam cpackflg[st] = TRUE; 43014494Ssam # endif 43114494Ssam } 43214494Ssam } 43314494Ssam for(i=0; i<st; i++){ /* get most similar state */ 43414494Ssam /* reject state with more transitions, state already represented by a third state, 43514494Ssam and state which is compressed by char if ours is not to be */ 43614494Ssam if(sfall[i] != -1) continue; 43714494Ssam if(cpackflg[st] == 1) if(!(cpackflg[i] == 1)) continue; 43814494Ssam p = gotof[i]; 43914494Ssam if(p == -1) /* no transitions */ continue; 44014494Ssam tcnt = nexts[p]; 44114494Ssam if(tcnt > cnt) continue; 44214494Ssam diff = 0; 44314494Ssam k = 0; 44414494Ssam j = 0; 44514494Ssam upper = p + tcnt; 44614494Ssam while(ach[j] && p < upper){ 44714494Ssam while(ach[j] < nchar[p] && ach[j]){diff++; j++; } 44814494Ssam if(ach[j] == 0)break; 44914494Ssam if(ach[j] > nchar[p]){diff=NCH;break;} 45014494Ssam /* ach[j] == nchar[p] */ 45114494Ssam if(ast[j] != nexts[++p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]]))diff++; 45214494Ssam j++; 45314494Ssam } 45414494Ssam while(ach[j]){ 45514494Ssam diff++; 45614494Ssam j++; 45714494Ssam } 45814494Ssam if(p < upper)diff = NCH; 45914494Ssam if(diff < cval && diff < tcnt){ 46014494Ssam cval = diff; 46114494Ssam cmin = i; 46214494Ssam if(cval == 0)break; 46314494Ssam } 46414494Ssam } 46514494Ssam /* cmin = state "most like" state st */ 46614494Ssam # ifdef DEBUG 46714494Ssam if(debug)printf("select st %d for st %d diff %d\n",cmin,st,cval); 46814494Ssam # endif 46914494Ssam # ifdef PS 47014494Ssam if(cmin != -1){ /* if we can use st cmin */ 47114494Ssam gotof[st] = nptr; 47214494Ssam k = 0; 47314494Ssam sfall[st] = cmin; 47414494Ssam p = gotof[cmin]+1; 47514494Ssam j = 0; 47614494Ssam while(ach[j]){ 47714494Ssam /* if cmin has a transition on c, then so will st */ 47814494Ssam /* st may be "larger" than cmin, however */ 47914494Ssam while(ach[j] < nchar[p-1] && ach[j]){ 48014494Ssam k++; 48114494Ssam nchar[nptr] = ach[j]; 48214494Ssam nexts[++nptr] = ast[j]; 48314494Ssam j++; 48414494Ssam } 48514494Ssam if(nchar[p-1] == 0)break; 48614494Ssam if(ach[j] > nchar[p-1]){ 48714494Ssam warning("bad transition %d %d",st,cmin); 48814494Ssam goto nopack; 48914494Ssam } 49014494Ssam /* ach[j] == nchar[p-1] */ 49114494Ssam if(ast[j] != nexts[p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]])){ 49214494Ssam k++; 49314494Ssam nchar[nptr] = ach[j]; 49414494Ssam nexts[++nptr] = ast[j]; 49514494Ssam } 49614494Ssam p++; 49714494Ssam j++; 49814494Ssam } 49914494Ssam while(ach[j]){ 50014494Ssam nchar[nptr] = ach[j]; 50114494Ssam nexts[++nptr] = ast[j++]; 50214494Ssam k++; 50314494Ssam } 50414494Ssam nexts[gotof[st]] = cnt = k; 50514494Ssam nchar[nptr++] = 0; 50614494Ssam } 50714494Ssam else { 50814494Ssam # endif 50914494Ssam nopack: 51014494Ssam /* stick it in */ 51114494Ssam gotof[st] = nptr; 51214494Ssam nexts[nptr] = cnt; 51314494Ssam for(i=0;i<cnt;i++){ 51414494Ssam nchar[nptr] = ach[i]; 51514494Ssam nexts[++nptr] = ast[i]; 51614494Ssam } 51714494Ssam nchar[nptr++] = 0; 51814494Ssam # ifdef PS 51914494Ssam } 52014494Ssam # endif 52114494Ssam if(cnt < 1){ 52214494Ssam gotof[st] = -1; 52314494Ssam nptr--; 52414494Ssam } 52514494Ssam else 52614494Ssam if(nptr > ntrans) 52714494Ssam error("Too many transitions %s",(ntrans==NTRANS?"\nTry using %a num":"")); 52814494Ssam return; 52914494Ssam } 53014494Ssam # ifdef DEBUG 53114494Ssam pstate(s) 53214494Ssam int s; { 53314494Ssam register int *p,i,j; 53414494Ssam printf("State %d:\n",s); 53514494Ssam p = state[s]; 53614494Ssam i = *p++; 53714494Ssam if(i == 0) return; 53814494Ssam printf("%4d",*p++); 53914494Ssam for(j = 1; j<i; j++){ 54014494Ssam printf(", %4d",*p++); 54114494Ssam if(j%30 == 0)putchar('\n'); 54214494Ssam } 54314494Ssam putchar('\n'); 54414494Ssam return; 54514494Ssam } 54614494Ssam # endif 54714494Ssam member(d,t) 54814494Ssam int d; 54914494Ssam char *t; { 55014494Ssam register int c; 55114494Ssam register char *s; 55214494Ssam c = d; 55314494Ssam s = t; 55414494Ssam c = cindex[c]; 55514494Ssam while(*s) 55614494Ssam if(*s++ == c) return(1); 55714494Ssam return(0); 55814494Ssam } 55914494Ssam # ifdef DEBUG 56014494Ssam stprt(i) 56114494Ssam int i; { 56214494Ssam register int p, t; 56314494Ssam printf("State %d:",i); 56414494Ssam /* print actions, if any */ 56514494Ssam t = atable[i]; 56614494Ssam if(t != -1)printf(" final"); 56714494Ssam putchar('\n'); 56814494Ssam if(cpackflg[i] == TRUE)printf("backup char in use\n"); 56914494Ssam if(sfall[i] != -1)printf("fall back state %d\n",sfall[i]); 57014494Ssam p = gotof[i]; 57114494Ssam if(p == -1) return; 57214494Ssam printf("(%d transitions)\n",nexts[p]); 57314494Ssam while(nchar[p]){ 57414494Ssam charc = 0; 57514494Ssam if(nexts[p+1] >= 0) 57614494Ssam printf("%d\t",nexts[p+1]); 57714494Ssam else printf("err\t"); 57814494Ssam allprint(nchar[p++]); 57914494Ssam while(nexts[p] == nexts[p+1] && nchar[p]){ 58014494Ssam if(charc > LINESIZE){ 58114494Ssam charc = 0; 58214494Ssam printf("\n\t"); 58314494Ssam } 58414494Ssam allprint(nchar[p++]); 58514494Ssam } 58614494Ssam putchar('\n'); 58714494Ssam } 58814494Ssam putchar('\n'); 58914494Ssam return; 59014494Ssam } 59114494Ssam # endif 59214494Ssam acompute(s) /* compute action list = set of poss. actions */ 59314494Ssam int s; { 59414494Ssam register int *p, i, j; 59514494Ssam int cnt, m; 59614494Ssam int temp[300], k, neg[300], n; 59714494Ssam k = 0; 59814494Ssam n = 0; 59914494Ssam p = state[s]; 60014494Ssam cnt = *p++; 60114494Ssam if(cnt > 300) 60214494Ssam error("Too many positions for one state - acompute"); 60314494Ssam for(i=0;i<cnt;i++){ 60414494Ssam if(name[*p] == FINAL)temp[k++] = left[*p]; 60514494Ssam else if(name[*p] == S1FINAL){temp[k++] = left[*p]; 60614494Ssam if (left[*p] >NACTIONS) error("Too many right contexts"); 60714494Ssam extra[left[*p]] = 1; 60814494Ssam } 60914494Ssam else if(name[*p] == S2FINAL)neg[n++] = left[*p]; 61014494Ssam p++; 61114494Ssam } 61214494Ssam atable[s] = -1; 61314494Ssam if(k < 1 && n < 1) return; 61414494Ssam # ifdef DEBUG 61514494Ssam if(debug) printf("final %d actions:",s); 61614494Ssam # endif 61714494Ssam /* sort action list */ 61814494Ssam for(i=0; i<k; i++) 61914494Ssam for(j=i+1;j<k;j++) 62014494Ssam if(temp[j] < temp[i]){ 62114494Ssam m = temp[j]; 62214494Ssam temp[j] = temp[i]; 62314494Ssam temp[i] = m; 62414494Ssam } 62514494Ssam /* remove dups */ 62614494Ssam for(i=0;i<k-1;i++) 62714494Ssam if(temp[i] == temp[i+1]) temp[i] = 0; 62814494Ssam /* copy to permanent quarters */ 62914494Ssam atable[s] = aptr; 63014494Ssam # ifdef DEBUG 63114494Ssam if(!ratfor)fprintf(fout,"/* actions for state %d */",s); 63214494Ssam # endif 63314494Ssam putc('\n',fout); 63414494Ssam for(i=0;i<k;i++) 63514494Ssam if(temp[i] != 0){ 63614494Ssam ratfor ? fprintf(fout,"data vstop(%d)/%d/\n",aptr,temp[i]) : fprintf(fout,"%d,\n",temp[i]); 63714494Ssam # ifdef DEBUG 63814494Ssam if(debug) 63914494Ssam printf("%d ",temp[i]); 64014494Ssam # endif 64114494Ssam aptr++; 64214494Ssam } 64314494Ssam for(i=0;i<n;i++){ /* copy fall back actions - all neg */ 64414494Ssam ratfor ? fprintf(fout,"data vstop(%d)/%d/\n",aptr,neg[i]) : fprintf(fout,"%d,\n",neg[i]); 64514494Ssam aptr++; 64614494Ssam # ifdef DEBUG 64714494Ssam if(debug)printf("%d ",neg[i]); 64814494Ssam # endif 64914494Ssam } 65014494Ssam # ifdef DEBUG 65114494Ssam if(debug)putchar('\n'); 65214494Ssam # endif 65314494Ssam ratfor ? fprintf(fout,"data vstop (%d)/0/\n",aptr) : fprintf(fout,"0,\n"); 65414494Ssam aptr++; 65514494Ssam return; 65614494Ssam } 65714494Ssam # ifdef DEBUG 65814494Ssam pccl() { 65914494Ssam /* print character class sets */ 66014494Ssam register int i, j; 66114494Ssam printf("char class intersection\n"); 66214494Ssam for(i=0; i< ccount; i++){ 66314494Ssam charc = 0; 66414494Ssam printf("class %d:\n\t",i); 66514494Ssam for(j=1;j<NCH;j++) 66614494Ssam if(cindex[j] == i){ 66714494Ssam allprint(j); 66814494Ssam if(charc > LINESIZE){ 66914494Ssam printf("\n\t"); 67014494Ssam charc = 0; 67114494Ssam } 67214494Ssam } 67314494Ssam putchar('\n'); 67414494Ssam } 67514494Ssam charc = 0; 67614494Ssam printf("match:\n"); 67714494Ssam for(i=0;i<NCH;i++){ 67814494Ssam allprint(match[i]); 67914494Ssam if(charc > LINESIZE){ 68014494Ssam putchar('\n'); 68114494Ssam charc = 0; 68214494Ssam } 68314494Ssam } 68414494Ssam putchar('\n'); 68514494Ssam return; 68614494Ssam } 68714494Ssam # endif 68814494Ssam mkmatch(){ 68914494Ssam register int i; 69014494Ssam char tab[NCH]; 69114494Ssam for(i=0; i<ccount; i++) 69214494Ssam tab[i] = 0; 69314494Ssam for(i=1;i<NCH;i++) 69414494Ssam if(tab[cindex[i]] == 0) 69514494Ssam tab[cindex[i]] = i; 69614494Ssam /* tab[i] = principal char for new ccl i */ 69714494Ssam for(i = 1; i<NCH; i++) 69814494Ssam match[i] = tab[cindex[i]]; 69914494Ssam return; 70014494Ssam } 70114494Ssam layout(){ 70214494Ssam /* format and output final program's tables */ 70314494Ssam register int i, j, k; 70414494Ssam int top, bot, startup, omin; 70514494Ssam startup = 0; 70614494Ssam for(i=0; i<outsize;i++) 70714494Ssam verify[i] = advance[i] = 0; 70814494Ssam omin = 0; 70914494Ssam yytop = 0; 71014494Ssam for(i=0; i<= stnum; i++){ /* for each state */ 71114494Ssam j = gotof[i]; 71214494Ssam if(j == -1){ 71314494Ssam stoff[i] = 0; 71414494Ssam continue; 71514494Ssam } 71614494Ssam bot = j; 71714494Ssam while(nchar[j])j++; 71814494Ssam top = j - 1; 71914494Ssam # if DEBUG 72014494Ssam if (debug) 72114494Ssam { 72214494Ssam printf("State %d: (layout)\n", i); 72314494Ssam for(j=bot; j<=top;j++) 72414494Ssam { 72514494Ssam printf(" %o", nchar[j]); 72614494Ssam if (j%10==0) putchar('\n'); 72714494Ssam } 72814494Ssam putchar('\n'); 72914494Ssam } 73014494Ssam # endif 73114494Ssam while(verify[omin+ZCH]) omin++; 73214494Ssam startup = omin; 73314494Ssam # if DEBUG 73414494Ssam if (debug) printf("bot,top %d, %d startup begins %d\n",bot,top,startup); 73514494Ssam # endif 73614494Ssam if(chset){ 73714494Ssam do { 73814494Ssam ++startup; 73914494Ssam if(startup > outsize - ZCH) 74014494Ssam error("output table overflow"); 74114494Ssam for(j = bot; j<= top; j++){ 74214494Ssam k=startup+ctable[nchar[j]]; 74314494Ssam if(verify[k])break; 74414494Ssam } 74514494Ssam } while (j <= top); 74614494Ssam # if DEBUG 74714494Ssam if (debug) printf(" startup will be %d\n",startup); 74814494Ssam # endif 74914494Ssam /* have found place */ 75014494Ssam for(j = bot; j<= top; j++){ 75114494Ssam k = startup + ctable[nchar[j]]; 75214494Ssam if (ctable[nchar[j]]<=0) 75314494Ssam printf("j %d nchar %d ctable.nch %d\n",j,nchar[j],ctable[nchar[k]]); 75414494Ssam verify[k] = i+1; /* state number + 1*/ 75514494Ssam advance[k] = nexts[j+1]+1; /* state number + 1*/ 75614494Ssam if(yytop < k) yytop = k; 75714494Ssam } 75814494Ssam } 75914494Ssam else { 76014494Ssam do { 76114494Ssam ++startup; 76214494Ssam if(startup > outsize - ZCH) 76314494Ssam error("output table overflow"); 76414494Ssam for(j = bot; j<= top; j++){ 76514494Ssam k = startup + nchar[j]; 76614494Ssam if(verify[k])break; 76714494Ssam } 76814494Ssam } while (j <= top); 76914494Ssam /* have found place */ 77014494Ssam # if DEBUG 77114494Ssam if (debug) printf(" startup going to be %d\n", startup); 77214494Ssam # endif 77314494Ssam for(j = bot; j<= top; j++){ 77414494Ssam k = startup + nchar[j]; 77514494Ssam verify[k] = i+1; /* state number + 1*/ 77614494Ssam advance[k] = nexts[j+1]+1; /* state number + 1*/ 77714494Ssam if(yytop < k) yytop = k; 77814494Ssam } 77914494Ssam } 78014494Ssam stoff[i] = startup; 78114494Ssam } 78214494Ssam 78314494Ssam /* stoff[i] = offset into verify, advance for trans for state i */ 78414494Ssam /* put out yywork */ 78514494Ssam if(ratfor){ 78614494Ssam fprintf(fout, "define YYTOPVAL %d\n", yytop); 78714494Ssam rprint(verify,"verif",yytop+1); 78814494Ssam rprint(advance,"advan",yytop+1); 78914494Ssam shiftr(stoff, stnum); 79014494Ssam rprint(stoff,"stoff",stnum+1); 79114494Ssam shiftr(sfall, stnum); upone(sfall, stnum+1); 79214494Ssam rprint(sfall,"sfall",stnum+1); 79314494Ssam bprint(extra,"extra",casecount+1); 79414494Ssam bprint(match,"match",NCH); 79514494Ssam shiftr(atable, stnum); 79614494Ssam rprint(atable,"atable",stnum+1); 79714494Ssam return; 79814494Ssam } 79914494Ssam fprintf(fout,"# define YYTYPE %s\n",stnum+1 > NCH ? "int" : "char"); 80014494Ssam fprintf(fout,"struct yywork { YYTYPE verify, advance; } yycrank[] ={\n"); 80114494Ssam for(i=0;i<=yytop;i+=4){ 80214494Ssam for(j=0;j<4;j++){ 80314494Ssam k = i+j; 80414494Ssam if(verify[k]) 80514494Ssam fprintf(fout,"%d,%d,\t",verify[k],advance[k]); 80614494Ssam else 80714494Ssam fprintf(fout,"0,0,\t"); 80814494Ssam } 80914494Ssam putc('\n',fout); 81014494Ssam } 81114494Ssam fprintf(fout,"0,0};\n"); 81214494Ssam 81314494Ssam /* put out yysvec */ 81414494Ssam 81514494Ssam fprintf(fout,"struct yysvf yysvec[] ={\n"); 81614494Ssam fprintf(fout,"0,\t0,\t0,\n"); 81714494Ssam for(i=0;i<=stnum;i++){ /* for each state */ 81814494Ssam if(cpackflg[i])stoff[i] = -stoff[i]; 81914494Ssam fprintf(fout,"yycrank+%d,\t",stoff[i]); 82014494Ssam if(sfall[i] != -1) 82114494Ssam fprintf(fout,"yysvec+%d,\t", sfall[i]+1); /* state + 1 */ 82214494Ssam else fprintf(fout,"0,\t\t"); 82314494Ssam if(atable[i] != -1) 82414494Ssam fprintf(fout,"yyvstop+%d,",atable[i]); 82514494Ssam else fprintf(fout,"0,\t"); 82614494Ssam # ifdef DEBUG 82714494Ssam fprintf(fout,"\t\t/* state %d */",i); 82814494Ssam # endif 82914494Ssam putc('\n',fout); 83014494Ssam } 83114494Ssam fprintf(fout,"0,\t0,\t0};\n"); 83214494Ssam 83314494Ssam /* put out yymatch */ 83414494Ssam 83514494Ssam fprintf(fout,"struct yywork *yytop = yycrank+%d;\n",yytop); 83614494Ssam fprintf(fout,"struct yysvf *yybgin = yysvec+1;\n"); 83714494Ssam if(optim){ 83814494Ssam fprintf(fout,"char yymatch[] ={\n"); 83914494Ssam if (chset==0) /* no chset, put out in normal order */ 84014494Ssam { 84114494Ssam for(i=0; i<NCH; i+=8){ 84214494Ssam for(j=0; j<8; j++){ 84314494Ssam int fbch; 84414494Ssam fbch = match[i+j]; 84514494Ssam if(printable(fbch) && fbch != '\'' && fbch != '\\') 84614494Ssam fprintf(fout,"'%c' ,",fbch); 84714494Ssam else fprintf(fout,"0%-3o,",fbch); 84814494Ssam } 84914494Ssam putc('\n',fout); 85014494Ssam } 85114494Ssam } 85214494Ssam else 85314494Ssam { 85414494Ssam int *fbarr; 855*33343Sbostic fbarr = (int *)myalloc(2*NCH, sizeof(*fbarr)); 85614494Ssam if (fbarr==0) 85714494Ssam error("No space for char table reverse",0); 85814494Ssam for(i=0; i<ZCH; i++) 85914494Ssam fbarr[i]=0; 86014494Ssam for(i=0; i<NCH; i++) 86114494Ssam fbarr[ctable[i]] = ctable[match[i]]; 86214494Ssam for(i=0; i<ZCH; i+=8) 86314494Ssam { 86414494Ssam for(j=0; j<8; j++) 86514494Ssam fprintf(fout, "0%-3o,",fbarr[i+j]); 86614494Ssam putc('\n',fout); 86714494Ssam } 86814494Ssam cfree(fbarr, 2*NCH, 1); 86914494Ssam } 87014494Ssam fprintf(fout,"0};\n"); 87114494Ssam } 87214494Ssam /* put out yyextra */ 87314494Ssam fprintf(fout,"char yyextra[] ={\n"); 87414494Ssam for(i=0;i<casecount;i+=8){ 87514494Ssam for(j=0;j<8;j++) 87614494Ssam fprintf(fout, "%d,", i+j<NACTIONS ? 87714494Ssam extra[i+j] : 0); 87814494Ssam putc('\n',fout); 87914494Ssam } 88014494Ssam fprintf(fout,"0};\n"); 88114494Ssam return; 88214494Ssam } 88314494Ssam rprint(a,s,n) 88414494Ssam char *s; 88514494Ssam int *a, n; { 88614494Ssam register int i; 88714494Ssam fprintf(fout,"block data\n"); 88814494Ssam fprintf(fout,"common /L%s/ %s\n",s,s); 88914494Ssam fprintf(fout,"define S%s %d\n",s,n); 89014494Ssam fprintf(fout,"integer %s (S%s)\n",s,s); 89114494Ssam for(i=1; i<=n; i++) 89214494Ssam { 89314494Ssam if (i%8==1) fprintf(fout, "data "); 89414494Ssam fprintf(fout, "%s (%d)/%d/",s,i,a[i]); 89514494Ssam fprintf(fout, (i%8 && i<n) ? ", " : "\n"); 89614494Ssam } 89714494Ssam fprintf(fout,"end\n"); 89814494Ssam } 89914494Ssam shiftr(a, n) 90014494Ssam int *a; 90114494Ssam { 90214494Ssam int i; 90314494Ssam for(i=n; i>=0; i--) 90414494Ssam a[i+1]=a[i]; 90514494Ssam } 90614494Ssam upone(a,n) 90714494Ssam int *a; 90814494Ssam { 90914494Ssam int i; 91014494Ssam for(i=0; i<=n ; i++) 91114494Ssam a[i]++; 91214494Ssam } 91314494Ssam bprint(a,s,n) 91414494Ssam char *s, *a; 91514494Ssam int n; { 91614494Ssam register int i, j, k; 91714494Ssam fprintf(fout,"block data\n"); 91814494Ssam fprintf(fout,"common /L%s/ %s\n",s,s); 91914494Ssam fprintf(fout,"define S%s %d\n",s,n); 92014494Ssam fprintf(fout,"integer %s (S%s)\n",s,s); 92114494Ssam for(i=1;i<n;i+=8){ 92214494Ssam fprintf(fout,"data %s (%d)/%d/",s,i,a[i]); 92314494Ssam for(j=1;j<8;j++){ 92414494Ssam k = i+j; 92514494Ssam if(k < n)fprintf(fout,", %s (%d)/%d/",s,k,a[k]); 92614494Ssam } 92714494Ssam putc('\n',fout); 92814494Ssam } 92914494Ssam fprintf(fout,"end\n"); 93014494Ssam } 93114494Ssam # ifdef PP 93214494Ssam padd(array,n) 93314494Ssam int **array; 93414494Ssam int n; { 93514494Ssam register int i, *j, k; 93614494Ssam array[n] = nxtpos; 93714494Ssam if(count == 0){ 93814494Ssam *nxtpos++ = 0; 93914494Ssam return; 94014494Ssam } 94114494Ssam for(i=tptr-1;i>=0;i--){ 94214494Ssam j = array[i]; 94314494Ssam if(j && *j++ == count){ 94414494Ssam for(k=0;k<count;k++) 94514494Ssam if(!tmpstat[*j++])break; 94614494Ssam if(k >= count){ 94714494Ssam array[n] = array[i]; 94814494Ssam return; 94914494Ssam } 95014494Ssam } 95114494Ssam } 95214494Ssam add(array,n); 95314494Ssam return; 95414494Ssam } 95514494Ssam # endif 956