|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)y1.c 4.2 (Berkeley) 5/10/89"; ! 3: #endif not lint ! 4: ! 5: # include "dextern" ! 6: # include "pathnames.h" ! 7: ! 8: /* variables used locally */ ! 9: ! 10: /* lookahead computations */ ! 11: ! 12: int tbitset; /* size of lookahead sets */ ! 13: struct looksets lkst [ LSETSIZE ]; ! 14: int nlset = 0; /* next lookahead set index */ ! 15: int nolook = 0; /* flag to suppress lookahead computations */ ! 16: struct looksets clset; /* temporary storage for lookahead computations */ ! 17: ! 18: /* working set computations */ ! 19: ! 20: struct wset wsets[ WSETSIZE ]; ! 21: struct wset *cwp; ! 22: ! 23: /* state information */ ! 24: ! 25: int nstate = 0; /* number of states */ ! 26: struct item *pstate[NSTATES+2]; /* pointers to the descriptions of the states */ ! 27: int tystate[NSTATES]; /* contains type information about the states */ ! 28: int indgo[NSTATES]; /* index to the stored goto table */ ! 29: int tstates[ NTERMS ]; /* states generated by terminal gotos */ ! 30: int ntstates[ NNONTERM ]; /* states generated by nonterminal gotos */ ! 31: int mstates[ NSTATES ]; /* chain of overflows of term/nonterm generation lists */ ! 32: ! 33: /* storage for the actions in the parser */ ! 34: ! 35: int amem[ACTSIZE]; /* action table storage */ ! 36: int *memp = amem; /* next free action table position */ ! 37: ! 38: /* other storage areas */ ! 39: ! 40: int temp1[TEMPSIZE]; /* temporary storage, indexed by terms + ntokens or states */ ! 41: int lineno= 1; /* current input line number */ ! 42: int fatfl = 1; /* if on, error is fatal */ ! 43: int nerrors = 0; /* number of errors */ ! 44: ! 45: /* storage for information about the nonterminals */ ! 46: ! 47: int **pres[NNONTERM+2]; /* vector of pointers to productions yielding each nonterminal */ ! 48: struct looksets *pfirst[NNONTERM+2]; /* vector of pointers to first sets for each nonterminal */ ! 49: int pempty[NNONTERM+1]; /* vector of nonterminals nontrivially deriving e */ ! 50: ! 51: main(argc,argv) int argc; char *argv[]; { ! 52: ! 53: setup(argc,argv); /* initialize and read productions */ ! 54: tbitset = NWORDS(ntokens); ! 55: cpres(); /* make table of which productions yield a given nonterminal */ ! 56: cempty(); /* make a table of which nonterminals can match the empty string */ ! 57: cpfir(); /* make a table of firsts of nonterminals */ ! 58: stagen(); /* generate the states */ ! 59: output(); /* write the states and the tables */ ! 60: go2out(); ! 61: hideprod(); ! 62: summary(); ! 63: callopt(); ! 64: others(); ! 65: exit(0); ! 66: } ! 67: ! 68: others(){ /* put out other arrays, copy the parsers */ ! 69: register c, i, j; ! 70: ! 71: finput = fopen( _PATH_PARSER, "r" ); ! 72: if( finput == NULL ) error( "cannot find parser %s", _PATH_PARSER); ! 73: ! 74: warray( "yyr1", levprd, nprod ); ! 75: ! 76: aryfil( temp1, nprod, 0 ); ! 77: PLOOP(1,i)temp1[i] = prdptr[i+1]-prdptr[i]-2; ! 78: warray( "yyr2", temp1, nprod ); ! 79: ! 80: aryfil( temp1, nstate, -1000 ); ! 81: TLOOP(i){ ! 82: for( j=tstates[i]; j!=0; j=mstates[j] ){ ! 83: temp1[j] = tokset[i].value; ! 84: } ! 85: } ! 86: NTLOOP(i){ ! 87: for( j=ntstates[i]; j!=0; j=mstates[j] ){ ! 88: temp1[j] = -i; ! 89: } ! 90: } ! 91: warray( "yychk", temp1, nstate ); ! 92: ! 93: warray( "yydef", defact, nstate ); ! 94: ! 95: /* copy parser text */ ! 96: ! 97: while( (c=getc(finput) ) != EOF ){ ! 98: if( c == '$' ){ ! 99: if( (c=getc(finput)) != 'A' ) putc( '$', ftable ); ! 100: else { /* copy actions */ ! 101: faction = fopen( ACTNAME, "r" ); ! 102: if( faction == NULL ) error( "cannot reopen action tempfile" ); ! 103: while( (c=getc(faction) ) != EOF ) putc( c, ftable ); ! 104: fclose(faction); ! 105: ZAPFILE(ACTNAME); ! 106: c = getc(finput); ! 107: } ! 108: } ! 109: putc( c, ftable ); ! 110: } ! 111: ! 112: fclose( ftable ); ! 113: } ! 114: ! 115: char *chcopy( p, q ) char *p, *q; { ! 116: /* copies string q into p, returning next free char ptr */ ! 117: while( *p = *q++ ) ++p; ! 118: return( p ); ! 119: } ! 120: ! 121: # define ISIZE 400 ! 122: char *writem(pp) int *pp; { /* creates output string for item pointed to by pp */ ! 123: int i,*p; ! 124: static char sarr[ISIZE]; ! 125: char *q; ! 126: ! 127: for( p=pp; *p>0 ; ++p ) ; ! 128: p = prdptr[-*p]; ! 129: q = chcopy( sarr, nontrst[*p-NTBASE].name ); ! 130: q = chcopy( q, " : " ); ! 131: ! 132: for(;;){ ! 133: *q++ = ++p==pp ? '_' : ' '; ! 134: *q = '\0'; ! 135: if((i = *p) <= 0) break; ! 136: q = chcopy( q, symnam(i) ); ! 137: if( q> &sarr[ISIZE-30] ) error( "item too big" ); ! 138: } ! 139: ! 140: if( (i = *pp) < 0 ){ /* an item calling for a reduction */ ! 141: q = chcopy( q, " (" ); ! 142: sprintf( q, "%d)", -i ); ! 143: } ! 144: ! 145: return( sarr ); ! 146: } ! 147: ! 148: char *symnam(i){ /* return a pointer to the name of symbol i */ ! 149: char *cp; ! 150: ! 151: cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name ; ! 152: if( *cp == ' ' ) ++cp; ! 153: return( cp ); ! 154: } ! 155: ! 156: struct wset *zzcwp = wsets; ! 157: int zzgoent = 0; ! 158: int zzgobest = 0; ! 159: int zzacent = 0; ! 160: int zzexcp = 0; ! 161: int zzclose = 0; ! 162: int zzsrconf = 0; ! 163: int * zzmemsz = mem0; ! 164: int zzrrconf = 0; ! 165: ! 166: summary(){ /* output the summary on the tty */ ! 167: ! 168: if( foutput!=NULL ){ ! 169: fprintf( foutput, "\n%d/%d terminals, %d/%d nonterminals\n", ntokens, NTERMS, ! 170: nnonter, NNONTERM ); ! 171: fprintf( foutput, "%d/%d grammar rules, %d/%d states\n", nprod, NPROD, nstate, NSTATES ); ! 172: fprintf( foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf ); ! 173: fprintf( foutput, "%d/%d working sets used\n", zzcwp-wsets, WSETSIZE ); ! 174: fprintf( foutput, "memory: states,etc. %d/%d, parser %d/%d\n", zzmemsz-mem0, MEMSIZE, ! 175: memp-amem, ACTSIZE ); ! 176: fprintf( foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE ); ! 177: fprintf( foutput, "%d extra closures\n", zzclose - 2*nstate ); ! 178: fprintf( foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp ); ! 179: fprintf( foutput, "%d goto entries\n", zzgoent ); ! 180: fprintf( foutput, "%d entries saved by goto default\n", zzgobest ); ! 181: } ! 182: if( zzsrconf!=0 || zzrrconf!=0 ){ ! 183: fprintf( stdout,"\nconflicts: "); ! 184: if( zzsrconf )fprintf( stdout, "%d shift/reduce" , zzsrconf ); ! 185: if( zzsrconf && zzrrconf )fprintf( stdout, ", " ); ! 186: if( zzrrconf )fprintf( stdout, "%d reduce/reduce" , zzrrconf ); ! 187: fprintf( stdout, "\n" ); ! 188: } ! 189: ! 190: fclose( ftemp ); ! 191: if( fdefine != NULL ) fclose( fdefine ); ! 192: } ! 193: ! 194: /* VARARGS1 */ ! 195: error(s,a1) char *s; { /* write out error comment */ ! 196: ! 197: ++nerrors; ! 198: fprintf( stderr, "\n fatal error: "); ! 199: fprintf( stderr, s,a1); ! 200: fprintf( stderr, ", line %d\n", lineno ); ! 201: if( !fatfl ) return; ! 202: summary(); ! 203: exit(1); ! 204: } ! 205: ! 206: aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */ ! 207: int i; ! 208: for( i=0; i<n; ++i ) v[i] = c; ! 209: } ! 210: ! 211: setunion( a, b ) register *a, *b; { ! 212: /* set a to the union of a and b */ ! 213: /* return 1 if b is not a subset of a, 0 otherwise */ ! 214: register i, x, sub; ! 215: ! 216: sub = 0; ! 217: SETLOOP(i){ ! 218: *a = (x = *a)|*b++; ! 219: if( *a++ != x ) sub = 1; ! 220: } ! 221: return( sub ); ! 222: } ! 223: ! 224: prlook( p ) struct looksets *p;{ ! 225: register j, *pp; ! 226: pp = p->lset; ! 227: if( pp == 0 ) fprintf( foutput, "\tNULL"); ! 228: else { ! 229: fprintf( foutput, " { " ); ! 230: TLOOP(j) { ! 231: if( BIT(pp,j) ) fprintf( foutput, "%s ", symnam(j) ); ! 232: } ! 233: fprintf( foutput, "}" ); ! 234: } ! 235: } ! 236: ! 237: cpres(){ /* compute an array with the beginnings of productions yielding given nonterminals ! 238: The array pres points to these lists */ ! 239: /* the array pyield has the lists: the total size is only NPROD+1 */ ! 240: register **pmem; ! 241: register c, j, i; ! 242: static int * pyield[NPROD]; ! 243: ! 244: pmem = pyield; ! 245: ! 246: NTLOOP(i){ ! 247: c = i+NTBASE; ! 248: pres[i] = pmem; ! 249: fatfl = 0; /* make undefined symbols nonfatal */ ! 250: PLOOP(0,j){ ! 251: if (*prdptr[j] == c) *pmem++ = prdptr[j]+1; ! 252: } ! 253: if(pres[i] == pmem){ ! 254: error("nonterminal %s not defined!", nontrst[i].name); ! 255: } ! 256: } ! 257: pres[i] = pmem; ! 258: fatfl = 1; ! 259: if( nerrors ){ ! 260: summary(); ! 261: exit(1); ! 262: } ! 263: if( pmem != &pyield[nprod] ) error( "internal Yacc error: pyield %d", pmem-&pyield[nprod] ); ! 264: } ! 265: ! 266: int indebug = 0; ! 267: cpfir() { ! 268: /* compute an array with the first of nonterminals */ ! 269: register *p, **s, i, **t, ch, changes; ! 270: ! 271: zzcwp = &wsets[nnonter]; ! 272: NTLOOP(i){ ! 273: aryfil( wsets[i].ws.lset, tbitset, 0 ); ! 274: t = pres[i+1]; ! 275: for( s=pres[i]; s<t; ++s ){ /* initially fill the sets */ ! 276: for( p = *s; (ch = *p) > 0 ; ++p ) { ! 277: if( ch < NTBASE ) { ! 278: SETBIT( wsets[i].ws.lset, ch ); ! 279: break; ! 280: } ! 281: else if( !pempty[ch-NTBASE] ) break; ! 282: } ! 283: } ! 284: } ! 285: ! 286: /* now, reflect transitivity */ ! 287: ! 288: changes = 1; ! 289: while( changes ){ ! 290: changes = 0; ! 291: NTLOOP(i){ ! 292: t = pres[i+1]; ! 293: for( s=pres[i]; s<t; ++s ){ ! 294: for( p = *s; ( ch = (*p-NTBASE) ) >= 0; ++p ) { ! 295: changes |= setunion( wsets[i].ws.lset, wsets[ch].ws.lset ); ! 296: if( !pempty[ch] ) break; ! 297: } ! 298: } ! 299: } ! 300: } ! 301: ! 302: NTLOOP(i) pfirst[i] = flset( &wsets[i].ws ); ! 303: if( !indebug ) return; ! 304: if( (foutput!=NULL) ){ ! 305: NTLOOP(i) { ! 306: fprintf( foutput, "\n%s: ", nontrst[i].name ); ! 307: prlook( pfirst[i] ); ! 308: fprintf( foutput, " %d\n", pempty[i] ); ! 309: } ! 310: } ! 311: } ! 312: ! 313: state(c){ /* sorts last state,and sees if it equals earlier ones. returns state number */ ! 314: int size1,size2; ! 315: register i; ! 316: struct item *p1, *p2, *k, *l, *q1, *q2; ! 317: p1 = pstate[nstate]; ! 318: p2 = pstate[nstate+1]; ! 319: if(p1==p2) return(0); /* null state */ ! 320: /* sort the items */ ! 321: for(k=p2-1;k>p1;k--) { /* make k the biggest */ ! 322: for(l=k-1;l>=p1;--l)if( l->pitem > k->pitem ){ ! 323: int *s; ! 324: struct looksets *ss; ! 325: s = k->pitem; ! 326: k->pitem = l->pitem; ! 327: l->pitem = s; ! 328: ss = k->look; ! 329: k->look = l->look; ! 330: l->look = ss; ! 331: } ! 332: } ! 333: size1 = p2 - p1; /* size of state */ ! 334: ! 335: for( i= (c>=NTBASE)?ntstates[c-NTBASE]:tstates[c]; i != 0; i = mstates[i] ) { ! 336: /* get ith state */ ! 337: q1 = pstate[i]; ! 338: q2 = pstate[i+1]; ! 339: size2 = q2 - q1; ! 340: if (size1 != size2) continue; ! 341: k=p1; ! 342: for(l=q1;l<q2;l++) { ! 343: if( l->pitem != k->pitem ) break; ! 344: ++k; ! 345: } ! 346: if (l != q2) continue; ! 347: /* found it */ ! 348: pstate[nstate+1] = pstate[nstate]; /* delete last state */ ! 349: /* fix up lookaheads */ ! 350: if( nolook ) return(i); ! 351: for( l=q1,k=p1; l<q2; ++l,++k ){ ! 352: int s; ! 353: SETLOOP(s) clset.lset[s] = l->look->lset[s]; ! 354: if( setunion( clset.lset, k->look->lset ) ) { ! 355: tystate[i] = MUSTDO; ! 356: /* register the new set */ ! 357: l->look = flset( &clset ); ! 358: } ! 359: } ! 360: return (i); ! 361: } ! 362: /* state is new */ ! 363: if( nolook ) error( "yacc state/nolook error" ); ! 364: pstate[nstate+2] = p2; ! 365: if(nstate+1 >= NSTATES) error("too many states" ); ! 366: if( c >= NTBASE ){ ! 367: mstates[ nstate ] = ntstates[ c-NTBASE ]; ! 368: ntstates[ c-NTBASE ] = nstate; ! 369: } ! 370: else { ! 371: mstates[ nstate ] = tstates[ c ]; ! 372: tstates[ c ] = nstate; ! 373: } ! 374: tystate[nstate]=MUSTDO; ! 375: return(nstate++); ! 376: } ! 377: ! 378: int pidebug = 0; /* debugging flag for putitem */ ! 379: putitem( ptr, lptr ) int *ptr; struct looksets *lptr; { ! 380: register struct item *j; ! 381: ! 382: if( pidebug && (foutput!=NULL) ) { ! 383: fprintf( foutput, "putitem(%s), state %d\n", writem(ptr), nstate ); ! 384: } ! 385: j = pstate[nstate+1]; ! 386: j->pitem = ptr; ! 387: if( !nolook ) j->look = flset( lptr ); ! 388: pstate[nstate+1] = ++j; ! 389: if( (int *)j > zzmemsz ){ ! 390: zzmemsz = (int *)j; ! 391: if( zzmemsz >= &mem0[MEMSIZE] ) error( "out of state space" ); ! 392: } ! 393: } ! 394: ! 395: cempty(){ /* mark nonterminals which derive the empty string */ ! 396: /* also, look for nonterminals which don't derive any token strings */ ! 397: ! 398: # define EMPTY 1 ! 399: # define WHOKNOWS 0 ! 400: # define OK 1 ! 401: ! 402: register i, *p; ! 403: ! 404: /* first, use the array pempty to detect productions that can never be reduced */ ! 405: /* set pempty to WHONOWS */ ! 406: aryfil( pempty, nnonter+1, WHOKNOWS ); ! 407: ! 408: /* now, look at productions, marking nonterminals which derive something */ ! 409: ! 410: more: ! 411: PLOOP(0,i){ ! 412: if( pempty[ *prdptr[i] - NTBASE ] ) continue; ! 413: for( p=prdptr[i]+1; *p>=0; ++p ){ ! 414: if( *p>=NTBASE && pempty[ *p-NTBASE ] == WHOKNOWS ) break; ! 415: } ! 416: if( *p < 0 ){ /* production can be derived */ ! 417: pempty[ *prdptr[i]-NTBASE ] = OK; ! 418: goto more; ! 419: } ! 420: } ! 421: ! 422: /* now, look at the nonterminals, to see if they are all OK */ ! 423: ! 424: NTLOOP(i){ ! 425: /* the added production rises or falls as the start symbol ... */ ! 426: if( i == 0 ) continue; ! 427: if( pempty[ i ] != OK ) { ! 428: fatfl = 0; ! 429: error( "nonterminal %s never derives any token string", nontrst[i].name ); ! 430: } ! 431: } ! 432: ! 433: if( nerrors ){ ! 434: summary(); ! 435: exit(1); ! 436: } ! 437: ! 438: /* now, compute the pempty array, to see which nonterminals derive the empty string */ ! 439: ! 440: /* set pempty to WHOKNOWS */ ! 441: ! 442: aryfil( pempty, nnonter+1, WHOKNOWS ); ! 443: ! 444: /* loop as long as we keep finding empty nonterminals */ ! 445: ! 446: again: ! 447: PLOOP(1,i){ ! 448: if( pempty[ *prdptr[i]-NTBASE ]==WHOKNOWS ){ /* not known to be empty */ ! 449: for( p=prdptr[i]+1; *p>=NTBASE && pempty[*p-NTBASE]==EMPTY ; ++p ) ; ! 450: if( *p < 0 ){ /* we have a nontrivially empty nonterminal */ ! 451: pempty[*prdptr[i]-NTBASE] = EMPTY; ! 452: goto again; /* got one ... try for another */ ! 453: } ! 454: } ! 455: } ! 456: ! 457: } ! 458: ! 459: int gsdebug = 0; ! 460: stagen(){ /* generate the states */ ! 461: ! 462: int i, j; ! 463: register c; ! 464: register struct wset *p, *q; ! 465: ! 466: /* initialize */ ! 467: ! 468: nstate = 0; ! 469: /* THIS IS FUNNY from the standpoint of portability */ ! 470: /* it represents the magic moment when the mem0 array, which has ! 471: /* been holding the productions, starts to hold item pointers, of a ! 472: /* different type... */ ! 473: /* someday, alloc should be used to allocate all this stuff... for now, we ! 474: /* accept that if pointers don't fit in integers, there is a problem... */ ! 475: ! 476: pstate[0] = pstate[1] = (struct item *)mem; ! 477: aryfil( clset.lset, tbitset, 0 ); ! 478: putitem( prdptr[0]+1, &clset ); ! 479: tystate[0] = MUSTDO; ! 480: nstate = 1; ! 481: pstate[2] = pstate[1]; ! 482: ! 483: aryfil( amem, ACTSIZE, 0 ); ! 484: ! 485: /* now, the main state generation loop */ ! 486: ! 487: more: ! 488: SLOOP(i){ ! 489: if( tystate[i] != MUSTDO ) continue; ! 490: tystate[i] = DONE; ! 491: aryfil( temp1, nnonter+1, 0 ); ! 492: /* take state i, close it, and do gotos */ ! 493: closure(i); ! 494: WSLOOP(wsets,p){ /* generate goto's */ ! 495: if( p->flag ) continue; ! 496: p->flag = 1; ! 497: c = *(p->pitem); ! 498: if( c <= 1 ) { ! 499: if( pstate[i+1]-pstate[i] <= p-wsets ) tystate[i] = MUSTLOOKAHEAD; ! 500: continue; ! 501: } ! 502: /* do a goto on c */ ! 503: WSLOOP(p,q){ ! 504: if( c == *(q->pitem) ){ /* this item contributes to the goto */ ! 505: putitem( q->pitem + 1, &q->ws ); ! 506: q->flag = 1; ! 507: } ! 508: } ! 509: if( c < NTBASE ) { ! 510: state(c); /* register new state */ ! 511: } ! 512: else { ! 513: temp1[c-NTBASE] = state(c); ! 514: } ! 515: } ! 516: if( gsdebug && (foutput!=NULL) ){ ! 517: fprintf( foutput, "%d: ", i ); ! 518: NTLOOP(j) { ! 519: if( temp1[j] ) fprintf( foutput, "%s %d, ", nontrst[j].name, temp1[j] ); ! 520: } ! 521: fprintf( foutput, "\n"); ! 522: } ! 523: indgo[i] = apack( &temp1[1], nnonter-1 ) - 1; ! 524: goto more; /* we have done one goto; do some more */ ! 525: } ! 526: /* no more to do... stop */ ! 527: } ! 528: ! 529: int cldebug = 0; /* debugging flag for closure */ ! 530: closure(i){ /* generate the closure of state i */ ! 531: ! 532: int c, ch, work, k; ! 533: register struct wset *u, *v; ! 534: int *pi; ! 535: int **s, **t; ! 536: struct item *q; ! 537: register struct item *p; ! 538: ! 539: ++zzclose; ! 540: ! 541: /* first, copy kernel of state i to wsets */ ! 542: ! 543: cwp = wsets; ! 544: ITMLOOP(i,p,q){ ! 545: cwp->pitem = p->pitem; ! 546: cwp->flag = 1; /* this item must get closed */ ! 547: SETLOOP(k) cwp->ws.lset[k] = p->look->lset[k]; ! 548: WSBUMP(cwp); ! 549: } ! 550: ! 551: /* now, go through the loop, closing each item */ ! 552: ! 553: work = 1; ! 554: while( work ){ ! 555: work = 0; ! 556: WSLOOP(wsets,u){ ! 557: ! 558: if( u->flag == 0 ) continue; ! 559: c = *(u->pitem); /* dot is before c */ ! 560: ! 561: if( c < NTBASE ){ ! 562: u->flag = 0; ! 563: continue; /* only interesting case is where . is before nonterminal */ ! 564: } ! 565: ! 566: /* compute the lookahead */ ! 567: aryfil( clset.lset, tbitset, 0 ); ! 568: ! 569: /* find items involving c */ ! 570: ! 571: WSLOOP(u,v){ ! 572: if( v->flag == 1 && *(pi=v->pitem) == c ){ ! 573: v->flag = 0; ! 574: if( nolook ) continue; ! 575: while( (ch= *++pi)>0 ){ ! 576: if( ch < NTBASE ){ /* terminal symbol */ ! 577: SETBIT( clset.lset, ch ); ! 578: break; ! 579: } ! 580: /* nonterminal symbol */ ! 581: setunion( clset.lset, pfirst[ch-NTBASE]->lset ); ! 582: if( !pempty[ch-NTBASE] ) break; ! 583: } ! 584: if( ch<=0 ) setunion( clset.lset, v->ws.lset ); ! 585: } ! 586: } ! 587: ! 588: /* now loop over productions derived from c */ ! 589: ! 590: c -= NTBASE; /* c is now nonterminal number */ ! 591: ! 592: t = pres[c+1]; ! 593: for( s=pres[c]; s<t; ++s ){ ! 594: /* put these items into the closure */ ! 595: WSLOOP(wsets,v){ /* is the item there */ ! 596: if( v->pitem == *s ){ /* yes, it is there */ ! 597: if( nolook ) goto nexts; ! 598: if( setunion( v->ws.lset, clset.lset ) ) v->flag = work = 1; ! 599: goto nexts; ! 600: } ! 601: } ! 602: ! 603: /* not there; make a new entry */ ! 604: if( cwp-wsets+1 >= WSETSIZE ) error( "working set overflow" ); ! 605: cwp->pitem = *s; ! 606: cwp->flag = 1; ! 607: if( !nolook ){ ! 608: work = 1; ! 609: SETLOOP(k) cwp->ws.lset[k] = clset.lset[k]; ! 610: } ! 611: WSBUMP(cwp); ! 612: ! 613: nexts: ; ! 614: } ! 615: ! 616: } ! 617: } ! 618: ! 619: /* have computed closure; flags are reset; return */ ! 620: ! 621: if( cwp > zzcwp ) zzcwp = cwp; ! 622: if( cldebug && (foutput!=NULL) ){ ! 623: fprintf( foutput, "\nState %d, nolook = %d\n", i, nolook ); ! 624: WSLOOP(wsets,u){ ! 625: if( u->flag ) fprintf( foutput, "flag set!\n"); ! 626: u->flag = 0; ! 627: fprintf( foutput, "\t%s", writem(u->pitem)); ! 628: prlook( &u->ws ); ! 629: fprintf( foutput, "\n" ); ! 630: } ! 631: } ! 632: } ! 633: ! 634: struct looksets *flset( p ) struct looksets *p; { ! 635: /* decide if the lookahead set pointed to by p is known */ ! 636: /* return pointer to a perminent location for the set */ ! 637: ! 638: register struct looksets *q; ! 639: int j, *w; ! 640: register *u, *v; ! 641: ! 642: for( q = &lkst[nlset]; q-- > lkst; ){ ! 643: u = p->lset; ! 644: v = q->lset; ! 645: w = & v[tbitset]; ! 646: while( v<w) if( *u++ != *v++ ) goto more; ! 647: /* we have matched */ ! 648: return( q ); ! 649: more: ; ! 650: } ! 651: /* add a new one */ ! 652: q = &lkst[nlset++]; ! 653: if( nlset >= LSETSIZE )error("too many lookahead sets" ); ! 654: SETLOOP(j){ ! 655: q->lset[j] = p->lset[j]; ! 656: } ! 657: return( q ); ! 658: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.