windows-nt/Source/XPSP1/NT/com/rpc/tools/yacc/yclsur.c

154 lines
3.4 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
// 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
}