|
|
1.1 ! root 1: static char *sccsid = "@(#)ey3.c 4.2 (Berkeley) 8/30/82"; ! 2: /* (c) 1979 Regents of the University of California */ ! 3: # include "ey.h" ! 4: ! 5: cpres(){ /* conpute an array with the beginnings of productions yielding given nonterminals ! 6: The array pres points to these lists */ ! 7: int i,j,c; ! 8: pres = (int ***)yalloc(nnonter+1); ! 9: for(i=0;i<=nnonter;i++){ ! 10: c = i+NTBASE; ! 11: pres[i] = (int **)mem; ! 12: fatfl = 0; /* make undefined symbols nonfatal */ ! 13: for(j=0;j<nprod;j++) ! 14: if (*prdptr[j] == c) *mem++ = (int)(prdptr[j]+1); ! 15: if(pres[i] == (int **)mem){ ! 16: error("nonterminal %s not defined!", nontrst[i].name); ! 17: } ! 18: } ! 19: pres[i] = (int **)mem; ! 20: fatfl = 1; ! 21: if( nerrors ){ ! 22: summary(); ! 23: cexit(1); ! 24: } ! 25: } ! 26: ! 27: int indebug = 0; ! 28: cpfir() { ! 29: /* compute an array with the first of nonterminals */ ! 30: int i, ch, **s, **t, changes, *p; ! 31: ! 32: pfirst = (struct looksets **)yalloc(nnonter+1); ! 33: for (i=0;i<=nnonter;i++) { ! 34: aryfil( wsets[i].ws, tbitset, 0 ); ! 35: t = pres[i+1]; ! 36: for( s=pres[i]; s<t; ++s ){ /* initially fill the sets */ ! 37: for( p = *s; (ch = *p) > 0 ; ++p ) { ! 38: if( ch < NTBASE ) { ! 39: wsets[i].ws[ch>>4] |= (1 << (ch&017) ); ! 40: break; ! 41: } ! 42: else if( !pempty[ch-NTBASE] ) break; ! 43: } ! 44: } ! 45: } ! 46: ! 47: /* now, reflect transitivity */ ! 48: ! 49: changes = 1; ! 50: while( changes ){ ! 51: changes = 0; ! 52: for( i=0; i<=nnonter; ++i ){ ! 53: t = pres[i+1]; ! 54: for( s=pres[i]; s<t; ++s ){ ! 55: for( p = *s; ( ch = (*p-NTBASE) ) >= 0; ++p ) { ! 56: changes |= UNION( wsets[i].ws, wsets[i].ws, wsets[ch].ws ); ! 57: if( !pempty[ch] ) break; ! 58: } ! 59: } ! 60: } ! 61: } ! 62: ! 63: for( i=0; i<=nnonter; i++ ) pfirst[i] = flset( wsets[i].ws ); ! 64: if( !indebug ) return; ! 65: settty(); ! 66: for( i=0; i<=nnonter; i++ ){ ! 67: fprintf( cout , "\n%s: ", nontrst[i].name ); ! 68: prlook( pfirst[i] ); ! 69: fprintf( cout , " %d\n", pempty[i] ); ! 70: } ! 71: } ! 72: ! 73: state(c){ /* sorts last state,and sees if it equals earlier ones. returns state number */ ! 74: int *s,size1,size2; ! 75: struct looksets *lp; ! 76: _REGISTER i; ! 77: struct item *p1, *p2, *k, *l, *q1, *q2; ! 78: p1 = pstate[nstate]; ! 79: p2 = pstate[nstate+1]; ! 80: if(p1==p2) return(0); /* null state */ ! 81: /* sort the items */ ! 82: for(k=p2-1;k>p1;k--) { /* make k the biggest */ ! 83: for(l=k-1;l>=p1;--l)if( l->pitem > k->pitem ){ ! 84: s = k->pitem; ! 85: k->pitem = l->pitem; ! 86: l->pitem = s; ! 87: lp = k->look; ! 88: k->look = l->look; ! 89: l->look = lp; ! 90: } ! 91: } ! 92: size1 = p2 - p1; /* size of state */ ! 93: ! 94: for( i= (c>=NTBASE)?ntstates[c-NTBASE]:tstates[c]; i != 0; i = mstates[i] ) { ! 95: /* get ith state */ ! 96: q1 = pstate[i]; ! 97: q2 = pstate[i+1]; ! 98: size2 = q2 - q1; ! 99: if (size1 != size2) continue; ! 100: k=p1; ! 101: for(l=q1;l<q2;l++) { ! 102: if( l->pitem != k->pitem ) break; ! 103: ++k; ! 104: } ! 105: if (l != q2) continue; ! 106: /* found it */ ! 107: pstate[nstate+1] = pstate[nstate]; /* delete last state */ ! 108: /* fix up lookaheads */ ! 109: k=p1; ! 110: for( l=q1; l<q2; ++l ){ ! 111: if( UNION( clset.lset, l->look->lset, k->look->lset ) ) { ! 112: tystate[i] = 1; ! 113: /* register the new set */ ! 114: l->look = flset( &clset ); ! 115: } ! 116: ++k; ! 117: } ! 118: return (i); ! 119: } ! 120: /* state is new */ ! 121: pstate[nstate+2] = p2; ! 122: if(nstate+1 >= stsize) error("too many states"); ! 123: if( c >= NTBASE ){ ! 124: mstates[ nstate ] = ntstates[ c-NTBASE ]; ! 125: ntstates[ c-NTBASE ] = nstate; ! 126: } ! 127: else { ! 128: mstates[ nstate ] = tstates[ c ]; ! 129: tstates[ c ] = nstate; ! 130: } ! 131: tystate[nstate]=1; ! 132: return(nstate++); ! 133: } ! 134: ! 135: int pidebug = 0; /* debugging flag for putitem */ ! 136: putitem ( ptr, lptr ) int *ptr; struct looksets *lptr;{ ! 137: int *jip, k; ! 138: struct item *i, *j; ! 139: ! 140: if( pidebug ) { ! 141: settty(); ! 142: fprintf( cout , "putitem(%s), state %d\n", writem(&ptr), nstate ); ! 143: } ! 144: /* see if it's there */ ! 145: j = pstate[nstate+1]; ! 146: for( i=pstate[nstate]; i<j; ++i ) ! 147: if(i->pitem == ptr) { ! 148: error("yacc error--duplicate item"); ! 149: } ! 150: /* not there */ ! 151: j->pitem = ptr; ! 152: j->look = flset( lptr ); ! 153: pstate[nstate+1] = ++j; ! 154: jip = (int *)j; ! 155: if(jip-mem0 >= memsiz) error("out of state space"); ! 156: } ! 157: ! 158: cempty(){ /* mark nonterminals which derive the empty string */ ! 159: ! 160: int i, *p; ! 161: ! 162: /* set pempty to 0 */ ! 163: pempty = (char *)yalloc( nnonter / sizeof(int) + 1 ); ! 164: aryfil( pempty, nnonter+1, 0 ); ! 165: for( i=1; i<nprod; ++i ) /* loop over productions */ ! 166: if( prdptr[i][1] <= 0 ) /* i is empty production */ ! 167: pempty[ *prdptr[i]-NTBASE ] = 1; ! 168: ! 169: /* now, all explicitly empty nonterminals marked with pempty = 1 */ ! 170: ! 171: /* loop as long as we keep finding nontrivial empty nonterminals */ ! 172: ! 173: again: ! 174: for( i=1; i<nprod; ++i ){ ! 175: if( pempty[ *prdptr[i]-NTBASE ]==0 ){ /* not known to be empty */ ! 176: for( p=prdptr[i]+1; *p>=NTBASE && pempty[*p-NTBASE]!=0 ; ++p ) ; ! 177: if( *p < 0 ){ /* we have a nontrivially empty nonterminal */ ! 178: pempty[*prdptr[i]-NTBASE] = 1; ! 179: goto again; /* got one ... try for another */ ! 180: } ! 181: } ! 182: } ! 183: } ! 184: ! 185: int gsdebug = 0; ! 186: stagen(){ /* generate the states */ ! 187: ! 188: int i, j, k, c; ! 189: ! 190: /* initialize */ ! 191: ! 192: nstate = 0; ! 193: pstate[0] = pstate[1] = (struct item *)mem; ! 194: aryfil( clset.lset, tbitset, 0 ); ! 195: putitem( prdptr[0]+1, &clset ); ! 196: tystate[0] = 1; ! 197: nstate = 1; ! 198: pstate[2] = pstate[1]; ! 199: ! 200: memact = 0; ! 201: aryfil( amem, actsiz, 0 ); ! 202: ! 203: /* now, the main state generation loop */ ! 204: ! 205: more: ! 206: for( i=0; i<nstate; ++i ){ ! 207: /* if tystate == 2, set to zero */ ! 208: if( tystate[i] != 1 ) continue; ! 209: tystate[i] = 0; ! 210: aryfil( temp1, nterms+nnonter+1, 0 ); ! 211: /* take state i, close it, and do gotos */ ! 212: closure(i); ! 213: for( j=0; j<cwset; ++j ){ /* generate gotos */ ! 214: if( wsets[j].flag ) continue; ! 215: wsets[j].flag = 1; ! 216: c = *(wsets[j].pitem); ! 217: /* if no symbols after the dot (ie empty rule) */ ! 218: if( c <= 1 ) { ! 219: /* if not in kernel then tystate = 2 unless not done with it */ ! 220: if( pstate[i+1]-pstate[i] <= j ) tystate[i] = (tystate[i]==1)?1:2; ! 221: continue; ! 222: } ! 223: /* do a goto on c */ ! 224: for( k=j; k<cwset; ++k ){ ! 225: if( c == *(wsets[k].pitem) ){ /* this item contributes to the goto */ ! 226: putitem( wsets[k].pitem + 1, wsets[k].ws ); ! 227: wsets[k].flag = 1; ! 228: } ! 229: } ! 230: if( c < NTBASE ) temp1[c] = state(c); ! 231: else temp1[c-NTBASE+nterms] = state(c); ! 232: } ! 233: if( gsdebug ){ ! 234: settty(); ! 235: fprintf( cout , "%d: ", i ); ! 236: for( j=1; j<=nterms; ++j ){ ! 237: if( temp1[j] != 0 ) fprintf( cout , "%s %d, ", symnam(j), temp1[j]); ! 238: } ! 239: for( j=1; j<=nnonter; ++j ){ ! 240: if( temp1[j+nterms] ) fprintf( cout , "%s %d, ", nontrst[j].name, temp1[j+nterms] ); ! 241: } ! 242: fprintf( cout , "\n"); ! 243: } ! 244: apstate[i] = apack( &temp1[0], nterms ); ! 245: indgo[i] = apack( &temp1[nterms+1], nnonter-1 ) - 1; ! 246: goto more; /* we have done one goto; do some more */ ! 247: } ! 248: /* no more to do... stop */ ! 249: } ! 250: ! 251: int cldebug = 0; /* debugging flag for closure */ ! 252: closure(i){ /* generate the closure of state i */ ! 253: ! 254: int c, ch, work; ! 255: _REGISTER j, k; ! 256: int *pi; ! 257: int **s, **t; ! 258: struct item *q; ! 259: _REGISTER struct item *p; ! 260: ! 261: ++zzclose; ! 262: ! 263: /* first, copy kernel of state i to wsets */ ! 264: ! 265: lambdarule = -1; ! 266: cwset = 0; ! 267: q = pstate[i+1]; ! 268: /* for every item in the kernel */ ! 269: for( p=pstate[i]; p<q; ++p ){ ! 270: wsets[cwset].pitem = p->pitem; ! 271: wsets[cwset].flag = 1; /* this item must get closed */ ! 272: for( k=0; k<tbitset; ++k ) wsets[cwset].ws[k] = p->look->lset[k]; ! 273: ++cwset; ! 274: } ! 275: ! 276: /* now, go through the loop, closing each item */ ! 277: ! 278: work = 1; ! 279: while( work ){ ! 280: work = 0; ! 281: for( j=0; j<cwset; ++j ){ ! 282: ! 283: /* for every item in state, if terminal after dot, flag = 0 */ ! 284: if( wsets[j].flag == 0 ) continue; ! 285: /* dot is before c, since pitem of X -> A.B is B */ ! 286: c = *(wsets[j].pitem); ! 287: ! 288: if( c < NTBASE ){ ! 289: wsets[j].flag = 0; ! 290: continue; /* only interesting case is where . is before nonterminal */ ! 291: } ! 292: ! 293: /* compute the lookahead */ ! 294: aryfil( clset.lset, tbitset, 0 ); ! 295: ! 296: /* find items involving c */ ! 297: ! 298: /* for all the rest of the items in the state */ ! 299: for( k=j; k<cwset; ++k ){ ! 300: if( wsets[k].flag == 1 && *(pi=wsets[k].pitem) == c ){ ! 301: wsets[k].flag = 0; ! 302: if( nolook ) continue; ! 303: while( (ch= *++pi)>0 ){ ! 304: if( ch < NTBASE ){ /* terminal symbol */ ! 305: /* put ch in clset */ ! 306: clset.lset[ch>>4] |= (1<<(ch&017)); ! 307: break; ! 308: } ! 309: /* nonterminal symbol */ ! 310: /* clset <- clset U first(ch) */ ! 311: UNION( clset.lset, clset.lset, pfirst[ch-NTBASE] ); ! 312: /* if ch cannot derive lambda we are done */ ! 313: if( !pempty[ch-NTBASE] ) break; ! 314: } ! 315: /* if end of rule the clset <- clset U (lookahead for LHS) */ ! 316: if( ch<=0 ) UNION( clset.lset, clset.lset, wsets[k].ws ); ! 317: } ! 318: } ! 319: ! 320: /* now loop over productions derived from c */ ! 321: ! 322: c -= NTBASE; /* c is now nonterminal number */ ! 323: ! 324: t = pres[c+1]; ! 325: /* for each rule that c derives */ ! 326: for( s=pres[c]; s<t; ++s ){ ! 327: /* put these items into the closure */ ! 328: for( k=0; k<cwset; ++k ){ /* is the item there */ ! 329: if( wsets[k].pitem == *s ){ /* yes, it is there */ ! 330: if( nolook ) goto nexts; ! 331: /* if something new in ws, set flag = 1 */ ! 332: if( UNION( wsets[k].ws, wsets[k].ws, clset.lset ) ) ! 333: wsets[k].flag = work = 1; ! 334: goto nexts; ! 335: } ! 336: } ! 337: ! 338: /* not there; make a new entry */ ! 339: if( cwset+1 >= wssize ) error( "working set overflow" ); ! 340: wsets[cwset].pitem = *s; ! 341: wsets[cwset].flag = 1; ! 342: if (**s < 0) ! 343: lambdarule = cwset; ! 344: if( nolook ){ ! 345: cwset++; ! 346: goto nexts; ! 347: } ! 348: work = 1; ! 349: for( k=0; k<tbitset; ++k ) wsets[cwset].ws[k] = clset.lset[k]; ! 350: cwset++; ! 351: ! 352: nexts: ; ! 353: } ! 354: ! 355: } ! 356: } ! 357: ! 358: /* have computed closure; flags are reset; return */ ! 359: ! 360: if( cwset > zzcwset ) zzcwset = cwset; ! 361: if( !cldebug ) return; ! 362: settty(); ! 363: fprintf( cout , "\nState %d, nolook = %d\n", i, nolook ); ! 364: for( j=0; j<cwset; ++j ){ ! 365: if( wsets[j].flag ) fprintf( cout , "flag set!\n"); ! 366: wsets[j].flag = 0; ! 367: fprintf( cout , "\t%s", writem(&wsets[j].pitem)); ! 368: prlook( wsets[j].ws ); ! 369: fprintf( cout , "\n" ); ! 370: } ! 371: ! 372: } ! 373: ! 374: struct looksets *flset( p ) ! 375: struct looksets *p; ! 376: { ! 377: /* decide if the lookahead set pointed to by p is known */ ! 378: /* return pointer to a perminent location for the set */ ! 379: ! 380: int j, *w; ! 381: _REGISTER *u, *v, i; ! 382: ! 383: for( i=0; i<nlset; ++i ){ ! 384: u = p->lset; ! 385: v = lkst[i].lset; ! 386: w = & v[tbitset]; ! 387: while( v<w) if( *u++ != *v++ ) goto more; ! 388: /* we have matched */ ! 389: return( & lkst[i] ); ! 390: more: ; ! 391: } ! 392: /* add a new one */ ! 393: if( nlset+1 >= lsetsz )error("too many lookahead sets"); ! 394: for( j=0; j<tbitset; ++j ){ ! 395: lkst[nlset].lset[j] = p->lset[j]; ! 396: } ! 397: return( & lkst[nlset++]); ! 398: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.