154 lines
3.4 KiB
C
154 lines
3.4 KiB
C
// 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]; 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
|
|
}
|