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