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