home *** CD-ROM | disk | FTP | other *** search
-
- # include "y1.h"
-
- /*
- * yclsur.1c
- *
- * Modified to make debug code conditionally compile.
- * 28-Aug-81
- * Bob Denny
- */
-
- void closure( i )
-
-
-
- {
- /* generate the closure of state i */
-
- int c,
- ch,
- work,
- k;
- register struct wset * u,
- * v;
- int * pi;
- int * * 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 ]; s < t; ++s )
-
- {
- /* put these items into the closure */
- WSLOOP( wsets, v )
-
- {
- /* is the item there */
- if ( v->pitem == *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
- }
-