// Copyright (c) 1993-1999 Microsoft Corporation #include "y1.h" /* * yclsur.1c * * Modified to make debug code conditionally compile. * 28-Aug-81 * Bob Denny */ void closure( int i) { /* generate the closure of state i */ int work, k; SSIZE_T ch, c; register struct wset *u, *v; SSIZE_T *pi; SSIZE_T **s, **t; struct item *q; register struct item *p; ++zzclose; /* first, copy kernel of state i to wsets */ cwp = wsets; ITMLOOP(i,p,q) { cwp->pitem = p->pitem; cwp->flag = 1; /* this item must get closed */ SETLOOP(k) cwp->ws.lset[k] = p->look->lset[k]; WSBUMP(cwp); } /* now, go through the loop, closing each item */ work = 1; while( work ) { work = 0; WSLOOP(wsets,u) { if( u->flag == 0 ) continue; c = *(u->pitem); /* dot is before c */ if( c < NTBASE ) { u->flag = 0; continue; /* only interesting case is where . is before nonterminal */ } /* compute the lookahead */ aryfil( clset.lset, tbitset, 0 ); /* find items involving c */ WSLOOP(u,v) { if( v->flag == 1 && *(pi=v->pitem) == c ) { v->flag = 0; if( nolook ) continue; while( (ch= *++pi)>0 ) { if( ch < NTBASE ) { /* terminal symbol */ SETBIT( clset.lset, ch ); break; } /* nonterminal symbol */ setunion( clset.lset, pfirst[ch-NTBASE]->lset ); if( !pempty[ch-NTBASE] ) break; } if( ch<=0 ) setunion( clset.lset, v->ws.lset ); } } /* now loop over productions derived from c */ c -= NTBASE; /* c is now nonterminal number */ t = pres[c+1]; for( s=pres[c]; spitem == *s ) { /* yes, it is there */ if( nolook ) goto nexts; if( setunion( v->ws.lset, clset.lset ) ) v->flag = work = 1; goto nexts; } } /* not there; make a new entry */ if( cwp-wsets+1 >= WSETSIZE ) error( "working set overflow" ); cwp->pitem = *s; cwp->flag = 1; if( !nolook ) { work = 1; SETLOOP(k) cwp->ws.lset[k] = clset.lset[k]; } WSBUMP(cwp); nexts: ; } } } /* have computed closure; flags are reset; return */ if( cwp > zzcwp ) zzcwp = cwp; #ifdef debug if( foutput!=NULL ) { fprintf( foutput, "\nState %d, nolook = %d\n", i, nolook ); WSLOOP(wsets,u) { if( u->flag ) fprintf( foutput, "flag set!\n"); u->flag = 0; fprintf( foutput, "\t%s", writem(u->pitem)); prlook( &u->ws ); fprintf( foutput, "\n" ); } } #endif }