|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.