|
|
1.1 root 1: /* (c) 1979 Regents of the University of California */
2: # include "ey.h"
3:
4: output(){ /* print the output for the states */
5:
6: int i, j, k, c;
7:
8: settab();
9: arrset("yyact");
10:
11: for( i=0; i<nstate; ++i ){ /* output the stuff for state i */
12: nolook = (tystate[i]==0);
13: closure(i);
14: /* output actions */
15: aryfil( temp1, nterms+1, 0 );
16: for( j=0; j<cwset; ++j ){ /* look at the items */
17: c = *( wsets[j].pitem );
18: if( c>0 && c<NTBASE && temp1[c]==0 ) temp1[c] = go2(i,c);
19: }
20:
21: if( i == 1 ) temp1[1] = ACCEPTCODE;
22:
23: /* now, we have the shifts; look at the reductions */
24:
25: lastred = 0;
26: for( j=0; j<cwset; ++j ){
27: c = *( wsets[j].pitem );
28: if( c<=0 ){ /* reduction */
29: lastred = -c;
30: for( k=1; k<=nterms; ++k ){
31: if( ((wsets[j].ws[k>>4])&(1<<(k&017))) != 0 ) {
32: if( temp1[k] == 0 ) temp1[k] = c;
33: else if( temp1[k]<0 ){ /* reduce/reduce conflict */
34: settty();
35: fprintf( cout , "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s",
36: i, -temp1[k], lastred, symnam(k) );
37: if( -temp1[k] > lastred ) temp1[k] = -lastred;
38: ++zzrrconf;
39: settab();
40: }
41: else { /* potential shift/reduce conflict */
42: switch( precftn( lastred, k ) ) {
43:
44: case 0: /* precedence does not apply */
45:
46: settty();
47: fprintf( cout , "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s", i,
48: temp1[k], lastred, symnam(k) );
49: ++zzsrconf;
50: settab();
51: break;
52:
53: case 1: /* reduce */
54:
55: temp1[k] = -lastred;
56: break;
57:
58: case 2: /* error, binary operator */
59:
60: temp1[k] = ERRCODE;
61: break;
62:
63: case 3: /* shift ... leave the entry alone */
64:
65: break;
66: }
67: }
68: }
69: }
70: }
71: }
72: wract(i);
73: }
74:
75: settab();
76: arrdone();
77:
78: /* now, output the pointers to the action array */
79: /* also output the info about reductions */
80: prred();
81: }
82:
83: prred(){ /* print the information about the actions and the reductions */
84: int index, i;
85:
86: arrset("yypact");
87: index = 1; /* position in the output table */
88:
89: for( i=0; i<nstate; ++i ){
90: if( tystate[i]>0 ){ /* the state is real */
91: temp1[i] = index;
92: arrval( index );
93: index += tystate[i];
94: }
95: else {
96: arrval( temp1[-tystate[i]] );
97: }
98: }
99:
100: arrdone();
101:
102: arrset("yyr1");
103: for( i=1; i<nprod; ++i ) arrval( *prdptr[i] - NTBASE );
104: arrdone();
105:
106: arrset("yyr2");
107: for( i=1; i<nprod; ++i ) arrval( ( prdptr[i+1]-prdptr[i]-2 ) );
108: arrdone();
109:
110: }
111:
112: go2(i,c){ /* do a goto on the closure state, not worrying about lookaheads */
113: if( c<NTBASE ) return( amem[ apstate[i]+c ] );
114: else return( amem[ apstate[i] + c - NTBASE + nterms ] );
115: }
116:
117: int pkdebug = 0;
118: apack(p, n ) int *p;{ /* pack state i from temp1 into amem */
119: _REGISTER k, l, off;
120: int j;
121:
122: /* find the spot */
123:
124: j = n;
125: for( off = 0; off <= j && p[off] == 0; ++off ) ;
126: if( off > j ){ /* no actions */
127: return(0);
128: }
129: j -= off;
130: for( k=0; k<actsiz; ++k ){
131: for( l=0; l<=j; ++l ){
132: if( p[off+l] != 0 ){
133: if( p[off+l] != amem[k+l] && amem[k+l] != 0 ) goto nextk;
134: }
135: }
136: if( pkdebug ){ settty(); fprintf( cout , "off = %d, k = %d\n", off, k ); }
137: /* we have found an acceptable k */
138: for( l=0; l<=j; ++l ){
139: if( p[off+l] ){
140: if( k+l >= actsiz ) error("action table overflow");
141: if( k+l >= memact ) memact = k+l;
142: amem[k+l] = p[off+l];
143: }
144: }
145: if( pkdebug ){
146: for( k=0; k<memact; k+=10){
147: fprintf( cout , "\t");
148: for( l=0; l<=9; ++l ) fprintf( cout , "%d ", amem[k+l] );
149: fprintf( cout , "\n");
150: }
151: }
152: return(k-off);
153:
154: nextk: ;
155: }
156: error("no space in action table");
157: }
158:
159: go2out(){ /* output the gotos for the nontermninals */
160: int i, j, k, best, offset, count, cbest, times;
161:
162: settab();
163: arrset("yygo");
164: offset = 1;
165:
166: for( i=1; i<=nnonter; ++i ) {
167: go2gen(i);
168:
169: /* find the best one to make default */
170:
171: temp2[i] = offset;
172:
173: best = -1;
174: times = 0;
175:
176: for( j=0; j<=nstate; ++j ){ /* is j the most frequent */
177: if( tystate[j] == 0 ) continue;
178: if( tystate[j] == best ) continue;
179:
180: /* is tystate[j] the most frequent */
181:
182: count = 0;
183: cbest = tystate[j];
184:
185: for( k=j; k<=nstate; ++k ) if( tystate[k]==cbest ) ++count;
186:
187: if( count > times ){
188: best = cbest;
189: times = count;
190: }
191: }
192:
193: /* best is now the default entry */
194:
195: zzgobest += (times-1)*2;
196: settab();
197: for( j=0; j<=nstate; ++j ){
198: if( tystate[j] != 0 && tystate[j]!=best ){
199: arrval( j );
200: arrval( tystate[j] );
201: offset += 2;
202: zzgoent += 2;
203: }
204: }
205:
206: /* now, the default */
207:
208: zzgoent += 2;
209: arrval( -1 );
210: arrval( best );
211: offset += 2;
212:
213: }
214:
215: arrdone();
216:
217: arrset("yypgo");
218: for( i=1; i<=nnonter; ++i ) arrval( temp2[i] );
219: arrdone();
220:
221: }
222:
223: int g2debug = 0;
224: go2gen(c){ /* output the gotos for nonterminal c */
225:
226: int i, work, cc;
227: struct item *p, *q;
228:
229: /* first, find nonterminals with gotos on c */
230:
231: aryfil( temp1, nnonter+1, 0 );
232: temp1[c] = 1;
233:
234: work = 1;
235: while( work ){
236: work = 0;
237: for( i=0; i<nprod; ++i ){
238: if( (cc=prdptr[i][1]-NTBASE) >= 0 ){ /* cc is a nonterminal */
239: if( temp1[cc] != 0 ){ /* cc has a goto on c */
240: cc = *prdptr[i]-NTBASE; /* thus, the left side of production i does too */
241: if( temp1[cc] == 0 ){
242: work = 1;
243: temp1[cc] = 1;
244: }
245: }
246: }
247: }
248: }
249:
250: /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
251:
252: if( g2debug ){
253: settty();
254: fprintf( cout , "%s: gotos on ", nontrst[c].name );
255: for( i=0; i<=nnonter; ++i ) if( temp1[i]) fprintf( cout , "%s ", nontrst[i].name);
256: fprintf( cout , "\n");
257: }
258:
259: /* now, go through and put gotos into tystate */
260:
261: aryfil( tystate, nstate, 0 );
262: settty();
263: fprintf( cout , "\nnonterminal %s\n", nontrst[c].name );
264: for( i=0; i<nstate; ++i ){
265: q = pstate[i+1];
266: for( p=pstate[i]; p<q; ++p ){
267: if( (cc= *p->pitem) >= NTBASE ){
268: if( temp1[cc -= NTBASE] ){ /* goto on c is possible */
269: tystate[i] = amem[indgo[i]+c];
270: break;
271: }
272: }
273: }
274: if( tystate[i] ) fprintf( cout , "\t%d\t%d\n", i, tystate[i]);
275: }
276: }
277:
278: precftn(r,t){ /* decide a shift/reduce conflict by precedence.
279: Returns 0 if action is 'do nothing',1 if action is reduce,
280: 2 if the action is 'error,binary operator'
281: and 3 if the action is 'reduce'. */
282:
283: int lp,lt;
284: lp = levprd[r];
285: lt = trmlev[t];
286: if ((lt==0)||((lp&03)==0))return(0);
287: if((lt>>3) == (lp>>3)){
288: return(lt&03);
289: }
290: if((lt>>3) > (lp>>3)) return(3);
291: return(1);
292: }
293:
294: int cdebug = 0; /* debug for common states */
295: wract(i){ /* output state i */
296: /* temp1 has the actions, lastred the default */
297: int p, p0, p1, size;
298: int ntimes, tred, count, j;
299: struct item *q0, *q1;
300:
301: /* find the best choice for lastred */
302:
303: lastred = 0;
304: ntimes = 0;
305: /***** UCB MOD - full state spec if shift on error *****/
306: if (temp1[2] <= 0)
307: for( j=1; j<=nterms; ++j ){
308: if( temp1[j] >= 0 ) continue;
309: if( temp1[j]+lastred == 0 ) continue;
310: /* count the number of appearances of temp1[j] */
311: count = 0;
312: tred = -temp1[j];
313: for( p=1; p<=nterms; ++p ){
314: if( temp1[p]+tred == 0 ) ++count;
315: }
316: if( count >ntimes ){
317: lastred = tred;
318: ntimes = count;
319: }
320: }
321:
322: /* clear out entries in temp1 which equal lastred */
323: for( p=1; p<= nterms; ++p ) if( temp1[p]+lastred == 0 )temp1[p]=0;
324:
325: /* write out the state */
326:
327: /* first, check for equality with another state */
328: /* see if there is a nonterminal with all dots before it. */
329:
330: p0 = 0;
331: q1 = pstate[i+1];
332: for( q0=pstate[i]; q0<q1; ++q0 ){
333: if( (p1= *(q0->pitem) ) < NTBASE ) goto standard;
334: if( p0 == 0 ) p0 = p1;
335: else if( p0 != p1 ) goto standard;
336: }
337:
338: /* now, all items have dots before p0 */
339: if( cdebug ){
340: settty();
341: fprintf( cout , "state %d, pre-nonterminal %s\n",i,nontrst[p0-NTBASE].name);
342: }
343:
344: for( j=0; j<i; ++j ){
345: if( apstate[i] != apstate[j] ) continue;
346:
347: /* equal positions -- check items */
348:
349: if( cdebug )fprintf( cout , "states %d and %d have equal positions\n",i,j);
350: q1 = pstate[j+1];
351: for( q0=pstate[j]; q0<q1; ++q0 ){
352: if( *(q0->pitem) != p0 ) goto nextj;
353: }
354:
355: /* we have a match with state j ! */
356:
357: tystate[i] = -j;
358: zzacsave += tystate[j];
359: zznsave++;
360: wrstate(i);
361: return;
362:
363: nextj: ;
364: }
365:
366:
367: standard:
368: tystate[i] = 2;
369: wrstate(i);
370:
371: size = 0;
372: for( p0=1; p0<=nterms; ++p0 )
373: if( (p1=temp1[p0])!=0 ) {
374: /***** UCB MOD - test actions are negative of symbol to be tested
375: this speeds up the parser as it is easy to check for
376: *****/
377: arrval( -trmset[p0].value );
378: if( p1 < 0 ) arrval( REDUCACT - p1 );
379: else if( p1 == ACCEPTCODE ) arrval( ACCEPTACT );
380: else if( p1 == ERRCODE ) arrval( ERRACT );
381: else arrval( SHIFTACT + p1 );
382: size += 2;
383: }
384: if( lastred ) arrval( REDUCACT + lastred );
385: else arrval( ERRACT );
386: tystate[i] = size+1; /* store entry size in tystate */
387: zzacent += (size+1);
388: return;
389: }
390:
391: wrstate(i){ /* writes state i */
392: int j0,j1,s;
393: struct item *pp, *qq;
394: settty();
395: fprintf( cout , "\nstate %d\n",i);
396: qq = pstate[i+1];
397: for( pp=pstate[i]; pp<qq; ++pp) fprintf( cout , "\t%s\n", writem(pp));
398:
399: /* check for state equal to another */
400:
401: if( tystate[i] <= 0 ){
402: fprintf( cout , "\n\tsame as %d\n\n", -tystate[i] );
403: return;
404: }
405:
406: for( j0=1; j0<=nterms; ++j0 ) if( (j1=temp1[j0]) != 0 ){
407: fprintf( cout , "\n\t%s ", symnam(j0) );
408: if( j1>0 ){ /* shift, error, or accept */
409: if( j1 == ACCEPTCODE ) fprintf( cout , "accept" );
410: else if( j1 == ERRCODE ) fprintf( cout , "error" );
411: else fprintf( cout , "shift %d", j1 );
412: }
413: else fprintf( cout , "reduce %d",-j1 );
414: }
415:
416: /* output the final production */
417:
418: if( lastred ) fprintf( cout , "\n\t. reduce %d\n\n", lastred );
419: else fprintf( cout , "\n\t. error\n\n" );
420:
421: ret:
422: settab();
423: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.