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