1*10934Srrh #ifndef lint
2*10934Srrh static char sccsid[] = "@(#)y3.c 4.1 (Berkeley) 02/11/83";
3*10934Srrh #endif not lint
4*10934Srrh
5*10934Srrh # include "dextern"
6*10934Srrh
7*10934Srrh /* important local variables */
8*10934Srrh int lastred; /* the number of the last reduction of a state */
9*10934Srrh int defact[NSTATES]; /* the default actions of states */
10*10934Srrh
output()11*10934Srrh output(){ /* print the output for the states */
12*10934Srrh
13*10934Srrh int i, k, c;
14*10934Srrh register struct wset *u, *v;
15*10934Srrh
16*10934Srrh fprintf( ftable, "short yyexca[] ={\n" );
17*10934Srrh
18*10934Srrh SLOOP(i) { /* output the stuff for state i */
19*10934Srrh nolook = !(tystate[i]==MUSTLOOKAHEAD);
20*10934Srrh closure(i);
21*10934Srrh /* output actions */
22*10934Srrh nolook = 1;
23*10934Srrh aryfil( temp1, ntokens+nnonter+1, 0 );
24*10934Srrh WSLOOP(wsets,u){
25*10934Srrh c = *( u->pitem );
26*10934Srrh if( c>1 && c<NTBASE && temp1[c]==0 ) {
27*10934Srrh WSLOOP(u,v){
28*10934Srrh if( c == *(v->pitem) ) putitem( v->pitem+1, (struct looksets *)0 );
29*10934Srrh }
30*10934Srrh temp1[c] = state(c);
31*10934Srrh }
32*10934Srrh else if( c > NTBASE && temp1[ (c -= NTBASE) + ntokens ] == 0 ){
33*10934Srrh temp1[ c+ntokens ] = amem[indgo[i]+c];
34*10934Srrh }
35*10934Srrh }
36*10934Srrh
37*10934Srrh if( i == 1 ) temp1[1] = ACCEPTCODE;
38*10934Srrh
39*10934Srrh /* now, we have the shifts; look at the reductions */
40*10934Srrh
41*10934Srrh lastred = 0;
42*10934Srrh WSLOOP(wsets,u){
43*10934Srrh c = *( u->pitem );
44*10934Srrh if( c<=0 ){ /* reduction */
45*10934Srrh lastred = -c;
46*10934Srrh TLOOP(k){
47*10934Srrh if( BIT(u->ws.lset,k) ){
48*10934Srrh if( temp1[k] == 0 ) temp1[k] = c;
49*10934Srrh else if( temp1[k]<0 ){ /* reduce/reduce conflict */
50*10934Srrh if( foutput!=NULL )
51*10934Srrh fprintf( foutput,
52*10934Srrh "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s",
53*10934Srrh i, -temp1[k], lastred, symnam(k) );
54*10934Srrh if( -temp1[k] > lastred ) temp1[k] = -lastred;
55*10934Srrh ++zzrrconf;
56*10934Srrh }
57*10934Srrh else { /* potential shift/reduce conflict */
58*10934Srrh precftn( lastred, k, i );
59*10934Srrh }
60*10934Srrh }
61*10934Srrh }
62*10934Srrh }
63*10934Srrh }
64*10934Srrh wract(i);
65*10934Srrh }
66*10934Srrh
67*10934Srrh fprintf( ftable, "\t};\n" );
68*10934Srrh
69*10934Srrh wdef( "YYNPROD", nprod );
70*10934Srrh
71*10934Srrh }
72*10934Srrh
73*10934Srrh int pkdebug = 0;
apack(p,n)74*10934Srrh apack(p, n ) int *p;{ /* pack state i from temp1 into amem */
75*10934Srrh int off;
76*10934Srrh register *pp, *qq, *rr;
77*10934Srrh int *q, *r;
78*10934Srrh
79*10934Srrh /* we don't need to worry about checking because we
80*10934Srrh we will only look entries known to be there... */
81*10934Srrh
82*10934Srrh /* eliminate leading and trailing 0's */
83*10934Srrh
84*10934Srrh q = p+n;
85*10934Srrh for( pp=p,off=0 ; *pp==0 && pp<=q; ++pp,--off ) /* VOID */ ;
86*10934Srrh if( pp > q ) return(0); /* no actions */
87*10934Srrh p = pp;
88*10934Srrh
89*10934Srrh /* now, find a place for the elements from p to q, inclusive */
90*10934Srrh
91*10934Srrh r = &amem[ACTSIZE-1];
92*10934Srrh for( rr=amem; rr<=r; ++rr,++off ){ /* try rr */
93*10934Srrh for( qq=rr,pp=p ; pp<=q ; ++pp,++qq){
94*10934Srrh if( *pp != 0 ){
95*10934Srrh if( *pp != *qq && *qq != 0 ) goto nextk;
96*10934Srrh }
97*10934Srrh }
98*10934Srrh
99*10934Srrh /* we have found an acceptable k */
100*10934Srrh
101*10934Srrh if( pkdebug && foutput!=NULL ) fprintf( foutput, "off = %d, k = %d\n", off, rr-amem );
102*10934Srrh
103*10934Srrh for( qq=rr,pp=p; pp<=q; ++pp,++qq ){
104*10934Srrh if( *pp ){
105*10934Srrh if( qq > r ) error( "action table overflow" );
106*10934Srrh if( qq>memp ) memp = qq;
107*10934Srrh *qq = *pp;
108*10934Srrh }
109*10934Srrh }
110*10934Srrh if( pkdebug && foutput!=NULL ){
111*10934Srrh for( pp=amem; pp<= memp; pp+=10 ){
112*10934Srrh fprintf( foutput, "\t");
113*10934Srrh for( qq=pp; qq<=pp+9; ++qq ) fprintf( foutput, "%d ", *qq );
114*10934Srrh fprintf( foutput, "\n");
115*10934Srrh }
116*10934Srrh }
117*10934Srrh return( off );
118*10934Srrh
119*10934Srrh nextk: ;
120*10934Srrh }
121*10934Srrh error("no space in action table" );
122*10934Srrh /* NOTREACHED */
123*10934Srrh }
124*10934Srrh
go2out()125*10934Srrh go2out(){ /* output the gotos for the nontermninals */
126*10934Srrh int i, j, k, best, count, cbest, times;
127*10934Srrh
128*10934Srrh fprintf( ftemp, "$\n" ); /* mark begining of gotos */
129*10934Srrh
130*10934Srrh for( i=1; i<=nnonter; ++i ) {
131*10934Srrh go2gen(i);
132*10934Srrh
133*10934Srrh /* find the best one to make default */
134*10934Srrh
135*10934Srrh best = -1;
136*10934Srrh times = 0;
137*10934Srrh
138*10934Srrh for( j=0; j<=nstate; ++j ){ /* is j the most frequent */
139*10934Srrh if( tystate[j] == 0 ) continue;
140*10934Srrh if( tystate[j] == best ) continue;
141*10934Srrh
142*10934Srrh /* is tystate[j] the most frequent */
143*10934Srrh
144*10934Srrh count = 0;
145*10934Srrh cbest = tystate[j];
146*10934Srrh
147*10934Srrh for( k=j; k<=nstate; ++k ) if( tystate[k]==cbest ) ++count;
148*10934Srrh
149*10934Srrh if( count > times ){
150*10934Srrh best = cbest;
151*10934Srrh times = count;
152*10934Srrh }
153*10934Srrh }
154*10934Srrh
155*10934Srrh /* best is now the default entry */
156*10934Srrh
157*10934Srrh zzgobest += (times-1);
158*10934Srrh for( j=0; j<=nstate; ++j ){
159*10934Srrh if( tystate[j] != 0 && tystate[j]!=best ){
160*10934Srrh fprintf( ftemp, "%d,%d,", j, tystate[j] );
161*10934Srrh zzgoent += 1;
162*10934Srrh }
163*10934Srrh }
164*10934Srrh
165*10934Srrh /* now, the default */
166*10934Srrh
167*10934Srrh zzgoent += 1;
168*10934Srrh fprintf( ftemp, "%d\n", best );
169*10934Srrh
170*10934Srrh }
171*10934Srrh
172*10934Srrh
173*10934Srrh
174*10934Srrh }
175*10934Srrh
176*10934Srrh int g2debug = 0;
go2gen(c)177*10934Srrh go2gen(c){ /* output the gotos for nonterminal c */
178*10934Srrh
179*10934Srrh int i, work, cc;
180*10934Srrh struct item *p, *q;
181*10934Srrh
182*10934Srrh
183*10934Srrh /* first, find nonterminals with gotos on c */
184*10934Srrh
185*10934Srrh aryfil( temp1, nnonter+1, 0 );
186*10934Srrh temp1[c] = 1;
187*10934Srrh
188*10934Srrh work = 1;
189*10934Srrh while( work ){
190*10934Srrh work = 0;
191*10934Srrh PLOOP(0,i){
192*10934Srrh if( (cc=prdptr[i][1]-NTBASE) >= 0 ){ /* cc is a nonterminal */
193*10934Srrh if( temp1[cc] != 0 ){ /* cc has a goto on c */
194*10934Srrh cc = *prdptr[i]-NTBASE; /* thus, the left side of production i does too */
195*10934Srrh if( temp1[cc] == 0 ){
196*10934Srrh work = 1;
197*10934Srrh temp1[cc] = 1;
198*10934Srrh }
199*10934Srrh }
200*10934Srrh }
201*10934Srrh }
202*10934Srrh }
203*10934Srrh
204*10934Srrh /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
205*10934Srrh
206*10934Srrh if( g2debug && foutput!=NULL ){
207*10934Srrh fprintf( foutput, "%s: gotos on ", nontrst[c].name );
208*10934Srrh NTLOOP(i) if( temp1[i] ) fprintf( foutput, "%s ", nontrst[i].name);
209*10934Srrh fprintf( foutput, "\n");
210*10934Srrh }
211*10934Srrh
212*10934Srrh /* now, go through and put gotos into tystate */
213*10934Srrh
214*10934Srrh aryfil( tystate, nstate, 0 );
215*10934Srrh SLOOP(i){
216*10934Srrh ITMLOOP(i,p,q){
217*10934Srrh if( (cc= *p->pitem) >= NTBASE ){
218*10934Srrh if( temp1[cc -= NTBASE] ){ /* goto on c is possible */
219*10934Srrh tystate[i] = amem[indgo[i]+c];
220*10934Srrh break;
221*10934Srrh }
222*10934Srrh }
223*10934Srrh }
224*10934Srrh }
225*10934Srrh }
226*10934Srrh
precftn(r,t,s)227*10934Srrh precftn(r,t,s){ /* decide a shift/reduce conflict by precedence.
228*10934Srrh /* r is a rule number, t a token number */
229*10934Srrh /* the conflict is in state s */
230*10934Srrh /* temp1[t] is changed to reflect the action */
231*10934Srrh
232*10934Srrh int lp,lt, action;
233*10934Srrh
234*10934Srrh lp = levprd[r];
235*10934Srrh lt = toklev[t];
236*10934Srrh if( PLEVEL(lt) == 0 || PLEVEL(lp) == 0 ) {
237*10934Srrh /* conflict */
238*10934Srrh if( foutput != NULL ) fprintf( foutput, "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s",
239*10934Srrh s, temp1[t], r, symnam(t) );
240*10934Srrh ++zzsrconf;
241*10934Srrh return;
242*10934Srrh }
243*10934Srrh if( PLEVEL(lt) == PLEVEL(lp) ) action = ASSOC(lt);
244*10934Srrh else if( PLEVEL(lt) > PLEVEL(lp) ) action = RASC; /* shift */
245*10934Srrh else action = LASC; /* reduce */
246*10934Srrh
247*10934Srrh switch( action ){
248*10934Srrh
249*10934Srrh case BASC: /* error action */
250*10934Srrh temp1[t] = ERRCODE;
251*10934Srrh return;
252*10934Srrh
253*10934Srrh case LASC: /* reduce */
254*10934Srrh temp1[t] = -r;
255*10934Srrh return;
256*10934Srrh
257*10934Srrh }
258*10934Srrh }
259*10934Srrh
wract(i)260*10934Srrh wract(i){ /* output state i */
261*10934Srrh /* temp1 has the actions, lastred the default */
262*10934Srrh int p, p0, p1;
263*10934Srrh int ntimes, tred, count, j;
264*10934Srrh int flag;
265*10934Srrh
266*10934Srrh /* find the best choice for lastred */
267*10934Srrh
268*10934Srrh lastred = 0;
269*10934Srrh ntimes = 0;
270*10934Srrh TLOOP(j){
271*10934Srrh if( temp1[j] >= 0 ) continue;
272*10934Srrh if( temp1[j]+lastred == 0 ) continue;
273*10934Srrh /* count the number of appearances of temp1[j] */
274*10934Srrh count = 0;
275*10934Srrh tred = -temp1[j];
276*10934Srrh levprd[tred] |= REDFLAG;
277*10934Srrh TLOOP(p){
278*10934Srrh if( temp1[p]+tred == 0 ) ++count;
279*10934Srrh }
280*10934Srrh if( count >ntimes ){
281*10934Srrh lastred = tred;
282*10934Srrh ntimes = count;
283*10934Srrh }
284*10934Srrh }
285*10934Srrh
286*10934Srrh /* for error recovery, arrange that, if there is a shift on the
287*10934Srrh /* error recovery token, `error', that the default be the error action */
288*10934Srrh if( temp1[1] > 0 ) lastred = 0;
289*10934Srrh
290*10934Srrh /* clear out entries in temp1 which equal lastred */
291*10934Srrh TLOOP(p) if( temp1[p]+lastred == 0 )temp1[p]=0;
292*10934Srrh
293*10934Srrh wrstate(i);
294*10934Srrh defact[i] = lastred;
295*10934Srrh
296*10934Srrh flag = 0;
297*10934Srrh TLOOP(p0){
298*10934Srrh if( (p1=temp1[p0])!=0 ) {
299*10934Srrh if( p1 < 0 ){
300*10934Srrh p1 = -p1;
301*10934Srrh goto exc;
302*10934Srrh }
303*10934Srrh else if( p1 == ACCEPTCODE ) {
304*10934Srrh p1 = -1;
305*10934Srrh goto exc;
306*10934Srrh }
307*10934Srrh else if( p1 == ERRCODE ) {
308*10934Srrh p1 = 0;
309*10934Srrh goto exc;
310*10934Srrh exc:
311*10934Srrh if( flag++ == 0 ) fprintf( ftable, "-1, %d,\n", i );
312*10934Srrh fprintf( ftable, "\t%d, %d,\n", tokset[p0].value, p1 );
313*10934Srrh ++zzexcp;
314*10934Srrh }
315*10934Srrh else {
316*10934Srrh fprintf( ftemp, "%d,%d,", tokset[p0].value, p1 );
317*10934Srrh ++zzacent;
318*10934Srrh }
319*10934Srrh }
320*10934Srrh }
321*10934Srrh if( flag ) {
322*10934Srrh defact[i] = -2;
323*10934Srrh fprintf( ftable, "\t-2, %d,\n", lastred );
324*10934Srrh }
325*10934Srrh fprintf( ftemp, "\n" );
326*10934Srrh return;
327*10934Srrh }
328*10934Srrh
wrstate(i)329*10934Srrh wrstate(i){ /* writes state i */
330*10934Srrh register j0,j1;
331*10934Srrh register struct item *pp, *qq;
332*10934Srrh register struct wset *u;
333*10934Srrh
334*10934Srrh if( foutput == NULL ) return;
335*10934Srrh fprintf( foutput, "\nstate %d\n",i);
336*10934Srrh ITMLOOP(i,pp,qq) fprintf( foutput, "\t%s\n", writem(pp->pitem));
337*10934Srrh if( tystate[i] == MUSTLOOKAHEAD ){
338*10934Srrh /* print out empty productions in closure */
339*10934Srrh WSLOOP( wsets+(pstate[i+1]-pstate[i]), u ){
340*10934Srrh if( *(u->pitem) < 0 ) fprintf( foutput, "\t%s\n", writem(u->pitem) );
341*10934Srrh }
342*10934Srrh }
343*10934Srrh
344*10934Srrh /* check for state equal to another */
345*10934Srrh
346*10934Srrh TLOOP(j0) if( (j1=temp1[j0]) != 0 ){
347*10934Srrh fprintf( foutput, "\n\t%s ", symnam(j0) );
348*10934Srrh if( j1>0 ){ /* shift, error, or accept */
349*10934Srrh if( j1 == ACCEPTCODE ) fprintf( foutput, "accept" );
350*10934Srrh else if( j1 == ERRCODE ) fprintf( foutput, "error" );
351*10934Srrh else fprintf( foutput, "shift %d", j1 );
352*10934Srrh }
353*10934Srrh else fprintf( foutput, "reduce %d",-j1 );
354*10934Srrh }
355*10934Srrh
356*10934Srrh /* output the final production */
357*10934Srrh
358*10934Srrh if( lastred ) fprintf( foutput, "\n\t. reduce %d\n\n", lastred );
359*10934Srrh else fprintf( foutput, "\n\t. error\n\n" );
360*10934Srrh
361*10934Srrh /* now, output nonterminal actions */
362*10934Srrh
363*10934Srrh j1 = ntokens;
364*10934Srrh for( j0 = 1; j0 <= nnonter; ++j0 ){
365*10934Srrh if( temp1[++j1] ) fprintf( foutput, "\t%s goto %d\n", symnam( j0+NTBASE), temp1[j1] );
366*10934Srrh }
367*10934Srrh
368*10934Srrh }
369*10934Srrh
wdef(s,n)370*10934Srrh wdef( s, n ) char *s; { /* output a definition of s to the value n */
371*10934Srrh fprintf( ftable, "# define %s %d\n", s, n );
372*10934Srrh }
373*10934Srrh
warray(s,v,n)374*10934Srrh warray( s, v, n ) char *s; int *v, n; {
375*10934Srrh
376*10934Srrh register i;
377*10934Srrh
378*10934Srrh fprintf( ftable, "short %s[]={\n", s );
379*10934Srrh for( i=0; i<n; ){
380*10934Srrh if( i%10 == 0 ) fprintf( ftable, "\n" );
381*10934Srrh fprintf( ftable, "%4d", v[i] );
382*10934Srrh if( ++i == n ) fprintf( ftable, " };\n" );
383*10934Srrh else fprintf( ftable, "," );
384*10934Srrh }
385*10934Srrh }
386*10934Srrh
hideprod()387*10934Srrh hideprod(){
388*10934Srrh /* in order to free up the mem and amem arrays for the optimizer,
389*10934Srrh /* and still be able to output yyr1, etc., after the sizes of
390*10934Srrh /* the action array is known, we hide the nonterminals
391*10934Srrh /* derived by productions in levprd.
392*10934Srrh */
393*10934Srrh
394*10934Srrh register i, j;
395*10934Srrh
396*10934Srrh j = 0;
397*10934Srrh levprd[0] = 0;
398*10934Srrh PLOOP(1,i){
399*10934Srrh if( !(levprd[i] & REDFLAG) ){
400*10934Srrh ++j;
401*10934Srrh if( foutput != NULL ){
402*10934Srrh fprintf( foutput, "Rule not reduced: %s\n", writem( prdptr[i] ) );
403*10934Srrh }
404*10934Srrh }
405*10934Srrh levprd[i] = *prdptr[i] - NTBASE;
406*10934Srrh }
407*10934Srrh if( j ) fprintf( stdout, "%d rules never reduced\n", j );
408*10934Srrh }
409