# include "y1.h" # include /* * 12-Apr-83 (RBD) Add symbolic exit status */ void cempty( ) { /* mark nonterminals which derive the empty string */ /* also, look for nonterminals which don't derive any token strings */ # define EMPTY 1 # define WHOKNOWS 0 # define OK 1 register i, * p; /* first, use the array pempty to detect productions that can never be reduced */ /* set pempty to WHONOWS */ aryfil( pempty, nnonter + 1, WHOKNOWS ); /* now, look at productions, marking nonterminals which derive something */ more : PLOOP( 0, i ) { if ( pempty[ *prdptr[ i ] - NTBASE ] ) continue ; for ( p = prdptr[ i ] + 1; *p >= 0; ++p ) { if ( *p >= NTBASE && pempty[ *p - NTBASE ] == WHOKNOWS ) break ; } if ( *p < 0 ) { /* production can be derived */ pempty[ *prdptr[ i ] - NTBASE ] = OK; goto more; } } /* now, look at the nonterminals, to see if they are all OK */ NTLOOP( i ) { /* the added production rises or falls as the start symbol ... */ if ( i == 0 ) continue ; if ( pempty[ i ] != OK ) { fatfl = 0; error( "nonterminal %s never derives any token string", nontrst[ i ].name ); } } if ( nerrors ) { summary( ); exit( EX_ERR ); } /* now, compute the pempty array, to see which nonterminals derive the empty string */ /* set pempty to WHOKNOWS */ aryfil( pempty, nnonter + 1, WHOKNOWS ); /* loop as long as we keep finding empty nonterminals */ again : PLOOP( 1, i ) { if ( pempty[ *prdptr[ i ] - NTBASE ] == WHOKNOWS ) { /* not known to be empty */ for ( p = prdptr[ i ] + 1; *p >= NTBASE && pempty[ *p - NTBASE ] == EMPTY; ++p ) ; if ( *p < 0 ) { /* we have a nontrivially empty nonterminal */ pempty[ *prdptr[ i ] - NTBASE ] = EMPTY; goto again; /* got one ... try for another */ } } } }