852 lines
17 KiB
C
852 lines
17 KiB
C
# include "ldefs.h"
|
|
void
|
|
cfoll(int v)
|
|
{
|
|
int i,j,k;
|
|
uchar *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 = ptr[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");
|
|
ptr[v] = p;
|
|
name[v] = RCCL; /* RNCCL eliminated */
|
|
# ifdef DEBUG
|
|
if(debug && *p){
|
|
print("ccl %d: %d",v,*p++);
|
|
while(*p)
|
|
print(", %d",*p++);
|
|
print("\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
|
|
}
|
|
}
|
|
|
|
# ifdef DEBUG
|
|
void
|
|
pfoll(void)
|
|
{
|
|
int i,k,*p;
|
|
int j;
|
|
/* print sets of chars which may follow positions */
|
|
print("pos\tchars\n");
|
|
for(i=0;i<tptr;i++)
|
|
if(p=foll[i]){
|
|
j = *p++;
|
|
if(j >= 1){
|
|
print("%d:\t%d",i,*p++);
|
|
for(k=2;k<=j;k++)
|
|
print(", %d",*p++);
|
|
print("\n");
|
|
}
|
|
}
|
|
}
|
|
# endif
|
|
|
|
void
|
|
add(int **array, int n)
|
|
{
|
|
int i, *temp;
|
|
uchar *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":""));
|
|
}
|
|
|
|
void
|
|
follow(int v)
|
|
{
|
|
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
|
|
}
|
|
}
|
|
|
|
void
|
|
first(int v) /* calculate set of positions with v as root which can be active initially */
|
|
{
|
|
int i;
|
|
uchar *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 = (uchar *)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
|
|
}
|
|
}
|
|
|
|
void
|
|
cgoto(void)
|
|
{
|
|
int i, j, s;
|
|
int npos, curpos, n;
|
|
int tryit;
|
|
uchar tch[NCH];
|
|
int tst[NCH];
|
|
uchar *q;
|
|
|
|
/* generate initial state, for each start condition */
|
|
Bprint(&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)
|
|
print("%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 = ptr[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){
|
|
print("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;
|
|
print("\n\t");
|
|
}
|
|
}
|
|
print("\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;
|
|
}
|
|
Bprint(&fout,"0};\n");
|
|
}
|
|
|
|
/* Beware -- 70% of total CPU time is spent in this subroutine -
|
|
if you don't believe me - try it yourself ! */
|
|
void
|
|
nextstate(int s, int c)
|
|
{
|
|
int j, *newpos;
|
|
uchar *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, ptr[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;
|
|
}
|
|
|
|
int
|
|
notin(int n)
|
|
{ /* see if tmpstat occurs previously */
|
|
int *j,k;
|
|
uchar *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);
|
|
}
|
|
|
|
void
|
|
packtrans(int st, uchar *tch, int *tst, int cnt, int tryit)
|
|
{
|
|
/* 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 i,j,k;
|
|
int cmin, cval, tcnt, diff, p, *ast;
|
|
uchar *ach;
|
|
int go[NCH], temp[NCH], c;
|
|
int swork[NCH];
|
|
uchar cwork[NCH];
|
|
int upper;
|
|
|
|
rcount += cnt;
|
|
cmin = -1;
|
|
cval = NCH;
|
|
ast = tst;
|
|
ach = tch;
|
|
/* try to pack transitions using ccl's */
|
|
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) print("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;
|
|
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)print("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":""));
|
|
}
|
|
|
|
# ifdef DEBUG
|
|
void
|
|
pstate(int s)
|
|
{
|
|
int *p,i,j;
|
|
print("State %d:\n",s);
|
|
p = state[s];
|
|
i = *p++;
|
|
if(i == 0) return;
|
|
print("%4d",*p++);
|
|
for(j = 1; j<i; j++){
|
|
print(", %4d",*p++);
|
|
if(j%30 == 0)print("\n");
|
|
}
|
|
print("\n");
|
|
}
|
|
# endif
|
|
|
|
int
|
|
member(int d, uchar *t)
|
|
{
|
|
int c;
|
|
uchar *s;
|
|
|
|
c = d;
|
|
s = t;
|
|
c = cindex[c];
|
|
while(*s)
|
|
if(*s++ == c) return(1);
|
|
return(0);
|
|
}
|
|
|
|
# ifdef DEBUG
|
|
void
|
|
stprt(int i)
|
|
{
|
|
int p, t;
|
|
|
|
print("State %d:",i);
|
|
/* print actions, if any */
|
|
t = atable[i];
|
|
if(t != -1)print(" final");
|
|
print("\n");
|
|
if(cpackflg[i] == TRUE)print("backup char in use\n");
|
|
if(sfall[i] != -1)print("fall back state %d\n",sfall[i]);
|
|
p = gotof[i];
|
|
if(p == -1) return;
|
|
print("(%d transitions)\n",nexts[p]);
|
|
while(nchar[p]){
|
|
charc = 0;
|
|
if(nexts[p+1] >= 0)
|
|
print("%d\t",nexts[p+1]);
|
|
else print("err\t");
|
|
allprint(nchar[p++]);
|
|
while(nexts[p] == nexts[p+1] && nchar[p]){
|
|
if(charc > LINESIZE){
|
|
charc = 0;
|
|
print("\n\t");
|
|
}
|
|
allprint(nchar[p++]);
|
|
}
|
|
print("\n");
|
|
}
|
|
print("\n");
|
|
}
|
|
# endif
|
|
|
|
void
|
|
acompute(int s) /* compute action list = set of poss. actions */
|
|
{
|
|
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) print("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
|
|
Bprint(&fout,"/* actions for state %d */",s);
|
|
# endif
|
|
Bputc(&fout, '\n');
|
|
for(i=0;i<k;i++)
|
|
if(temp[i] != 0){
|
|
Bprint(&fout,"%d,\n",temp[i]);
|
|
# ifdef DEBUG
|
|
if(debug)
|
|
print("%d ",temp[i]);
|
|
# endif
|
|
aptr++;
|
|
}
|
|
for(i=0;i<n;i++){ /* copy fall back actions - all neg */
|
|
Bprint(&fout,"%d,\n",neg[i]);
|
|
aptr++;
|
|
# ifdef DEBUG
|
|
if(debug)print("%d ",neg[i]);
|
|
# endif
|
|
}
|
|
# ifdef DEBUG
|
|
if(debug)print("\n");
|
|
# endif
|
|
Bprint(&fout,"0,\n");
|
|
aptr++;
|
|
}
|
|
|
|
# ifdef DEBUG
|
|
void
|
|
pccl(void) {
|
|
/* print character class sets */
|
|
int i, j;
|
|
|
|
print("char class intersection\n");
|
|
for(i=0; i< ccount; i++){
|
|
charc = 0;
|
|
print("class %d:\n\t",i);
|
|
for(j=1;j<NCH;j++)
|
|
if(cindex[j] == i){
|
|
allprint(j);
|
|
if(charc > LINESIZE){
|
|
print("\n\t");
|
|
charc = 0;
|
|
}
|
|
}
|
|
print("\n");
|
|
}
|
|
charc = 0;
|
|
print("match:\n");
|
|
for(i=0;i<NCH;i++){
|
|
allprint(match[i]);
|
|
if(charc > LINESIZE){
|
|
print("\n");
|
|
charc = 0;
|
|
}
|
|
}
|
|
print("\n");
|
|
}
|
|
# endif
|
|
|
|
void
|
|
mkmatch(void)
|
|
{
|
|
int i;
|
|
uchar 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]];
|
|
}
|
|
|
|
void
|
|
layout(void)
|
|
{
|
|
/* format and output final program's tables */
|
|
int i, j, k;
|
|
int top, bot, startup, omin;
|
|
|
|
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;
|
|
# ifdef DEBUG
|
|
if (debug) {
|
|
print("State %d: (layout)\n", i);
|
|
for(j=bot; j<=top;j++) {
|
|
print(" %o", nchar[j]);
|
|
if (j%10==0) print("\n");
|
|
}
|
|
print("\n");
|
|
}
|
|
# endif
|
|
while(verify[omin+NCH]) omin++;
|
|
startup = omin;
|
|
# ifdef DEBUG
|
|
if (debug) print("bot,top %d, %d startup begins %d\n",bot,top,startup);
|
|
# endif
|
|
do {
|
|
startup += 1;
|
|
if(startup > outsize - NCH)
|
|
error("output table overflow");
|
|
for(j = bot; j<= top; j++){
|
|
k = startup + nchar[j];
|
|
if(verify[k])break;
|
|
}
|
|
} while (j <= top);
|
|
/* have found place */
|
|
# ifdef DEBUG
|
|
if (debug) print(" 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 */
|
|
Bprint(&fout,"# define YYTYPE %s\n",stnum+1 >= NCH ? "int" : "Uchar");
|
|
Bprint(&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])
|
|
Bprint(&fout,"%d,%d,\t",verify[k],advance[k]);
|
|
else
|
|
Bprint(&fout,"0,0,\t");
|
|
}
|
|
Bputc(&fout, '\n');
|
|
}
|
|
Bprint(&fout,"0,0};\n");
|
|
|
|
/* put out yysvec */
|
|
|
|
Bprint(&fout,"struct yysvf yysvec[] = {\n");
|
|
Bprint(&fout,"0,\t0,\t0,\n");
|
|
for(i=0;i<=stnum;i++){ /* for each state */
|
|
if(cpackflg[i])stoff[i] = -stoff[i];
|
|
Bprint(&fout,"yycrank+%d,\t",stoff[i]);
|
|
if(sfall[i] != -1)
|
|
Bprint(&fout,"yysvec+%d,\t", sfall[i]+1); /* state + 1 */
|
|
else Bprint(&fout,"0,\t\t");
|
|
if(atable[i] != -1)
|
|
Bprint(&fout,"yyvstop+%d,",atable[i]);
|
|
else Bprint(&fout,"0,\t");
|
|
# ifdef DEBUG
|
|
Bprint(&fout,"\t\t/* state %d */",i);
|
|
# endif
|
|
Bputc(&fout, '\n');
|
|
}
|
|
Bprint(&fout,"0,\t0,\t0};\n");
|
|
|
|
/* put out yymatch */
|
|
|
|
Bprint(&fout,"struct yywork *yytop = yycrank+%d;\n",yytop);
|
|
Bprint(&fout,"struct yysvf *yybgin = yysvec+1;\n");
|
|
Bprint(&fout,"Uchar yymatch[] = {\n");
|
|
for(i=0; i<NCH; i+=8){
|
|
for(j=0; j<8; j++){
|
|
int fbch;
|
|
fbch = match[i+j];
|
|
if(isprint(fbch) && fbch != '\'' && fbch != '\\')
|
|
Bprint(&fout,"'%c' ,",fbch);
|
|
else Bprint(&fout,"0%-3o,",fbch);
|
|
}
|
|
Bputc(&fout, '\n');
|
|
}
|
|
Bprint(&fout,"0};\n");
|
|
/* put out yyextra */
|
|
Bprint(&fout,"Uchar yyextra[] = {\n");
|
|
for(i=0;i<casecount;i+=8){
|
|
for(j=0;j<8;j++)
|
|
Bprint(&fout, "%d,", i+j<NACTIONS ?
|
|
extra[i+j] : 0);
|
|
Bputc(&fout, '\n');
|
|
}
|
|
Bprint(&fout,"0};\n");
|
|
}
|
|
|
|
# ifdef PP
|
|
void
|
|
padd(int **array, int n)
|
|
{
|
|
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);
|
|
}
|
|
# endif
|