114494Ssam #ifndef lint
2*57660Sbostic static char sccsid[] = "@(#)sub2.c 4.4 (Berkeley) 01/22/93";
314494Ssam #endif
414494Ssam
514494Ssam # include "ldefs.c"
cfoll(v)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);
2933343Sbostic 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");
4333343Sbostic 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
pfoll()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
add(array,n)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 }
follow(v)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 }
first(v)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;
17633343Sbostic 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 }
cgoto()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;
24433343Sbostic 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 ! */
nextstate(s,c)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 }
notin(n)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 }
packtrans(st,tch,tst,cnt,tryit)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
pstate(s)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
member(d,t)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
stprt(i)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
acompute(s)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
pccl()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
mkmatch()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 }
layout()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;
85533343Sbostic 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 }
868*57660Sbostic free(fbarr);
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 }
rprint(a,s,n)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 }
shiftr(a,n)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 }
upone(a,n)90614494Ssam upone(a,n)
90714494Ssam int *a;
90814494Ssam {
90914494Ssam int i;
91014494Ssam for(i=0; i<=n ; i++)
91114494Ssam a[i]++;
91214494Ssam }
bprint(a,s,n)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
padd(array,n)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