📄 sub2.c
字号:
# 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 DEBUGpfoll() { 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; }# endifadd(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++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -