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