static char sccsid
[] = "@(#)sub2.c 4.1 (Berkeley) %G%";
if(i
< NCH
) i
= 1; /* character */
case 1: case RSTR
: case RCCL
: case RNCCL
: case RNULLS
:
padd(foll
,v
); /* packing version */
add(foll
,v
); /* no packing version */
if(i
== RSTR
) cfoll(left
[v
]);
else if(i
== RCCL
|| i
== RNCCL
){ /* compress ccl list */
symbol
[*p
++] = (i
== RCCL
);
for(k
=0;p
+k
< pcptr
; k
++)
if(p
+k
>= pcptr
)*pcptr
++ = cindex
[j
];
if(pcptr
> pchar
+ pchlen
)
error("Too many packed character classes");
name
[v
] = RCCL
; /* RNCCL eliminated */
printf("ccl %d: %d",v
,*p
++);
case STAR
: case PLUS
: case QUEST
: case RSCON
:
case BAR
: case RCAT
: case DIV
: case RNEWE
:
warning("bad switch cfoll %d",v
);
/* print sets of chars which may follow positions */
printf("%d:\t%d",i
,*p
++);
array
[n
] = nxtpos
; /* note no packing is done in positions */
if(nxtpos
>= positions
+maxpos
)
error("Too many positions %s",(maxpos
== MAXPOS
?"\nTry using %p num":""));
/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
case BAR
: case QUEST
: case RNEWE
:
warning("bad switch follow %d",p
);
first(v
) /* calculate set of positions with v as root which can be active initially */
case 1: case RCCL
: case RNCCL
: case RNULLS
: case FINAL
: case S1FINAL
: case S2FINAL
:
case STAR
: case QUEST
: case PLUS
: case RSTR
:
warning("bad switch first %d",v
);
/* generate initial state, for each start condition */
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;
if(tptr
> 0)first(tptr
-1);
printf("%s:\n",sname
[stnum
/2]);
/* 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
++){
for(i
=0;i
<NCH
;i
++) symbol
[i
] = 0;
for(i
= 1; i
<=npos
; i
++){
if(name
[curpos
] < NCH
) symbol
[name
[curpos
]] = TRUE
;
else switch(name
[curpos
]){
symbol
[right
[curpos
]] = TRUE
;
warning("bad switch cgoto %d state %d",curpos
,s
);
printf("State %d transitions on:\n\t",s
);
if(symbol
[i
]) allprint(i
);
/* for each char, calculate next state */
nextstate(s
,i
); /* executed for each state, transition pair */
if(xstate
== -2) warning("bad state %d %o",s
,i
);
error("Too many states %s",(nstates
== NSTATES
? "\nTry using %n num":""));
else { /* xstate >= 0 ==> state exists */
/* pack transitions into permanent array */
if(n
> 0) packtrans(s
,tch
,tst
,n
,tryit
);
ratfor
? fprintf(fout
,"end\n") : fprintf(fout
,"0};\n");
/* Beware -- 70% of total CPU time is spent in this subroutine -
if you don't believe me - try it yourself ! */
register char *temp
, *tz
;
int *pos
, i
, *f
, num
, curpos
, number
;
/* state to goto from state s on char c */
|| j
== RSTR
&& c
== right
[curpos
]
|| j
== RCCL
&& member(c
,left
[curpos
])){
int n
; { /* see if tmpstat occurs previously */
for(i
=n
;i
>=0;i
--){ /* for each state */
packtrans(st
,tch
,tst
,cnt
,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 cmin
, cval
, tcnt
, diff
, p
, *ast
;
int go
[NCH
], temp
[NCH
], c
;
/* try to pack transitions using ccl's */
if(!optim
)goto nopack
; /* skip all compaction */
if(tryit
){ /* ccl's used */
if(go
[c
] != tst
[i
] || c
== tch
[i
])
/* fill in error entries */
if(symbol
[i
]) temp
[i
] = -2; /* error trans */
if(k
<cnt
){ /* compress by char */
if(debug
) printf("use compression %d, %d vs %d\n",st
,k
,cnt
);
swork
[k
++] = (temp
[i
] == -2 ? -1 : temp
[i
]);
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;
if(p
== -1) /* no transitions */ continue;
while(ach
[j
] && p
< upper
){
while(ach
[j
] < nchar
[p
] && ach
[j
]){diff
++; j
++; }
if(ach
[j
] > nchar
[p
]){diff
=NCH
;break;}
if(ast
[j
] != nexts
[++p
] || ast
[j
] == -1 || (cpackflg
[st
] && ach
[j
] != match
[ach
[j
]]))diff
++;
if(diff
< cval
&& diff
< tcnt
){
/* cmin = state "most like" state st */
if(debug
)printf("select st %d for st %d diff %d\n",cmin
,st
,cval
);
if(cmin
!= -1){ /* if we can use st cmin */
/* 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
]){
if(nchar
[p
-1] == 0)break;
warning("bad transition %d %d",st
,cmin
);
/* ach[j] == nchar[p-1] */
if(ast
[j
] != nexts
[p
] || ast
[j
] == -1 || (cpackflg
[st
] && ach
[j
] != match
[ach
[j
]])){
nexts
[++nptr
] = ast
[j
++];
nexts
[gotof
[st
]] = cnt
= k
;
error("Too many transitions %s",(ntrans
==NTRANS
?"\nTry using %a num":""));
if(j
%30 == 0)putchar('\n');
/* print actions, if any */
if(t
!= -1)printf(" final");
if(cpackflg
[i
] == TRUE
)printf("backup char in use\n");
if(sfall
[i
] != -1)printf("fall back state %d\n",sfall
[i
]);
printf("(%d transitions)\n",nexts
[p
]);
printf("%d\t",nexts
[p
+1]);
while(nexts
[p
] == nexts
[p
+1] && nchar
[p
]){
acompute(s
) /* compute action list = set of poss. actions */
int temp
[300], k
, neg
[300], n
;
error("Too many positions for one state - acompute");
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");
else if(name
[*p
] == S2FINAL
)neg
[n
++] = left
[*p
];
if(k
< 1 && n
< 1) return;
if(debug
) printf("final %d actions:",s
);
if(temp
[i
] == temp
[i
+1]) temp
[i
] = 0;
/* copy to permanent quarters */
if(!ratfor
)fprintf(fout
,"/* actions for state %d */",s
);
ratfor
? fprintf(fout
,"data vstop(%d)/%d/\n",aptr
,temp
[i
]) : fprintf(fout
,"%d,\n",temp
[i
]);
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
]);
if(debug
)printf("%d ",neg
[i
]);
ratfor
? fprintf(fout
,"data vstop (%d)/0/\n",aptr
) : fprintf(fout
,"0,\n");
/* print character class sets */
printf("char class intersection\n");
for(i
=0; i
< ccount
; i
++){
printf("class %d:\n\t",i
);
/* tab[i] = principal char for new ccl i */
match
[i
] = tab
[cindex
[i
]];
/* format and output final program's tables */
int top
, bot
, startup
, omin
;
verify
[i
] = advance
[i
] = 0;
for(i
=0; i
<= stnum
; i
++){ /* for each state */
printf("State %d: (layout)\n", i
);
if (j
%10==0) putchar('\n');
while(verify
[omin
+ZCH
]) omin
++;
if (debug
) printf("bot,top %d, %d startup begins %d\n",bot
,top
,startup
);
if(startup
> outsize
- ZCH
)
error("output table overflow");
for(j
= bot
; j
<= top
; j
++){
k
=startup
+ctable
[nchar
[j
]];
if (debug
) printf(" startup will be %d\n",startup
);
for(j
= bot
; j
<= top
; j
++){
k
= startup
+ ctable
[nchar
[j
]];
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(startup
> outsize
- ZCH
)
error("output table overflow");
for(j
= bot
; j
<= top
; j
++){
if (debug
) printf(" startup going to be %d\n", startup
);
for(j
= bot
; j
<= top
; j
++){
verify
[k
] = i
+1; /* state number + 1*/
advance
[k
] = nexts
[j
+1]+1; /* state number + 1*/
/* stoff[i] = offset into verify, advance for trans for state i */
fprintf(fout
, "define YYTOPVAL %d\n", yytop
);
rprint(verify
,"verif",yytop
+1);
rprint(advance
,"advan",yytop
+1);
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
);
rprint(atable
,"atable",stnum
+1);
fprintf(fout
,"# define YYTYPE %s\n",stnum
+1 > NCH
? "int" : "char");
fprintf(fout
,"struct yywork { YYTYPE verify, advance; } yycrank[] ={\n");
fprintf(fout
,"%d,%d,\t",verify
[k
],advance
[k
]);
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
]);
fprintf(fout
,"yysvec+%d,\t", sfall
[i
]+1); /* state + 1 */
else fprintf(fout
,"0,\t\t");
fprintf(fout
,"yyvstop+%d,",atable
[i
]);
else fprintf(fout
,"0,\t");
fprintf(fout
,"\t\t/* state %d */",i
);
fprintf(fout
,"0,\t0,\t0};\n");
fprintf(fout
,"struct yywork *yytop = yycrank+%d;\n",yytop
);
fprintf(fout
,"struct yysvf *yybgin = yysvec+1;\n");
fprintf(fout
,"char yymatch[] ={\n");
if (chset
==0) /* no chset, put out in normal order */
if(printable(fbch
) && fbch
!= '\'' && fbch
!= '\\')
fprintf(fout
,"'%c' ,",fbch
);
else fprintf(fout
,"0%-3o,",fbch
);
fbarr
= myalloc(2*NCH
, sizeof(*fbarr
));
error("No space for char table reverse",0);
fbarr
[ctable
[i
]] = ctable
[match
[i
]];
fprintf(fout
, "0%-3o,",fbarr
[i
+j
]);
fprintf(fout
,"char yyextra[] ={\n");
for(i
=0;i
<casecount
;i
+=8){
fprintf(fout
, "%d,", i
+j
<NACTIONS
?
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
);
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
,"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
);
fprintf(fout
,"data %s (%d)/%d/",s
,i
,a
[i
]);
if(k
< n
)fprintf(fout
,", %s (%d)/%d/",s
,k
,a
[k
]);