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