808 lines
20 KiB
C
808 lines
20 KiB
C
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
Copyright (c) 1989-2000 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
ebase.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This file generates the error recovery data base.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
1. Inputs to this module are the extable.* files generated by yacc in
|
|||
|
response to the s switch.
|
|||
|
2. Take the state vs token index file ( extable.h3 ), and generate the
|
|||
|
state vs token table using the token index to token value
|
|||
|
translations provided by extable.h1
|
|||
|
3. Take the state vs expected RHS file ( extable.h2 ) and generate a
|
|||
|
data base of expected RHS in every state.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
vibhasc 11-15-91
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
|
|||
|
/*****************************************************************************
|
|||
|
local defines and includes
|
|||
|
*****************************************************************************/
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <assert.h>
|
|||
|
#include <malloc.h>
|
|||
|
#include <string.h>
|
|||
|
|
|||
|
#include "ebase.h"
|
|||
|
|
|||
|
#define STATE_VS_TOKEN_INDEX_FILE "extable.h3"
|
|||
|
#define TOKEN_TRANSLATION_FILE "extable.h1"
|
|||
|
#define STATE_VS_EXPECTED_FILE "extable.h2"
|
|||
|
#define ISVALIDTOKEN( i ) (TRUE)
|
|||
|
#define MAX_TRANSLATION_LINE_SIZE (512)
|
|||
|
|
|||
|
#define TRUE 1
|
|||
|
#define FALSE 0
|
|||
|
/* from winerror.h */
|
|||
|
#define ERROR_INVALID_DATA 13
|
|||
|
|
|||
|
#define CHECK_FSCAN_STATUS( fscanfcall ) \
|
|||
|
if ( EOF == (fscanfcall) ) \
|
|||
|
{ \
|
|||
|
fprintf( stderr, \
|
|||
|
"\nmidleb : error MIDLEB%d : unexpected end of input stream", \
|
|||
|
ERROR_INVALID_DATA ); \
|
|||
|
exit( ERROR_INVALID_DATA ); \
|
|||
|
}
|
|||
|
|
|||
|
typedef unsigned int BOOL;
|
|||
|
|
|||
|
typedef enum _status
|
|||
|
{
|
|||
|
|
|||
|
STATUS_OK = 0,
|
|||
|
OUT_OF_MEMORY,
|
|||
|
CANT_OPEN_INPUT_FILE,
|
|||
|
CANT_OPEN_OUTPUT_FILE,
|
|||
|
WRONG_ARGUMENT_COUNT
|
|||
|
|
|||
|
} STATUS_T;
|
|||
|
|
|||
|
typedef struct _xlat
|
|||
|
{
|
|||
|
char * pIncoming;
|
|||
|
char * pTranslated;
|
|||
|
struct _xlat *pNext;
|
|||
|
} XLAT;
|
|||
|
|
|||
|
typedef struct _DBENTRY
|
|||
|
{
|
|||
|
short State;
|
|||
|
char * pTranslated;
|
|||
|
} DBENTRY;
|
|||
|
|
|||
|
/*****************************************************************************
|
|||
|
global data
|
|||
|
*****************************************************************************/
|
|||
|
|
|||
|
FILE * hStateVsTokenIndexFile;
|
|||
|
FILE * hStateVsExpectedFile;
|
|||
|
FILE * hOutput;
|
|||
|
FILE * hXlatFile;
|
|||
|
FILE * hTokXlatHdl;
|
|||
|
SGOTO ** pSGoto;
|
|||
|
short * pSGotoCount;
|
|||
|
short ** pTokVsState;
|
|||
|
short * pTokVsStateIndex;
|
|||
|
short ValidStates;
|
|||
|
short ValidTokens;
|
|||
|
char * pPrefix;
|
|||
|
XLAT * pXlat = 0,
|
|||
|
* pXlatCur = 0;
|
|||
|
DBENTRY * pDataBase;
|
|||
|
short NTOKENS;
|
|||
|
short ACCEPTCODE;
|
|||
|
short * TokVal;
|
|||
|
short * TokCount;
|
|||
|
short NSTATES;
|
|||
|
short MAXTOKVSSTATE;
|
|||
|
short MAXSTATEVSTOK;
|
|||
|
short MAXTOKENVALUE;
|
|||
|
short MAXSTATEVSEXPECTED;
|
|||
|
|
|||
|
/*****************************************************************************
|
|||
|
external procedures
|
|||
|
*****************************************************************************/
|
|||
|
|
|||
|
STATUS_T Init( char *, char * );
|
|||
|
STATUS_T Generate( FILE * );
|
|||
|
STATUS_T OpenFileForReadProcessing( FILE **, char * );
|
|||
|
void Dump( void );
|
|||
|
BOOL SearchForStateInTokenVsState( short, short );
|
|||
|
void TranslateExpectedConstructs( void );
|
|||
|
char * Translate( char * );
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
main(
|
|||
|
int argc,
|
|||
|
char *argv[] )
|
|||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
the main routine.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Standard
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Exit Status
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
Usage : ebase <OutputFilename> <Xlatefile> <prefix>
|
|||
|
|
|||
|
Xlatefile is the file where production names to message translation
|
|||
|
is specified.
|
|||
|
|
|||
|
prefix is idl or acf. The expected string array is created with a
|
|||
|
standard name prefixed with the user specified prefix.
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
{
|
|||
|
|
|||
|
STATUS_T Status;
|
|||
|
|
|||
|
fprintf( stderr, "Error Recovery Data Base Generator\n" );
|
|||
|
|
|||
|
|
|||
|
if( argc == 4 )
|
|||
|
{
|
|||
|
|
|||
|
pPrefix = argv[ 3 ];
|
|||
|
|
|||
|
if( (Status = Init( argv[ 1 ], argv[ 2 ] )) == STATUS_OK )
|
|||
|
{
|
|||
|
Status = Generate( hStateVsTokenIndexFile );
|
|||
|
}
|
|||
|
|
|||
|
Dump();
|
|||
|
|
|||
|
TranslateExpectedConstructs();
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
fprintf( stderr, "Wrong argument count\n" );
|
|||
|
fprintf( stderr, "Usage : midleb <output file or - > <translation-file-name> <prefix>\n");
|
|||
|
Status = WRONG_ARGUMENT_COUNT;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
exit( Status );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Initialize
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
OutputName : output file name
|
|||
|
XlatFilename : the production/token name to error message translation.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_T - OUT_OF_MEMORY or
|
|||
|
- CANT_OPEN_INPUT_FILE or
|
|||
|
- STATUS_OK
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
Sets up the file handles for all the files that need to be read from
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
STATUS_T
|
|||
|
Init(
|
|||
|
char * OutputFileName,
|
|||
|
char * XlatFileName )
|
|||
|
{
|
|||
|
STATUS_T Status;
|
|||
|
int i;
|
|||
|
|
|||
|
Status = OpenFileForReadProcessing(
|
|||
|
&hStateVsTokenIndexFile,
|
|||
|
STATE_VS_TOKEN_INDEX_FILE );
|
|||
|
|
|||
|
if( Status == STATUS_OK )
|
|||
|
{
|
|||
|
Status = OpenFileForReadProcessing(
|
|||
|
&hStateVsExpectedFile,
|
|||
|
STATE_VS_EXPECTED_FILE );
|
|||
|
|
|||
|
if( Status == STATUS_OK )
|
|||
|
{
|
|||
|
Status = OpenFileForReadProcessing(
|
|||
|
&hTokXlatHdl,
|
|||
|
TOKEN_TRANSLATION_FILE );
|
|||
|
if( Status == STATUS_OK )
|
|||
|
{
|
|||
|
Status = OpenFileForReadProcessing( &hXlatFile, XlatFileName );
|
|||
|
|
|||
|
if( Status == STATUS_OK )
|
|||
|
{
|
|||
|
if( strcmp( OutputFileName, "-" ) == 0 )
|
|||
|
hOutput = stdout;
|
|||
|
else if( (hOutput = fopen( OutputFileName , "w" )) == (FILE *)0 )
|
|||
|
{
|
|||
|
Status = CANT_OPEN_OUTPUT_FILE;
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if( Status != STATUS_OK )
|
|||
|
return Status;
|
|||
|
|
|||
|
/** read in the required numbers from the TOKEN_TRANSLATION_FILE **/
|
|||
|
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hTokXlatHdl, "%hd %hd\n", &NTOKENS, &ACCEPTCODE ) );
|
|||
|
|
|||
|
/** read in the token translation table **/
|
|||
|
|
|||
|
TokVal = (short *)calloc( 1, NTOKENS * sizeof( short ) );
|
|||
|
TokCount = (short *)calloc( 1, NTOKENS * sizeof( short ) );
|
|||
|
|
|||
|
if (!TokVal || !TokCount )
|
|||
|
{
|
|||
|
fprintf( stderr, "Out of memory.\n");
|
|||
|
exit(OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
|
|||
|
for( i = 0;
|
|||
|
i < NTOKENS;
|
|||
|
i++ )
|
|||
|
{
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hTokXlatHdl, "%hd", &TokVal[ i ]) );
|
|||
|
}
|
|||
|
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hTokXlatHdl, "\n" ) );
|
|||
|
|
|||
|
for( i = 0;
|
|||
|
i < NTOKENS;
|
|||
|
i++ )
|
|||
|
{
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hTokXlatHdl, "%hd", &TokCount[ i ]) );
|
|||
|
}
|
|||
|
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hTokXlatHdl, "\n" ) );
|
|||
|
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hTokXlatHdl,
|
|||
|
"%hd %hd %hd %hd %hd\n",
|
|||
|
&NSTATES,
|
|||
|
&MAXTOKVSSTATE,
|
|||
|
&MAXSTATEVSTOK,
|
|||
|
&MAXTOKENVALUE,
|
|||
|
&MAXSTATEVSEXPECTED ) );
|
|||
|
|
|||
|
/** allocate memory now **/
|
|||
|
|
|||
|
pSGoto = (SGOTO **) calloc( 1,NSTATES * sizeof( SGOTO * ) );
|
|||
|
|
|||
|
pSGotoCount = (short *)calloc(1, NSTATES * sizeof( short ) );
|
|||
|
|
|||
|
pTokVsState = (short **)calloc( 1,(MAXTOKENVALUE+1) * sizeof( short * ) );
|
|||
|
|
|||
|
pTokVsStateIndex = (short *)calloc(1, (MAXTOKENVALUE+1) * sizeof( short ) );
|
|||
|
|
|||
|
pDataBase = ( DBENTRY * )calloc( 1, MAXSTATEVSEXPECTED * sizeof( DBENTRY ) );
|
|||
|
|
|||
|
|
|||
|
if( !pSGoto || !pSGotoCount || !pTokVsState || !pTokVsStateIndex || !pDataBase )
|
|||
|
{
|
|||
|
fprintf( stderr, "Out of memory.\n");
|
|||
|
exit(OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
STATUS_T
|
|||
|
Generate(
|
|||
|
FILE * hSVsTIndexFile )
|
|||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Generate the state vs token table, given the state vs token index table
|
|||
|
in extable.h3 and token vs token index translation of extable.h1.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hStateVsTokenIndexFile - handle to the file which has the state vs
|
|||
|
token index info.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
The state vs token index file has the goto info for every valid token,
|
|||
|
For every state, this file contains the goto ( or none ) for every valid
|
|||
|
token ( represented by the token index ). Thus for each state, we lookup
|
|||
|
to see if the state has a goto for a given token index. If it does, then
|
|||
|
we translate the token index into a token value, and mark the goto for the
|
|||
|
state for that token in the state vs token table.
|
|||
|
|
|||
|
In the end we will have a very sparse array, which contains all the states
|
|||
|
and the gotos for the state for each token ( or the absence of any goto ).
|
|||
|
|
|||
|
We will use this table to generate two tables:
|
|||
|
|
|||
|
1. The set of all states which have a goto on a token
|
|||
|
2. The set of all tokens valid for any state.
|
|||
|
|
|||
|
The exception to this rule is the accept action which is treated like
|
|||
|
an absence of goto.
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
{
|
|||
|
|
|||
|
short iState,i,j,Temp,SGotoCount;
|
|||
|
SGOTO *p;
|
|||
|
|
|||
|
/** fixup pointers to token vs state pointer array **/
|
|||
|
|
|||
|
for( i = 0;
|
|||
|
i < NTOKENS;
|
|||
|
i++ )
|
|||
|
{
|
|||
|
|
|||
|
if( TokCount[ i ] )
|
|||
|
{
|
|||
|
j = TokVal[ i ];
|
|||
|
|
|||
|
if( ISVALIDTOKEN( j ) )
|
|||
|
{
|
|||
|
pTokVsState[ j ] = calloc( 1, TokCount[ i ] * sizeof( short ) );
|
|||
|
|
|||
|
if (!pTokVsState[ j ])
|
|||
|
{
|
|||
|
fprintf( stderr, "Out of memory.\n" );
|
|||
|
exit( OUT_OF_MEMORY );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
for( iState = 0;
|
|||
|
iState < NSTATES;
|
|||
|
++iState )
|
|||
|
{
|
|||
|
|
|||
|
/** ignore the state number */
|
|||
|
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hSVsTIndexFile,
|
|||
|
"%hd %c",
|
|||
|
&Temp,
|
|||
|
&Temp ) );
|
|||
|
|
|||
|
/** get the count of number of state goto entries **/
|
|||
|
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hSVsTIndexFile,
|
|||
|
"%hd %c",
|
|||
|
&SGotoCount,
|
|||
|
&Temp ) );
|
|||
|
|
|||
|
/** now read in the goto vs token pairs **/
|
|||
|
|
|||
|
|
|||
|
if( SGotoCount )
|
|||
|
{
|
|||
|
|
|||
|
p = pSGoto[ iState ] = calloc( 1, SGotoCount * sizeof( SGOTO ) );
|
|||
|
|
|||
|
if (!p)
|
|||
|
{
|
|||
|
fprintf( stderr, "Out of memory.\n" );
|
|||
|
exit( OUT_OF_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
for( j = 0;
|
|||
|
j < SGotoCount;
|
|||
|
++j )
|
|||
|
{
|
|||
|
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hSVsTIndexFile,
|
|||
|
"%hd%c %hd",
|
|||
|
&p->Goto,
|
|||
|
&Temp,
|
|||
|
&p->Token ) );
|
|||
|
|
|||
|
Temp = TokVal[ p->Token ];
|
|||
|
|
|||
|
if( ISVALIDTOKEN( Temp ) )
|
|||
|
{
|
|||
|
if( !SearchForStateInTokenVsState( Temp, p->Goto ) )
|
|||
|
{
|
|||
|
i = pTokVsStateIndex[ Temp ];
|
|||
|
pTokVsStateIndex[ Temp ]++;
|
|||
|
|
|||
|
*(pTokVsState[Temp] + i ) = p->Goto;
|
|||
|
}
|
|||
|
p++;
|
|||
|
pSGotoCount[ iState ]++;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
return STATUS_OK;
|
|||
|
}
|
|||
|
|
|||
|
STATUS_T
|
|||
|
OpenFileForReadProcessing(
|
|||
|
FILE ** pHandle,
|
|||
|
char * pName )
|
|||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This process opens a file for read processing, reports an error if
|
|||
|
the file could not be opened.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pHandle - pointer to a file handle deposition area.
|
|||
|
pName - pointer to a file name, null terminated.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_T - STATUS_OK if all is well.
|
|||
|
- CANT_OPEN_INPUT_FILE otherwise.
|
|||
|
Notes:
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
{
|
|||
|
FILE *hF;
|
|||
|
|
|||
|
if( ( hF = fopen( pName, "r" ) ) == (FILE *)NULL )
|
|||
|
{
|
|||
|
fprintf( stderr, "Cannot open input file : %s\n", pName );
|
|||
|
return CANT_OPEN_INPUT_FILE;
|
|||
|
}
|
|||
|
*pHandle = hF;
|
|||
|
return STATUS_OK;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
Dump( void )
|
|||
|
{
|
|||
|
SGOTO * p;
|
|||
|
short iTemp, i,j;
|
|||
|
|
|||
|
/** dump the state goto table **/
|
|||
|
|
|||
|
for( iTemp = 0, ValidStates = 0;
|
|||
|
iTemp < NSTATES;
|
|||
|
++iTemp )
|
|||
|
{
|
|||
|
|
|||
|
p = pSGoto[ iTemp ];
|
|||
|
|
|||
|
if( j = pSGotoCount[ iTemp ] )
|
|||
|
{
|
|||
|
fprintf( hOutput, "\n SGOTO _sG%s%.4hd [ %d ] = { ", pPrefix, iTemp, j );
|
|||
|
|
|||
|
for( i = 0;
|
|||
|
i < j;
|
|||
|
i++ )
|
|||
|
{
|
|||
|
|
|||
|
fprintf( hOutput
|
|||
|
, " {%hd, %hd} %c"
|
|||
|
, p[ i ].Goto
|
|||
|
, TokVal[ p[ i ].Token]
|
|||
|
, ( (i+1 == j) ? ' ' : ',' ));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
fprintf( hOutput, "};" );
|
|||
|
|
|||
|
ValidStates++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** now dump the array of pointers to this **/
|
|||
|
|
|||
|
fprintf( hOutput, "\n\n#define VALIDSTATES_%s %d\n", pPrefix, ValidStates );
|
|||
|
|
|||
|
fprintf( hOutput, "\n\nSGOTOVECTOR SGoto%s[ VALIDSTATES_%s ] = {\n",pPrefix, pPrefix);
|
|||
|
|
|||
|
for( i = 0;
|
|||
|
i < NSTATES;
|
|||
|
++i )
|
|||
|
{
|
|||
|
if( pSGotoCount[ i ] )
|
|||
|
{
|
|||
|
fprintf( hOutput, "\n{ %d, _sG%s%.4hd, %d }"
|
|||
|
, i
|
|||
|
,pPrefix
|
|||
|
, i
|
|||
|
, pSGotoCount[ i ] );
|
|||
|
fprintf( hOutput,"%c", ((i + 1 == NSTATES) ? ' ' : ',' ));
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
fprintf( hOutput, "\n};\n\n" );
|
|||
|
|
|||
|
/** count the valid token entries. i.e tokens for which states exist **/
|
|||
|
|
|||
|
fprintf(hOutput, "#if 0\n");
|
|||
|
|
|||
|
for( ValidTokens = 0, i = 0;
|
|||
|
i < MAXTOKENVALUE;
|
|||
|
++i )
|
|||
|
{
|
|||
|
|
|||
|
if( pTokVsStateIndex[ i ] )
|
|||
|
ValidTokens++;
|
|||
|
}
|
|||
|
|
|||
|
/** dump the token vs state table **/
|
|||
|
|
|||
|
for( iTemp = 0;
|
|||
|
iTemp < NTOKENS;
|
|||
|
++iTemp )
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
if( j = pTokVsStateIndex[ TokVal[ iTemp ] ] )
|
|||
|
{
|
|||
|
|
|||
|
fprintf( hOutput, "short _tS%s%.4d[ %d ] = {", pPrefix, TokVal[ iTemp ], j );
|
|||
|
|
|||
|
for( i = 0;
|
|||
|
i < j;
|
|||
|
++i )
|
|||
|
{
|
|||
|
|
|||
|
fprintf( hOutput, " %d %c", *(pTokVsState[ TokVal[ iTemp ] ]+i),
|
|||
|
(( i + 1 == j ) ? ' ' : ',' ));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
fprintf( hOutput, "};\n" );
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/** dump the vectors to the token vs state table **/
|
|||
|
|
|||
|
fprintf(hOutput, "\n#define VALIDTOKENS %d\n", ValidTokens );
|
|||
|
fprintf( hOutput, "\nTOKVSSTATEVECTOR TokVsState%s[ VALIDTOKENS ] = { \n",pPrefix);
|
|||
|
|
|||
|
for( i = 0;
|
|||
|
i < MAXTOKENVALUE+1;
|
|||
|
++i )
|
|||
|
{
|
|||
|
|
|||
|
if( j = pTokVsStateIndex[ i ])
|
|||
|
{
|
|||
|
fprintf( hOutput, "\n{ %d, _tS%s%.4d, %d }",i, pPrefix, i, j );
|
|||
|
fprintf(hOutput, "%c", (i + 1 == NTOKENS) ? ' ' : ',' );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
fprintf( hOutput, "\n\n};\n" );
|
|||
|
fprintf( hOutput, "\n" );
|
|||
|
|
|||
|
fprintf(hOutput, "#endif\n");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
SearchForStateInTokenVsState(
|
|||
|
short TokenValue,
|
|||
|
short Goto )
|
|||
|
{
|
|||
|
int i,j;
|
|||
|
|
|||
|
for( i = 0, j = pTokVsStateIndex[ TokenValue ];
|
|||
|
i < j;
|
|||
|
++i )
|
|||
|
{
|
|||
|
if( *(pTokVsState[ TokenValue ] + i) == Goto )
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
TranslateExpectedConstructs( void )
|
|||
|
{
|
|||
|
int i,State,Count,Temp;
|
|||
|
char Buffer[ MAX_TRANSLATION_LINE_SIZE ];
|
|||
|
char Buffer1[ MAX_TRANSLATION_LINE_SIZE ];
|
|||
|
DBENTRY *p;
|
|||
|
XLAT *pX;
|
|||
|
|
|||
|
/**
|
|||
|
firstly, read in the translation data base, which shows the
|
|||
|
expected token name vs the actual error string the compiler wants to
|
|||
|
output.
|
|||
|
**/
|
|||
|
|
|||
|
for(;;)
|
|||
|
{
|
|||
|
i = fscanf( hXlatFile,
|
|||
|
"%[^ \t]%1s%[^\n]\n",
|
|||
|
Buffer,
|
|||
|
&Temp,
|
|||
|
Buffer1 );
|
|||
|
|
|||
|
if( i == EOF || i == 0 )
|
|||
|
break;
|
|||
|
|
|||
|
if( ( Buffer[0] != '$' ) && ( Buffer[1] != '$' ) )
|
|||
|
{
|
|||
|
pX = calloc( 1 , sizeof( XLAT ) );
|
|||
|
|
|||
|
if (!pX )
|
|||
|
{
|
|||
|
fprintf( stderr, "Out of memory!" );
|
|||
|
exit(OUT_OF_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
pX->pIncoming = malloc( strlen( Buffer ) + 1 );
|
|||
|
|
|||
|
if (!pX->pIncoming )
|
|||
|
{
|
|||
|
fprintf( stderr, "Out of memory!" );
|
|||
|
exit(OUT_OF_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
strcpy( pX->pIncoming, Buffer );
|
|||
|
|
|||
|
pX->pTranslated = malloc( strlen( Buffer1 ) + 1 );
|
|||
|
|
|||
|
if (!pX->pTranslated)
|
|||
|
{
|
|||
|
fprintf( stderr, "Out of memory!" );
|
|||
|
exit(OUT_OF_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
strcpy( pX->pTranslated, Buffer1 );
|
|||
|
|
|||
|
if( pXlatCur == 0 )
|
|||
|
{
|
|||
|
pXlatCur = pXlat = pX;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pXlatCur->pNext = pX;
|
|||
|
pXlatCur = pX;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
Then read the STATE_VS_EXPECTED_FILE, and read in the expected
|
|||
|
tokens/productions for each entry, as translated by looking up the
|
|||
|
data base.
|
|||
|
**/
|
|||
|
|
|||
|
p = pDataBase;
|
|||
|
|
|||
|
while( p < (pDataBase + MAXSTATEVSEXPECTED) )
|
|||
|
{
|
|||
|
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hStateVsExpectedFile, "%d %c %d %c",
|
|||
|
&State,
|
|||
|
&Temp,
|
|||
|
&Count,
|
|||
|
&Temp,
|
|||
|
Buffer ) );
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if( Count )
|
|||
|
{
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hStateVsExpectedFile, " %[^\n]\n", Buffer ) );
|
|||
|
p->State = (short) State;
|
|||
|
p->pTranslated = Translate( Buffer );
|
|||
|
p++;
|
|||
|
}
|
|||
|
else
|
|||
|
CHECK_FSCAN_STATUS(
|
|||
|
fscanf( hStateVsExpectedFile, "\n" ) );
|
|||
|
|
|||
|
}
|
|||
|
/**
|
|||
|
emit the state vs expected array with the proper prefix
|
|||
|
**/
|
|||
|
|
|||
|
fprintf( hOutput, "\n#ifndef _DBENTRY_DEFINED\n" );
|
|||
|
fprintf( hOutput, "\n#define _DBENTRY_DEFINED\n" );
|
|||
|
fprintf( hOutput, "\ntypedef struct _DBENTRY {" );
|
|||
|
fprintf( hOutput, "\n\t short State;");
|
|||
|
fprintf( hOutput, "\n\t char * pTranslated;");
|
|||
|
fprintf( hOutput, "\n} DBENTRY;\n");
|
|||
|
fprintf( hOutput, "\n#endif\n" );
|
|||
|
|
|||
|
fprintf( hOutput, "\n#define MAXSTATEVSEXPECTED_SIZE_%s %d\n", pPrefix, MAXSTATEVSEXPECTED );
|
|||
|
fprintf( hOutput, "\n DBENTRY %s_SyntaxErrorDB[ MAXSTATEVSEXPECTED_SIZE_%s ] = {\n", pPrefix, pPrefix);
|
|||
|
|
|||
|
for( p = pDataBase;
|
|||
|
p < (pDataBase + MAXSTATEVSEXPECTED);
|
|||
|
p++ )
|
|||
|
{
|
|||
|
fprintf( hOutput, "{ %d , \"%s\"},\n" , p->State, p->pTranslated );
|
|||
|
}
|
|||
|
|
|||
|
fprintf( hOutput, "\n};\n" );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
char *
|
|||
|
Translate(
|
|||
|
char *pIncoming )
|
|||
|
{
|
|||
|
char *p;
|
|||
|
|
|||
|
pXlatCur = pXlat;
|
|||
|
|
|||
|
while( pXlatCur )
|
|||
|
{
|
|||
|
if( strcmp( pXlatCur->pIncoming, pIncoming ) == 0 )
|
|||
|
return pXlatCur->pTranslated;
|
|||
|
pXlatCur = pXlatCur->pNext;
|
|||
|
}
|
|||
|
|
|||
|
p = malloc( strlen( pIncoming ) + 1 );
|
|||
|
|
|||
|
if (!p )
|
|||
|
{
|
|||
|
fprintf( stderr, "Out of memory.\n" );
|
|||
|
exit( OUT_OF_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
strcpy( p, pIncoming );
|
|||
|
|
|||
|
return p;
|
|||
|
}
|
|||
|
|