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