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