windows-nt/Source/XPSP1/NT/com/rpc/tools/yacc/ywstat.c
2020-09-26 16:20:57 +08:00

301 lines
6 KiB
C

// Copyright (c) 1993-1999 Microsoft Corporation
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The s switch has been introduced to allow yacc to generate extended tables
for MIDL error recovery and reporting scheme. The following are the routines
which take part in s switch processing:
. EmitStateVsExpectedConstruct
. EmitStateGotoTable
. SSwitchInit
. SSwitchExit
The global int variable ssw is 0 if s switch is not specified, non-zero
otherwise. This is set in ysetup.c If the sswitch is specified, the i switch
is automatically enabled.
----------------------------------------------------------------------------*/
#include <malloc.h>
#include <stdlib.h>
#include "y3.h"
#include "y4.h"
extern int ssw;
FILE *tokxlathdl;/* token xlation file,token index vs value*/
FILE *stgotohdl; /* state goto table file handle */
FILE *stexhdl; /* state vs expected construct handle */
short MaxStateVsTokenCount = 0;
short MaxTokenVsStateCount = 0;
short *pTokenVsStateCount;
SSIZE_T MaxTokenValue = 0;
short NStates = 0;
int StateVsExpectedCount = 0;
void
wrstate( int i)
{
/* writes state i */
register j0;
SSIZE_T j1;
register struct item *pp, *qq;
register struct wset *u;
if( foutput == NULL ) return;
SSwitchInit();
fprintf( foutput, "\nstate %d\n",i);
ITMLOOP(i,pp,qq)
{
fprintf( foutput, "\t%s\n", writem(pp->pitem));
EmitStateVsExpectedConstruct( i, pp->pitem );
}
if( tystate[i] == MUSTLOOKAHEAD )
{
/* print out empty productions in closure */
WSLOOP( wsets+(pstate[i+1]-pstate[i]), u )
{
if( *(u->pitem) < 0 ) fprintf( foutput, "\t%s\n", writem(u->pitem) );
}
}
/* check for state equal to another */
TLOOP(j0)
{
if( (j1=temp1[j0]) != 0 )
{
fprintf( foutput, "\n\t%s ", symnam(j0) );
if( j1>0 )
{
/* shift, error, or accept */
if( j1 == ACCEPTCODE ) fprintf( foutput, "accept" );
else if( j1 == ERRCODE ) fprintf( foutput, "error" );
else fprintf( foutput, "shift %d", j1 );
}
else fprintf( foutput, "reduce %d",-j1 );
}
}
/* output any s switch information */
EmitStateGotoTable( i );
/* output the final production */
if( lastred ) fprintf( foutput, "\n\t. reduce %d\n\n", lastred );
else fprintf( foutput, "\n\t. error\n\n" );
/* now, output nonterminal actions */
j1 = ntokens;
for( j0 = 1; j0 <= nnonter; ++j0 )
{
if( temp1[++j1] )
fprintf( foutput, "\t%s goto %d\n", symnam( j0+NTBASE), temp1[j1] );
}
}
void
wdef( char *s, int n )
{
/* output a definition of s to the value n */
fprintf( ftable, "# define %s %d\n", s, n );
}
void
EmitStateGotoTable(
int i )
{
register int j0;
short count = 0;
#define TLOOP_0(i) for(i=0;i<=ntokens;++i)
if( ssw )
{
NStates++;
TLOOP_0( j0 )
{
if( (temp1[ j0 ] > 0 ) && (temp1[ j0 ] != ACCEPTCODE ) )
count++;
}
if( count >= MaxStateVsTokenCount )
MaxStateVsTokenCount = count;
fprintf( stgotohdl, "%.4d : %.4d : ", i, count );
TLOOP_0( j0 )
{
if( (temp1[ j0 ] > 0 ) && (temp1[ j0 ] != ACCEPTCODE ) )
{
fprintf( stgotohdl, " %.4d, %.4d", temp1[ j0 ], j0 );
pTokenVsStateCount[ j0 ] += 1;
if( pTokenVsStateCount[ j0 ] >= MaxTokenVsStateCount )
MaxTokenVsStateCount = pTokenVsStateCount[ j0 ];
}
}
fprintf( stgotohdl, "\n");
}
}
void
EmitStateVsExpectedConstruct(
int state,
SSIZE_T *pp )
{
SSIZE_T i,*p;
// char *q;
int flag = 0;
int Count;
if( ssw )
{
for( p=pp; *p>0 ; ++p ) ;
p = prdptr[-*p];
// fprintf( stexhdl, " %s", nontrst[ *p-NTBASE ].name );
fprintf( stexhdl, " %.4d : ", state );
Count = CountStateVsExpectedConstruct( state, pp );
StateVsExpectedCount += Count;
fprintf( stexhdl, " %.4d : ",Count );
for(;;)
{
if( ++p==pp )
{
if( ( i = *p ) <= 0 )
{
fprintf( stexhdl, "\n" );
return;
}
else
fprintf( stexhdl, "%s\n", symnam(i) );
}
if( p >= pp ) return;
}
}
}
int
CountStateVsExpectedConstruct(
int state,
SSIZE_T *pp )
{
SSIZE_T i,*p;
int flag = 0;
int Count = 0;
if( ssw )
{
for( p=pp; *p>0 ; ++p ) ;
p = prdptr[-*p];
for(;;)
{
if( ++p==pp )
{
if( ( i = *p ) <= 0 )
{
return Count;
}
else
++Count;
}
if( p >= pp ) return Count;
}
}
return Count; /* NOTREACHED */
}
void
SSwitchInit()
{
static sswitch_inited = 0;
int i = 0;
if( ssw && ! sswitch_inited )
{
tokxlathdl = fopen( "extable.h1" , "w" );
if ( NULL == tokxlathdl ) {error("Unable to open tokxlathdl" );exit(0);}
/* output the token index vs the token value table */
fprintf( tokxlathdl, "%d %d\n", ntokens+1, ACCEPTCODE );
while( i <= ntokens )
{
fprintf( tokxlathdl , "%d ",
tokset[ i ].value);
if( tokset[ i ].value >= MaxTokenValue )
MaxTokenValue = tokset[ i ].value;
++i;
}
fprintf(tokxlathdl, "\n");
/* set up for the state vs expected construct */
stexhdl = fopen( "extable.h2", "w" );
if ( NULL == stexhdl ) error("Unable to open extable.h2");
/* set up for state goto table */
stgotohdl = fopen( "extable.h3", "w");
if ( NULL == stgotohdl ) error("Unable to open extable.h3");
/* set up state vs token count array */
pTokenVsStateCount = calloc( 1, (ntokens+1 ) * sizeof(short) );
if ( NULL == pTokenVsStateCount ) error("Out of memory");
sswitch_inited = 1;
}
}
void
SSwitchExit( void )
{
int i;
if( ssw )
{
/** print the token index vs goto count **/
for( i = 0; i <= ntokens ; ++i )
{
fprintf( tokxlathdl , "%d ", pTokenVsStateCount[ i ]);
}
fprintf( tokxlathdl, "\n");
fprintf( tokxlathdl, "%d %d %d %d %d \n",
NStates,
MaxTokenVsStateCount,
MaxStateVsTokenCount,
MaxTokenValue,
StateVsExpectedCount );
fclose( tokxlathdl );
fclose( stexhdl );
fclose( stgotohdl );
}
}