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