While more portable methods exist to handle these cases, this change does not attempt to do more than fix the immediate problem and follow the conventions already established in this code. `snprintf()` is introduced as the minimum improvement apart from making the buffers larger. Fixes the following CodeQL alerts: 1. Failure on line 2339 in BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c - Type: Potentially overrunning write - Severity: Critical - Problem: This 'call to sprintf' operation requires 17 bytes but the destination is only 16 bytes. 2. Failure on line 2341 in BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c - Type: Potentially overrunning write - Severity: Critical - Problem: This 'call to sprintf' operation requires 17 bytes but the destination is only 16 bytes. 3. Failure on line 1309 in BaseTools/Source/C/VfrCompile/Pccts/antlr/main.c - Type: Potentially overrunning write - Severity: Critical - Problem: This 'call to sprintf' operation requires 25 bytes but the destination is only 20 bytes. Cc: Bob Feng <bob.c.feng@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Yuwei Chen <yuwei.chen@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Oliver Smith-Denny <osd@smith-denny.com>
1748 lines
52 KiB
C
1748 lines
52 KiB
C
/*
|
|
* main.c -- main program for PCCTS ANTLR.
|
|
*
|
|
* SOFTWARE RIGHTS
|
|
*
|
|
* We reserve no LEGAL rights to the Purdue Compiler Construction Tool
|
|
* Set (PCCTS) -- PCCTS is in the public domain. An individual or
|
|
* company may do whatever they wish with source code distributed with
|
|
* PCCTS or the code generated by PCCTS, including the incorporation of
|
|
* PCCTS, or its output, into commerical software.
|
|
*
|
|
* We encourage users to develop software with PCCTS. However, we do ask
|
|
* that credit is given to us for developing PCCTS. By "credit",
|
|
* we mean that if you incorporate our source code into one of your
|
|
* programs (commercial product, research project, or otherwise) that you
|
|
* acknowledge this fact somewhere in the documentation, research report,
|
|
* etc... If you like PCCTS and have developed a nice tool with the
|
|
* output, please mention that you developed it using PCCTS. In
|
|
* addition, we ask that this header remain intact in our source code.
|
|
* As long as these guidelines are kept, we expect to continue enhancing
|
|
* this system and expect to make other tools available as they are
|
|
* completed.
|
|
*
|
|
* ANTLR 1.33
|
|
* Terence Parr
|
|
* Parr Research Corporation
|
|
* with Purdue University and AHPCRC, University of Minnesota
|
|
* 1989-2001
|
|
*/
|
|
|
|
/* To set a breakpoint just before exit look for "cleanUp". */
|
|
/* To set a breakpoint for fatal error look for "fatal_intern" */
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "pcctscfg.h"
|
|
#include "stdpccts.h"
|
|
|
|
#define MAX_INT_STACK 50
|
|
static int istack[MAX_INT_STACK]; /* Int stack */
|
|
static int isp = MAX_INT_STACK;
|
|
|
|
static int DontAcceptFiles = 0; /* if stdin, don't read files */
|
|
static int DontAcceptStdin = 0; /* if files seen first, don't accept stdin */
|
|
|
|
static int tnodes_used_in_guard_predicates_etc; /* MR10 */
|
|
|
|
/* C m d - L i n e O p t i o n S t r u c t & F u n c s */
|
|
|
|
typedef struct _Opt {
|
|
char *option;
|
|
int arg;
|
|
#ifdef __cplusplus
|
|
void (*process)(...);
|
|
#else
|
|
void (*process)();
|
|
#endif
|
|
char *descr;
|
|
} Opt;
|
|
|
|
#ifdef __USE_PROTOS
|
|
extern void ProcessArgs(int, char **, Opt *);
|
|
#else
|
|
extern void ProcessArgs();
|
|
#endif
|
|
|
|
#ifdef __USE_PROTOS
|
|
int ci_strequ(char *a,char *b)
|
|
#else
|
|
int ci_strequ(a,b)
|
|
char *a;
|
|
char *b;
|
|
#endif
|
|
{
|
|
for ( ;*a != 0 && *b != 0; a++, b++) {
|
|
if (toupper(*a) != toupper(*b)) return 0;
|
|
}
|
|
return (*a == *b);
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pStdin( void )
|
|
#else
|
|
pStdin( )
|
|
#endif
|
|
{
|
|
if ( DontAcceptStdin )
|
|
{
|
|
warnNoFL("'-' (stdin) ignored as files were specified first");
|
|
return;
|
|
}
|
|
|
|
require(NumFiles<MaxNumFiles,"exceeded max # of input files");
|
|
FileStr[NumFiles++] = "stdin";
|
|
DontAcceptFiles = 1;
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pFile( char *s )
|
|
#else
|
|
pFile( s )
|
|
char *s;
|
|
#endif
|
|
{
|
|
if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
|
|
if ( DontAcceptFiles )
|
|
{
|
|
warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
|
|
return;
|
|
}
|
|
|
|
require(NumFiles<MaxNumFiles,"exceeded max # of input files");
|
|
FileStr[NumFiles++] = s;
|
|
DontAcceptStdin = 1;
|
|
}
|
|
|
|
/* MR14
|
|
Allow input to be a file containing a list of files
|
|
Bernard Giroud (b_giroud@decus.ch)
|
|
*/
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pFileList( char *s, char *t )
|
|
#else
|
|
pFileList( s, t )
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
#define MaxFLArea 1024
|
|
FILE *fl;
|
|
static char Fn_in_Fl[MaxFLArea] = "";
|
|
char one_fn[MaxFileName];
|
|
char *flp = &Fn_in_Fl[0];
|
|
int fnl, left = MaxFLArea, i;
|
|
|
|
if ( *t=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",t) ); return; }
|
|
if ( DontAcceptFiles )
|
|
{
|
|
warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",t));
|
|
return;
|
|
}
|
|
|
|
if ((fl = fopen(t, "r")) == NULL)
|
|
{
|
|
warnNoFL(eMsg1("file '%s' can't be opened", t));
|
|
return;
|
|
}
|
|
for (;;)
|
|
{
|
|
if (fgets(one_fn, 128 - 1, fl) == NULL)
|
|
break;
|
|
fnl = strlen(one_fn);
|
|
require(fnl<=left, "no more room in File List Area");
|
|
/* drop the trailing LF */
|
|
if (one_fn[fnl - 1] == 0x0a) one_fn[fnl - 1] = ' ';
|
|
strcat(Fn_in_Fl, one_fn);
|
|
left = left - fnl;
|
|
require(NumFiles<MaxNumFiles,"exceeded max # of input files");
|
|
FileStr[NumFiles++] = flp;
|
|
flp = flp + fnl;
|
|
}
|
|
fclose(fl);
|
|
for (i=0;i < MaxFLArea;i++) if (Fn_in_Fl[i] == ' ') Fn_in_Fl[i] = '\0';
|
|
DontAcceptStdin = 1;
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pLLK( char *s, char *t )
|
|
#else
|
|
pLLK( s, t )
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
LL_k = atoi(t);
|
|
if ( LL_k <= 0 ) {
|
|
warnNoFL("must have at least one token of lookahead (setting to 1)");
|
|
LL_k = 1;
|
|
}
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pCk( char *s, char *t )
|
|
#else
|
|
pCk( s, t )
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
CLL_k = atoi(t);
|
|
if ( CLL_k <= 0 ) {
|
|
warnNoFL("must have at least one token of look-ahead (setting to 1)");
|
|
CLL_k = 1;
|
|
}
|
|
}
|
|
|
|
static void /* MR6 */
|
|
#ifdef __USE_PROTOS
|
|
pTab( char *s, char *t ) /* MR6 */
|
|
#else
|
|
pTab( s, t ) /* MR6 */
|
|
char *s; /* MR6 */
|
|
char *t; /* MR6 */
|
|
#endif
|
|
{ /* MR6 */
|
|
TabWidth = atoi(t); /* MR6 */
|
|
if ( TabWidth < 0 || TabWidth > 8 ) { /* MR6 */
|
|
warnNoFL("tab width must be between 1 and 8"); /* MR6 */
|
|
TabWidth=0; /* MR6 */
|
|
} /* MR6 */
|
|
} /* MR6 */
|
|
|
|
static int ambAidDepthSpecified=0; /* MR11 */
|
|
|
|
static void /* MR11 */
|
|
#ifdef __USE_PROTOS
|
|
pAAd( char *s, char *t ) /* MR11 */
|
|
#else
|
|
pAAd( s, t ) /* MR11 */
|
|
char *s; /* MR11 */
|
|
char *t; /* MR11 */
|
|
#endif
|
|
{ /* MR11 */
|
|
ambAidDepthSpecified=1; /* MR11 */
|
|
MR_AmbAidDepth = atoi(t); /* MR11 */
|
|
} /* MR11 */
|
|
|
|
static void /* MR11 */
|
|
#ifdef __USE_PROTOS
|
|
pTreport( char *s, char *t ) /* MR11 */
|
|
#else
|
|
pTreport( s, t ) /* MR11 */
|
|
char *s; /* MR11 */
|
|
char *t; /* MR11 */
|
|
#endif
|
|
{ /* MR11 */
|
|
TnodesReportThreshold = atoi(t); /* MR11 */
|
|
} /* MR11 */
|
|
|
|
#ifdef __USE_PROTOS
|
|
void chkGTFlag(void) /* 7-Apr-97 MR1 */
|
|
#else
|
|
void chkGTFlag() /* 7-Apr-97 MR1 */
|
|
#endif
|
|
{
|
|
if ( !GenAST )
|
|
warn("#-variable or other AST item referenced w/o -gt option");
|
|
}
|
|
|
|
|
|
#ifdef __USE_PROTOS
|
|
static void pInfo(char *s, char *t) /* MR10 */
|
|
#else
|
|
static void pInfo(s,t) /* MR10 */
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
char *p;
|
|
int q;
|
|
for (p=t; *p != 0; p++) {
|
|
q=tolower(*p);
|
|
if (q=='t') {
|
|
InfoT=1;
|
|
} else if (q=='p') {
|
|
InfoP=1;
|
|
} else if (q=='m') {
|
|
InfoM=1;
|
|
} else if (q=='o') {
|
|
InfoO=1;
|
|
} else if (q=='0') {
|
|
; /* nothing */
|
|
} else if (q=='f') {
|
|
InfoF=1;
|
|
} else {
|
|
warnNoFL(eMsgd("unrecognized -info option \"%c\"",(int)*p));
|
|
};
|
|
};
|
|
}
|
|
|
|
#ifdef __USE_PROTOS
|
|
static void pCGen(void) { CodeGen = FALSE; LexGen = FALSE; }
|
|
static void pLGen(void) { LexGen = FALSE; }
|
|
static void pXTGen(void){ MR_Inhibit_Tokens_h_Gen = TRUE; }
|
|
static void pTGen(void) { TraceGen = TRUE; }
|
|
static void pSGen(void) { GenExprSetsOpt = FALSE; }
|
|
static void pPrt(void) { PrintOut = TRUE; pCGen(); pLGen(); }
|
|
static void pPrtA(void) { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
|
|
static void pAst(void) { GenAST = TRUE; }
|
|
static void pANSI(void) { GenANSI = TRUE; }
|
|
static void pCr(void) { GenCR = TRUE; }
|
|
static void pNOPURIFY(void) { PURIFY = FALSE; }
|
|
/*static void pCt(void) { warnNoFL("-ct option is now the default"); }*/
|
|
static void pLI(void) { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */
|
|
static void pLIms(void) { GenLineInfo = TRUE; GenLineInfoMS = TRUE; } /* MR14 */
|
|
static void pFr(char *s, char *t) {RemapFileName = t;}
|
|
static void pFe(char *s, char *t) {ErrFileName = t;}
|
|
static void pFl(char *s, char *t) {DlgFileName = t;}
|
|
static void pFm(char *s, char *t) {ModeFileName = t;}
|
|
static void pFt(char *s, char *t) {DefFileName = t;}
|
|
|
|
static void pE1(void) { elevel = 1; }
|
|
static void pE2(void) { elevel = 2; }
|
|
static void pE3(void) { elevel = 3; }
|
|
static void pEGen(void) { GenEClasseForRules = 1; }
|
|
static void pDL(void)
|
|
{
|
|
DemandLookahead = 1;
|
|
if ( GenCC ) {
|
|
warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
|
|
DemandLookahead = 0;
|
|
}
|
|
}
|
|
|
|
static void pAA(char *s,char *t) {MR_AmbAidRule = t;} /* MR11 */
|
|
static void pAAm(char *s){MR_AmbAidMultiple = 1;} /* MR11 */
|
|
static void pGHdr(void) { GenStdPccts = 1; }
|
|
static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
|
|
static void pW1(void) { WarningLevel = 1; }
|
|
static void pNewAST(void) { NewAST = 1; } /* MR13 */
|
|
static void ptmakeInParser(void) { tmakeInParser = 1; } /* MR23 */
|
|
static void pAlpha(void) { AlphaBetaTrace = 1; } /* MR14 */
|
|
static void pMR_BlkErr(void) { MR_BlkErr = 1; } /* MR21 */
|
|
static void pStdout(void) {UseStdout = 1; } /* MR6 */
|
|
static void pW2(void) { WarningLevel = 2; }
|
|
static void pCC(void) { GenCC = TRUE; }
|
|
#else
|
|
static void pCGen() { CodeGen = FALSE; LexGen = FALSE; }
|
|
static void pLGen() { LexGen = FALSE; }
|
|
static void pXTGen(){ MR_Inhibit_Tokens_h_Gen = TRUE; } /* MR14 */
|
|
static void pTGen() { TraceGen = TRUE; }
|
|
static void pSGen() { GenExprSetsOpt = FALSE; }
|
|
static void pPrt() { PrintOut = TRUE; pCGen(); pLGen(); }
|
|
static void pPrtA() { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
|
|
static void pAst() { GenAST = TRUE; }
|
|
static void pANSI() { GenANSI = TRUE; }
|
|
static void pCr() { GenCR = TRUE; }
|
|
static void pNOPURIFY() { PURIFY = FALSE; }
|
|
|
|
/*static void pCt() { warnNoFL("-ct option is now the default"); }*/
|
|
static void pLI() { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */
|
|
static void pLIms() { GenLineInfo = TRUE; GenLineInfoMS = TRUE; } /* MR14 */
|
|
static void pFr(s,t) char *s, *t; {RemapFileName = t;}
|
|
static void pFe(s,t) char *s, *t; {ErrFileName = t;}
|
|
static void pFl(s,t) char *s, *t; {DlgFileName = t;}
|
|
static void pFm(s,t) char *s, *t; {ModeFileName = t;}
|
|
static void pFt(s,t) char *s, *t; {DefFileName = t;}
|
|
|
|
static void pE1() { elevel = 1; }
|
|
static void pE2() { elevel = 2; }
|
|
static void pE3() { elevel = 3; }
|
|
static void pEGen() { GenEClasseForRules = 1; }
|
|
static void pDL()
|
|
{
|
|
DemandLookahead = 1;
|
|
if ( GenCC ) {
|
|
warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
|
|
DemandLookahead = 0;
|
|
}
|
|
}
|
|
|
|
static void pAA(s,t) char *s; char *t; {MR_AmbAidRule = t;} /* MR11 BJS 20-Mar-98 */
|
|
static void pAAm(s) char *s; {MR_AmbAidMultiple = 1;} /* MR11 BJS 20-Mar-98 */
|
|
static void pGHdr() { GenStdPccts = 1; }
|
|
static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
|
|
static void pW1() { WarningLevel = 1; }
|
|
static void pNewAST() { NewAST = 1; } /* MR13 */
|
|
static void ptmakeInParser() { tmakeInParser = 1; } /* MR23 */
|
|
static void pAlpha() { AlphaBetaTrace = 1; } /* MR14 */
|
|
static void pMR_BlkErr() { MR_BlkErr = 1; } /* MR21 */
|
|
static void pStdout() {UseStdout = 1; } /* MR6 */
|
|
static void pW2() { WarningLevel = 2; }
|
|
static void pCC() { GenCC = TRUE; }
|
|
#endif
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pPre( char *s, char *t )
|
|
#else
|
|
pPre( s, t )
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
RulePrefix = t;
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pOut( char *s, char *t )
|
|
#else
|
|
pOut( s, t )
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
OutputDirectory = t;
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pPred( void )
|
|
#else
|
|
pPred( )
|
|
#endif
|
|
{
|
|
warnNoFL("-pr is no longer used (predicates employed if present); see -prc, -mrhoist, -mrhoistk");
|
|
/*
|
|
** if ( DemandLookahead )
|
|
** warnNoFL("-gk conflicts with -pr; -gk turned off");
|
|
** DemandLookahead = 0;
|
|
** HoistPredicateContext = 0;
|
|
*/
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pPredCtx( char *s, char *t )
|
|
#else
|
|
pPredCtx(s,t)
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
if ( ci_strequ(t,"on")) HoistPredicateContext = 1;
|
|
else if ( ci_strequ(t,"off")) HoistPredicateContext = 0;
|
|
if ( DemandLookahead )
|
|
{
|
|
warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
|
|
DemandLookahead = 0;
|
|
}
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pMRhoist( char *s, char *t )
|
|
#else
|
|
pMRhoist(s,t)
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
if ( ci_strequ(t,"on")) MRhoisting = 1;
|
|
else if ( ci_strequ(t,"off")==0 ) MRhoisting = 0;
|
|
if (MRhoisting) {
|
|
fprintf(stderr,"Maintenance Release style hoisting enabled for predicates with lookahead depth = 1\n");
|
|
fprintf(stderr," No longer considered experimental\n");
|
|
fprintf(stderr," Can't consider suppression for predicates with lookahead depth > 1\n");
|
|
fprintf(stderr," Implies -prc on but does *not* imply -mrhoistk for k>1 predicates\n");
|
|
fprintf(stderr," This is a reminder, not a warning or error.\n");
|
|
};
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pMRhoistk( char *s, char *t )
|
|
#else
|
|
pMRhoistk(s,t)
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
if ( ci_strequ(t,"on")) MRhoistingk = 1;
|
|
else if ( ci_strequ(t,"off")==0 ) MRhoistingk = 0;
|
|
if (MRhoistingk) {
|
|
fprintf(stderr,"EXPERIMENTAL Maintenance Release style hoisting enabled\n");
|
|
fprintf(stderr," Applies to predicates with lookahead depth > 1\n");
|
|
fprintf(stderr," Implies -prc on and -mrhoist on\n");
|
|
};
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
pTRes( char *s, char *t )
|
|
#else
|
|
pTRes( s, t )
|
|
char *s;
|
|
char *t;
|
|
#endif
|
|
{
|
|
TreeResourceLimit = atoi(t);
|
|
if ( TreeResourceLimit <= 0 )
|
|
{
|
|
warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
|
|
TreeResourceLimit = -1; /* set to no limit */
|
|
}
|
|
}
|
|
|
|
Opt options[] = {
|
|
#ifdef __cplusplus
|
|
{ "-CC", 0, (void (*)(...)) pCC, "Generate C++ output (default=FALSE)"},
|
|
{ "-ck", 1, (void (*)(...)) pCk, "Set compressed lookahead depth; fast approximate lookahead"},
|
|
{ "-cr", 0, (void (*)(...)) pCr, "Generate cross reference (default=FALSE)"},
|
|
{ "-e1", 0, (void (*)(...)) pE1, "Ambiguities/errors shown in low detail (default)"},
|
|
{ "-e2", 0, (void (*)(...)) pE2, "Ambiguities/errors shown in more detail"},
|
|
{ "-e3", 0, (void (*)(...)) pE3,
|
|
"Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"},
|
|
{ "-f", 1, (void (*)(...)) pFileList,"Read names of grammar files from specified file"}, /* MR14 */
|
|
{ "-fe", 1, (void (*)(...)) pFe, "Rename err.c"},
|
|
{ "-fh", 1, (void (*)(...)) pFHdr, "Rename stdpccts.h header (turns on -gh)"},
|
|
{ "-fl", 1, (void (*)(...)) pFl, "Rename lexical output--parser.dlg"},
|
|
{ "-fm", 1, (void (*)(...)) pFm, "Rename mode.h"},
|
|
{ "-fr", 1, (void (*)(...)) pFr, "Rename remap.h"},
|
|
{ "-ft", 1, (void (*)(...)) pFt, "Rename tokens.h"},
|
|
{ "-ga", 0, (void (*)(...)) pANSI, "Generate ANSI-compatible code (default=FALSE)"},
|
|
{ "-gc", 0, (void (*)(...)) pCGen, "Do not generate output parser code (default=FALSE)"},
|
|
{ "-gd", 0, (void (*)(...)) pTGen, "Generate code to trace rule invocation (default=FALSE)"},
|
|
{ "-ge", 0, (void (*)(...)) pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
|
|
{ "-gh", 0, (void (*)(...)) pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
|
|
{ "-gk", 0, (void (*)(...)) pDL, "Generate parsers that delay lookahead fetches until needed"},
|
|
{ "-gl", 0, (void (*)(...)) pLI, "Generate line info about grammar actions in parser"},
|
|
{ "-glms", 0, (void (*)(...)) pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"},
|
|
{ "-gp", 1, (void (*)(...)) pPre, "Prefix all generated rule functions with a string"},
|
|
{ "-gs", 0, (void (*)(...)) pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
|
|
{ "-gt", 0, (void (*)(...)) pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
|
|
{ "-gx", 0, (void (*)(...)) pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
|
|
{ "-gxt",0, (void (*)(...)) pXTGen, "Do not generate tokens.h (default=FALSE)"},
|
|
{ "-k", 1, (void (*)(...)) pLLK, "Set full LL(k) lookahead depth (default==1)"},
|
|
{ "-o", 1, (void (*)(...)) pOut, OutputDirectoryOption},
|
|
{ "-p", 0, (void (*)(...)) pPrt, "Print out the grammar w/o actions (default=no)"},
|
|
{ "-pa", 0, (void (*)(...)) pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
|
|
{ "-pr",0, (void (*)(...)) pPred, "no longer used; predicates employed if present"},
|
|
{ "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
|
|
{ "-rl", 1, (void (*)(...)) pTRes, "Limit max # of tree nodes used by grammar analysis"},
|
|
{ "-stdout",0, (void (*)(...)) pStdout,"Send grammar.c/grammar.cpp to stdout"}, /* MR6 */
|
|
{ "-tab", 1, (void (*)(...)) pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */
|
|
{ "-w1", 0, (void (*)(...)) pW1, "Set the warning level to 1 (default)"},
|
|
{ "-w2", 0, (void (*)(...)) pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
|
|
{ "-", 0, (void (*)(...)) pStdin, "Read grammar from stdin" },
|
|
{ "-mrhoist",1, (void (*)(...)) pMRhoist, /* MR9 */
|
|
"Turn on/off k=1 Maintenance Release style hoisting"}, /* MR9 */
|
|
{ "-mrhoistk",1, (void (*)(...)) pMRhoistk, /* MR9 */
|
|
"Turn on/off EXPERIMENTAL k>1 Maintenance Release style hoisting"}, /* MR13 */
|
|
{ "-aa" , 1, (void (*)(...)) pAA, "Ambiguity aid for a rule (rule name or line number)"}, /* MR11 */
|
|
{ "-aam" , 0, (void (*)(...)) pAAm,
|
|
"Lookahead token may appear multiple times in -aa listing"}, /* MR11 */
|
|
{ "-aad" , 1, (void (*)(...)) pAAd,
|
|
"Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */
|
|
{ "-info", 1, (void (*)(...)) pInfo,
|
|
"Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"}, /* MR12 */
|
|
{ "-treport",1,(void (*)(...)) pTreport,
|
|
"Report when tnode usage exceeds value during ambiguity resolution"}, /* MR11 */
|
|
{ "-newAST", 0, (void (*)(...)) pNewAST,
|
|
"In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""}, /* MR13 */
|
|
{ "-tmake", 0, (void (*)(...)) ptmakeInParser,
|
|
"In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""}, /* MR23 */
|
|
{ "-alpha",0,(void (*)(...)) pAlpha,
|
|
"Provide additional information for \"(alpha)? beta\" error messages"}, /* MR14 */
|
|
{ "-mrblkerr",0,(void (*)(...)) pMR_BlkErr, /* MR21 */
|
|
"EXPERIMENTAL change to (...)* and (...)+ syntax error sets"}, /* MR21 */
|
|
{ "-nopurify",0,(void (*)(...)) pNOPURIFY,
|
|
"Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"}, /* MR23 */
|
|
{ "*", 0, (void (*)(...)) pFile, "" }, /* anything else is a file */
|
|
#else
|
|
{ "-CC", 0, pCC, "Generate C++ output (default=FALSE)"},
|
|
{ "-cr", 0, pCr, "Generate cross reference (default=FALSE)"},
|
|
{ "-ck", 1, pCk, "Set compressed lookahead depth; fast approximate lookahead"},
|
|
{ "-e1", 0, pE1, "Ambiguities/errors shown in low detail (default)"},
|
|
{ "-e2", 0, pE2, "Ambiguities/errors shown in more detail"},
|
|
{ "-e3", 0, pE3, "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"},
|
|
{ "-f", 1, pFileList,"Read names of grammar files from specified file"}, /* MR14 */
|
|
{ "-fe", 1, pFe, "Rename err.c"},
|
|
{ "-fh", 1, pFHdr, "Rename stdpccts.h header (turns on -gh)"},
|
|
{ "-fl", 1, pFl, "Rename lexical output--parser.dlg"},
|
|
{ "-fm", 1, pFm, "Rename mode.h"},
|
|
{ "-fr", 1, pFr, "Rename remap.h"},
|
|
{ "-ft", 1, pFt, "Rename tokens.h"},
|
|
{ "-ga", 0, pANSI, "Generate ANSI-compatible code (default=FALSE)"},
|
|
{ "-gc", 0, pCGen, "Do not generate output parser code (default=FALSE)"},
|
|
{ "-gd", 0, pTGen, "Generate code to trace rule invocation (default=FALSE)"},
|
|
{ "-ge", 0, pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
|
|
{ "-gh", 0, pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
|
|
{ "-gk", 0, pDL, "Generate parsers that delay lookahead fetches until needed"},
|
|
{ "-gl", 0, pLI, "Generate line info about grammar actions in C parser"},
|
|
{ "-glms", 0, pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"},
|
|
{ "-gp", 1, pPre, "Prefix all generated rule functions with a string"},
|
|
{ "-gs", 0, pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
|
|
{ "-gt", 0, pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
|
|
{ "-gx", 0, pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
|
|
{ "-gxt",0, pXTGen, "Do not generate tokens.h (default=FALSE)"},
|
|
{ "-k", 1, pLLK, "Set full LL(k) lookahead depth (default==1)"},
|
|
{ "-o", 1, pOut, OutputDirectoryOption},
|
|
{ "-p", 0, pPrt, "Print out the grammar w/o actions (default=no)"},
|
|
{ "-pa", 0, pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
|
|
{ "-pr",0, pPred, "no longer used; predicates employed if present"},
|
|
{ "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
|
|
{ "-rl", 1, pTRes, "Limit max # of tree nodes used by grammar analysis"},
|
|
{ "-stdout",0, pStdout, "Send grammar.c/grammar.cpp to stdout"}, /* MR6 */
|
|
{ "-tab", 1, pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */
|
|
{ "-w1", 0, pW1, "Set the warning level to 1 (default)"},
|
|
{ "-w2", 0, pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
|
|
{ "-mrhoist",1,pMRhoist, /* MR9 */
|
|
"Turn on/off k=1 Maintenance Release style hoisting"}, /* MR9 */
|
|
{ "-mrhoistk",1,pMRhoistk, /* MR13 */
|
|
"Turn on/off k>1 EXPERIMENTAL Maintenance Release style hoisting"}, /* MR13 */
|
|
{ "-aa" ,1,pAA, "Ambiguity aid for a rule (rule name or line number)"}, /* MR11 */
|
|
{ "-aam" ,0,pAAm,
|
|
"Lookahead token may appear multiple times in -aa listing"}, /* MR11 */
|
|
{ "-aad" ,1,pAAd,
|
|
"Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */
|
|
{ "-info",1,pInfo,
|
|
"Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"}, /* MR11 */
|
|
{ "-treport",1,pTreport,
|
|
"Report when tnode usage exceeds value during ambiguity resolution"}, /* MR11 */
|
|
{ "-newAST", 0, pNewAST,
|
|
"In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""}, /* MR13 */
|
|
{ "-tmake", 0, ptmakeInParser,
|
|
"In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""}, /* MR23 */
|
|
{ "-alpha",0, pAlpha,
|
|
"Provide additional information for \"(alpha)? beta\" error messages"}, /* MR14 */
|
|
{ "-mrblkerr",0,pMR_BlkErr, /* MR21 */
|
|
"EXPERIMENTAL change to (...)* and (...)+ syntax error sets"}, /* MR21 */
|
|
{ "-nopurify",0,pNOPURIFY,
|
|
"Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"}, /* MR23 */
|
|
{ "-", 0, pStdin, "Read grammar from stdin" },
|
|
{ "*", 0, pFile, "" }, /* anything else is a file */
|
|
#endif
|
|
{ NULL, 0, NULL }
|
|
};
|
|
|
|
void readDescr();
|
|
void cleanUp();
|
|
|
|
#ifdef __USE_PROTOS
|
|
static void buildRulePtr( void );
|
|
static void help( void );
|
|
static void init( void );
|
|
static void CompleteTokenSetRefs( void );
|
|
static void ensure_no_C_file_collisions(char *);
|
|
static void CompleteContextGuards(void);
|
|
#else
|
|
static void buildRulePtr( );
|
|
static void help( );
|
|
static void init( );
|
|
static void CompleteTokenSetRefs( );
|
|
static void ensure_no_C_file_collisions();
|
|
static void CompleteContextGuards();
|
|
#endif
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS /* <BJS> */
|
|
report_numericPredLabels(ActionNode *a)
|
|
#else
|
|
report_numericPredLabels(a)
|
|
ActionNode *a;
|
|
#endif
|
|
{ /* MR10 */
|
|
warnFL("numeric references to attributes (e.g. $i or $i.j) in semantic pred will be null during guess mode", /* MR10 */
|
|
FileStr[a->file],a->line); /* MR10 */
|
|
} /* MR10 */
|
|
|
|
/* M a i n */
|
|
|
|
int
|
|
#ifdef __USE_PROTOS
|
|
main( int argc, char *argv[] )
|
|
#else
|
|
main( argc, argv )
|
|
int argc;
|
|
char *argv[];
|
|
#endif
|
|
{
|
|
int i;
|
|
static char EPSTR[] = "[Ep]";
|
|
|
|
Save_argc=argc; /* MR10 */
|
|
Save_argv=argv; /* MR10 */
|
|
|
|
/* malloc_debug(8);*/
|
|
|
|
#ifdef SPECIAL_INITS
|
|
special_inits(); /* MR1 */
|
|
#endif
|
|
fprintf(stderr, "Antlr parser generator Version %s 1989-2001\n", Version);
|
|
if ( argc == 1 ) { help(); zzDIE; }
|
|
ProcessArgs(argc-1, &(argv[1]), options);
|
|
|
|
/* MR14 */ if (MR_AmbAidRule && AlphaBetaTrace) {
|
|
/* MR14 */ fatal("Can't specify both -aa (ambiguity aid) and -alpha (\"(alpha)? beta\" aid)");
|
|
/* MR14 */ }
|
|
|
|
if (MRhoistingk) { /* MR13 */
|
|
HoistPredicateContext=1; /* MR13 */
|
|
MRhoisting=1; /* MR13 */
|
|
}; /* MR13 */
|
|
if (MRhoisting && ! HoistPredicateContext) {
|
|
/*** warnNoFL("Using \"-mrhoist\" forces \"-prc on\""); ***/
|
|
HoistPredicateContext=1;
|
|
};
|
|
if (HoistPredicateContext && ! MRhoisting) {
|
|
warnNoFL("When using predicate context (-prc on) -mrhoist on is recommended");
|
|
}
|
|
/* Fix lookahead depth */
|
|
/* Compressed lookahead must always be larger than or equal to full lookahead */
|
|
if ( CLL_k < LL_k && CLL_k>0 )
|
|
{
|
|
warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
|
|
CLL_k = LL_k;
|
|
}
|
|
if ( CLL_k == -1 ) CLL_k = LL_k;
|
|
OutputLL_k = CLL_k;
|
|
if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
|
|
int n;
|
|
for(n=1; n<CLL_k; n<<=1) {;}
|
|
OutputLL_k = n;
|
|
};
|
|
|
|
if (MR_BlkErr) {
|
|
warnNoFL("The -mrblkerr option is EXPERIMENTAL");
|
|
if (LL_k > 1) {
|
|
warnNoFL("The -mrblkerr option is designed only for k=1 ck=1 grammars");
|
|
}
|
|
};
|
|
|
|
if ( ! ambAidDepthSpecified) {
|
|
MR_AmbAidDepth=1;
|
|
} else {
|
|
if (MR_AmbAidDepth > CLL_k || MR_AmbAidDepth <= 0) {
|
|
warnNoFL(eMsgd(
|
|
"Ambiguity aid depth (\"-aad ...\") must be a number between 1 and max(k,ck)=%d",CLL_k));
|
|
MR_AmbAidDepth=1;
|
|
};
|
|
if (MR_AmbAidDepth == 0) {
|
|
MR_AmbAidDepth=2;
|
|
};
|
|
};
|
|
|
|
if (MR_AmbAidRule != NULL) MR_AmbAidLine=atoi(MR_AmbAidRule);
|
|
|
|
fpTrans = &(C_Trans[0]); /* Translate to C Language */
|
|
fpJTrans = &(C_JTrans[0]);
|
|
init();
|
|
lexclass(LexStartSymbol);
|
|
|
|
readDescr();
|
|
LastTokenCounted = TokenNum;
|
|
RemapForcedTokens();
|
|
if ( CannotContinue ) {cleanUp(); zzDIE;}
|
|
if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
|
|
if ( WarningLevel>1 && HdrAction == NULL )
|
|
warnNoFL("no #header action was found");
|
|
if ( FoundAtOperator && ! FoundExceptionGroup) {
|
|
warnNoFL("found the exception operator '@' - but no exception group was found");
|
|
};
|
|
EpToken = addTname(EPSTR); /* add imaginary token epsilon */
|
|
set_orel(EpToken, &imag_tokens);
|
|
|
|
/* this won't work for hand-built scanners since EofToken is not
|
|
* known. Forces EOF to be token type 1.
|
|
*/
|
|
set_orel(EofToken, &imag_tokens);
|
|
|
|
set_size(NumWords(TokenNum-1));
|
|
|
|
/* compute the set of all known token types
|
|
* It represents the set of tokens from 1 to last_token_num + the
|
|
* reserved positions above that (if any). Don't include the set of
|
|
* imaginary tokens such as the token/error classes or EOF.
|
|
*/
|
|
{
|
|
set a;
|
|
a = set_dup(reserved_positions);
|
|
for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
|
|
all_tokens = set_dif(a, imag_tokens);
|
|
set_free(a);
|
|
}
|
|
|
|
ComputeTokSets(); /* Compute #tokclass sets */
|
|
CompleteTokenSetRefs(); /* Change complex nodes in syn diag */
|
|
CompleteContextGuards(); /* MR13 */
|
|
|
|
if ( CodeGen ) genDefFile(); /* create tokens.h */
|
|
if ( LexGen ) genLexDescr(); /* create parser.dlg */
|
|
|
|
if ( GenStdPccts )
|
|
{
|
|
FILE *f = fopen(OutMetaName(stdpccts), "w");
|
|
if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
|
|
else
|
|
{
|
|
#ifdef SPECIAL_FOPEN
|
|
special_fopen_actions(OutMetaName(stdpccts)); /* MR1 */
|
|
#endif
|
|
if (strcmp(stdpccts,"stdpccts.h") == 0) { /* MR10 */
|
|
genStdPCCTSIncludeFile(f,NULL); /* MR10 */
|
|
} else { /* MR10 */
|
|
genStdPCCTSIncludeFile(f,pcctsBaseName(stdpccts)); /* MR32 */
|
|
};
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
buildRulePtr(); /* create mapping from rule # to RuleBlk junction */
|
|
ComputeErrorSets();
|
|
FoLink( (Node *)SynDiag ); /* add follow links to end of all rules */
|
|
|
|
if ( GenCR ) GenCrossRef( SynDiag );
|
|
|
|
if ( CodeGen )
|
|
{
|
|
if ( SynDiag == NULL )
|
|
{
|
|
warnNoFL("no grammar description recognized");
|
|
cleanUp();
|
|
zzDIE;
|
|
}
|
|
else if ( !GenCC ) {
|
|
ErrFile = fopen(OutMetaName(ErrFileName), "w");
|
|
require(ErrFile != NULL, "main: can't open err file");
|
|
#ifdef SPECIAL_FOPEN
|
|
special_fopen_actions(OutMetaName(ErrFileName)); /* MR1 */
|
|
#endif
|
|
NewSetWd();
|
|
GenErrHdr();
|
|
TRANS(SynDiag); /* Translate to the target language */
|
|
DumpSetWd();
|
|
DumpRemainingTokSets();
|
|
fclose( ErrFile );
|
|
}
|
|
else {
|
|
strcpy(Parser_h_Name, CurrentClassName);
|
|
strcat(Parser_h_Name, ".h");
|
|
strcpy(Parser_c_Name, CurrentClassName);
|
|
strcat(Parser_c_Name, CPP_FILE_SUFFIX);
|
|
ensure_no_C_file_collisions(Parser_c_Name);
|
|
Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
|
|
require(Parser_h != NULL, "main: can't open class Parserx.h file");
|
|
#ifdef SPECIAL_FOPEN
|
|
special_fopen_actions(OutMetaName(Parser_h_Name)); /* MR1 */
|
|
#endif
|
|
Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
|
|
require(Parser_c != NULL, "main: can't open class Parserx.c file");
|
|
#ifdef SPECIAL_FOPEN
|
|
special_fopen_actions(OutMetaName(Parser_c_Name)); /* MR1 */
|
|
#endif
|
|
GenParser_h_Hdr();
|
|
if ( class_before_actions != NULL )
|
|
{
|
|
ListNode *p;
|
|
for (p = class_before_actions->next; p!=NULL; p=p->next)
|
|
{
|
|
UserAction *ua = (UserAction *)p->elem;
|
|
dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
|
|
}
|
|
}
|
|
GenParser_c_Hdr();
|
|
fprintf(Parser_h, "protected:\n"); /* MR20 */
|
|
NewSetWd();
|
|
TRANS(SynDiag); /* Translate to the target language */
|
|
DumpSetWd();
|
|
GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
|
|
if ( class_after_actions != NULL )
|
|
{
|
|
ListNode *p;
|
|
for (p = class_after_actions->next; p!=NULL; p=p->next)
|
|
{
|
|
UserAction *ua = (UserAction *)p->elem;
|
|
dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
|
|
}
|
|
}
|
|
DumpRemainingTokSets();
|
|
fprintf(Parser_h, "};\n");
|
|
fprintf(Parser_h, "\n#endif /* %s_h */\n", CurrentClassName);
|
|
fclose( Parser_h );
|
|
fclose( Parser_c );
|
|
}
|
|
}
|
|
|
|
MR_orphanRules(stderr);
|
|
if (LTinTokenAction && WarningLevel >= 2) {
|
|
if (GenCC) {
|
|
warnNoFL("At least one <<action>> following a token match contains a reference to LT(...)\n this will reference the immediately preceding token,\n not the one which follows as is the case with semantic predicates.");
|
|
}
|
|
warnNoFL("At least one <<action>> following a token match contains a reference to LA(...) or LATEXT(...)\n this will reference the immediately preceding token,\n not the one which follows as is the case with semantic predicates.");
|
|
}
|
|
|
|
if ( PrintOut )
|
|
{
|
|
if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
|
|
else PRINT(SynDiag);
|
|
}
|
|
|
|
#ifdef DBG_LL1
|
|
#endif
|
|
GenRemapFile(); /* create remap.h */
|
|
/* MR10 */ if (FoundGuessBlk) {
|
|
#ifdef __cplusplus__
|
|
/* MR10 */ list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels);
|
|
#else
|
|
#ifdef __USE_PROTOS
|
|
/* MR10 */ list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels);
|
|
#else
|
|
/* MR10 */ list_apply(NumericPredLabels,report_numericPredLabels);
|
|
#endif
|
|
#endif
|
|
/* MR10 */ };
|
|
|
|
if (InfoT && TnodesAllocated > 0) {
|
|
if (TnodesPeak > 10000) {
|
|
fprintf(stdout,"\nTree Nodes: peak %dk created %dk lost %d\n",
|
|
(TnodesPeak/1000),
|
|
(TnodesAllocated/1000),
|
|
TnodesInUse-tnodes_used_in_guard_predicates_etc);
|
|
} else {
|
|
fprintf(stdout,"\nTree Nodes: peak %d created %d lost %d\n",
|
|
TnodesPeak,
|
|
TnodesAllocated,
|
|
TnodesInUse-tnodes_used_in_guard_predicates_etc);
|
|
};
|
|
};
|
|
if (InfoF) {
|
|
DumpFcache();
|
|
};
|
|
if (MR_skipped_e3_report) {
|
|
fprintf(stderr,"note: use -e3 to get exact information on ambiguous tuples\n");
|
|
};
|
|
if (MR_BadExprSets != 0) {
|
|
fprintf(stderr,"note: Unreachable C or C++ code was generated for empty expression sets,\n");
|
|
fprintf(stderr," probably due to undefined rules or infinite left recursion.\n");
|
|
fprintf(stderr," To locate: search the generated code for \"empty set expression\"\n");
|
|
};
|
|
if (MR_AmbAidRule != NULL && MR_matched_AmbAidRule==0) {
|
|
RuleEntry *q = (RuleEntry *) hash_get(Rname,MR_AmbAidRule);
|
|
if (MR_AmbAidLine == 0 && q == NULL) {
|
|
warnNoFL(eMsg2("there is no rule \"%s\" so \"-aa %s\" will never match",
|
|
MR_AmbAidRule,MR_AmbAidRule));
|
|
} else {
|
|
warnNoFL(eMsg1("there was no ambiguity that matched \"-aa %s\"",MR_AmbAidRule));
|
|
};
|
|
};
|
|
if (AlphaBetaTrace) {
|
|
|
|
if (MR_AlphaBetaMessageCount == 0) {
|
|
fprintf(stderr,"note: there were no messages about \"(alpha)? beta\" blocks added to the generated code\n");
|
|
} else {
|
|
fprintf(stderr,"note: there were %d messages about \"(alpha)? beta\" blocks added to the generated code\n",
|
|
MR_AlphaBetaMessageCount);
|
|
}
|
|
|
|
if (set_null(MR_CompromisedRules)) {
|
|
fprintf(stderr,"note: the list of rules with compromised follow sets is empty\n");
|
|
} else {
|
|
fprintf(stderr,"note: the following is a list of rules which *may* have incorrect\n");
|
|
fprintf(stderr," follow sets computed as a result of an \"(alpha)? beta\" block\n");
|
|
fprintf(stderr,"\n");
|
|
MR_dumpRuleSet(MR_CompromisedRules);
|
|
fprintf(stderr,"\n");
|
|
}
|
|
}
|
|
cleanUp();
|
|
exit(PCCTS_EXIT_SUCCESS);
|
|
return 0; /* MR11 make compilers happy */
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
init( void )
|
|
#else
|
|
init( )
|
|
#endif
|
|
{
|
|
SignalEntry *q;
|
|
|
|
Tname = newHashTable();
|
|
Rname = newHashTable();
|
|
Fcache = newHashTable();
|
|
Tcache = newHashTable();
|
|
Sname = newHashTable();
|
|
Pname = newHashTable(); /* MR11 */
|
|
|
|
/* Add default signal names */
|
|
q = (SignalEntry *)hash_add(Sname,
|
|
"NoViableAlt",
|
|
(Entry *)newSignalEntry("NoViableAlt"));
|
|
require(q!=NULL, "cannot alloc signal entry");
|
|
q->signum = sigNoViableAlt;
|
|
q = (SignalEntry *)hash_add(Sname,
|
|
"MismatchedToken",
|
|
(Entry *)newSignalEntry("MismatchedToken"));
|
|
require(q!=NULL, "cannot alloc signal entry");
|
|
q->signum = sigMismatchedToken;
|
|
q = (SignalEntry *)hash_add(Sname,
|
|
"NoSemViableAlt",
|
|
(Entry *)newSignalEntry("NoSemViableAlt"));
|
|
require(q!=NULL, "cannot alloc signal entry");
|
|
q->signum = sigNoSemViableAlt;
|
|
|
|
reserved_positions = empty;
|
|
all_tokens = empty;
|
|
imag_tokens = empty;
|
|
tokclasses = empty;
|
|
TokenStr = (char **) calloc(TSChunk, sizeof(char *));
|
|
require(TokenStr!=NULL, "main: cannot allocate TokenStr");
|
|
FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
|
|
require(FoStack!=NULL, "main: cannot allocate FoStack");
|
|
FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
|
|
require(FoTOS!=NULL, "main: cannot allocate FoTOS");
|
|
Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
|
|
require(Cycles!=NULL, "main: cannot allocate Cycles List");
|
|
MR_CompromisedRules=empty; /* MR14 */
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
help( void )
|
|
#else
|
|
help( )
|
|
#endif
|
|
{
|
|
Opt *p = options;
|
|
fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
|
|
while ( *(p->option) != '*' )
|
|
{
|
|
fprintf(stderr, " %-9s%s %s\n",
|
|
p->option,
|
|
(p->arg)?"___":" ",
|
|
p->descr);
|
|
p++;
|
|
}
|
|
}
|
|
|
|
/* The RulePtr array is filled in here. RulePtr exists primarily
|
|
* so that sets of rules can be maintained for the FOLLOW caching
|
|
* mechanism found in rJunc(). RulePtr maps a rule num from 1 to n
|
|
* to a pointer to its RuleBlk junction where n is the number of rules.
|
|
*/
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
buildRulePtr( void )
|
|
#else
|
|
buildRulePtr( )
|
|
#endif
|
|
{
|
|
int r=1;
|
|
Junction *p = SynDiag;
|
|
RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
|
|
require(RulePtr!=NULL, "cannot allocate RulePtr array");
|
|
|
|
while ( p!=NULL )
|
|
{
|
|
require(r<=NumRules, "too many rules???");
|
|
RulePtr[r++] = p;
|
|
p = (Junction *)p->p2;
|
|
}
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
dlgerror(const char *s)
|
|
#else
|
|
dlgerror(s)
|
|
char *s;
|
|
#endif
|
|
{
|
|
fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
|
|
fprintf(stderr, " lexical error: %s (text was '%s')\n",
|
|
((s == NULL) ? "Lexical error" : s), zzlextext);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
readDescr( void )
|
|
#else
|
|
readDescr( )
|
|
#endif
|
|
{
|
|
zzerr = dlgerror;
|
|
input = NextFile();
|
|
if ( input==NULL ) fatal("No grammar description found (exiting...)");
|
|
ANTLR(grammar(), input);
|
|
tnodes_used_in_guard_predicates_etc=TnodesInUse; /* MR10 */
|
|
}
|
|
|
|
FILE *
|
|
#ifdef __USE_PROTOS
|
|
NextFile( void )
|
|
#else
|
|
NextFile( )
|
|
#endif
|
|
{
|
|
FILE *f;
|
|
|
|
for (;;)
|
|
{
|
|
CurFile++;
|
|
if ( CurFile >= NumFiles ) return(NULL);
|
|
if ( ci_strequ(FileStr[CurFile],"stdin")) return stdin;
|
|
f = fopen(FileStr[CurFile], "r");
|
|
if ( f == NULL )
|
|
{
|
|
warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
|
|
}
|
|
else
|
|
{
|
|
return(f);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Return a string corresponding to the output file name associated
|
|
* with the input file name passed in.
|
|
*
|
|
* Observe the following rules:
|
|
*
|
|
* f.e --> f".c"
|
|
* f --> f".c"
|
|
* f. --> f".c"
|
|
* f.e.g --> f.e".c"
|
|
*
|
|
* Where f,e,g are arbitrarily long sequences of characters in a file
|
|
* name.
|
|
*
|
|
* In other words, if a ".x" appears on the end of a file name, make it
|
|
* ".c". If no ".x" appears, append ".c" to the end of the file name.
|
|
*
|
|
* C++ mode using .cpp not .c.
|
|
*
|
|
* Use malloc() for new string.
|
|
*/
|
|
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
outname( char *fs )
|
|
#else
|
|
outname( fs )
|
|
char *fs;
|
|
#endif
|
|
{
|
|
if ( GenCC) {
|
|
return outnameX(fs,CPP_FILE_SUFFIX);
|
|
} else {
|
|
return outnameX(fs,".c");
|
|
};
|
|
}
|
|
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
outnameX( char *fs ,char *suffix)
|
|
#else
|
|
outnameX( fs , suffix )
|
|
char *fs;
|
|
char *suffix;
|
|
#endif
|
|
{
|
|
static char buf[MaxFileName+1];
|
|
char *p;
|
|
require(fs!=NULL&&*fs!='\0', "outname: NULL filename");
|
|
|
|
p = buf;
|
|
strcpy(buf, fs);
|
|
while ( *p != '\0' ) {p++;} /* Stop on '\0' */
|
|
while ( *p != '.' && p != buf ) {--p;} /* Find '.' */
|
|
if ( p != buf ) *p = '\0'; /* Found '.' */
|
|
require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big");
|
|
strcat(buf,suffix);
|
|
return( buf );
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
fatalFL( char *err_, char *f, int l )
|
|
#else
|
|
fatalFL( err_, f, l )
|
|
char *err_;
|
|
char *f;
|
|
int l;
|
|
#endif
|
|
{
|
|
fprintf(stderr, ErrHdr, f, l);
|
|
fprintf(stderr, " %s\n", err_);
|
|
cleanUp();
|
|
exit(PCCTS_EXIT_FAILURE);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
fatal_intern( char *err_, char *f, int l )
|
|
#else
|
|
fatal_intern( err_, f, l )
|
|
char *err_;
|
|
char *f;
|
|
int l;
|
|
#endif
|
|
{
|
|
fprintf(stderr, ErrHdr, f, l);
|
|
fprintf(stderr, " #$%%*&@# internal error: %s\n", err_);
|
|
fprintf(stderr, ErrHdr, f, l);
|
|
fprintf(stderr, " [complain to nearest government official\n");
|
|
fprintf(stderr, ErrHdr, f, l);
|
|
fprintf(stderr, " or send hate-mail to parrt@parr-research.com;\n");
|
|
fprintf(stderr, ErrHdr, f, l);
|
|
fprintf(stderr, " please pray to the ``bug'' gods that there is a trival fix.]\n");
|
|
cleanUp();
|
|
exit(PCCTS_EXIT_FAILURE);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
cleanUp( void )
|
|
#else
|
|
cleanUp( )
|
|
#endif
|
|
{
|
|
if ( DefFile != NULL) fclose( DefFile );
|
|
}
|
|
|
|
/* sprintf up to 3 strings */
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
eMsg3( char *s, char *a1, char *a2, char *a3 )
|
|
#else
|
|
eMsg3( s, a1, a2, a3 )
|
|
char *s;
|
|
char *a1;
|
|
char *a2;
|
|
char *a3;
|
|
#endif
|
|
{
|
|
static char buf[250]; /* DANGEROUS as hell !!!!!! */
|
|
|
|
sprintf(buf, s, a1, a2, a3);
|
|
return( buf );
|
|
}
|
|
|
|
/* sprintf a decimal */
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
eMsgd( char *s, int d )
|
|
#else
|
|
eMsgd( s, d )
|
|
char *s;
|
|
int d;
|
|
#endif
|
|
{
|
|
static char buf[250]; /* DANGEROUS as hell !!!!!! */
|
|
|
|
sprintf(buf, s, d);
|
|
return( buf );
|
|
}
|
|
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
eMsgd2( char *s, int d1,int d2)
|
|
#else
|
|
eMsgd2( s, d1, d2 )
|
|
char *s;
|
|
int d1;
|
|
int d2;
|
|
#endif
|
|
{
|
|
static char buf[250]; /* DANGEROUS as hell !!!!!! */
|
|
|
|
sprintf(buf, s, d1, d2);
|
|
return( buf );
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
s_fprT( FILE *f, set e )
|
|
#else
|
|
s_fprT( f, e )
|
|
FILE *f;
|
|
set e;
|
|
#endif
|
|
{
|
|
register unsigned *p;
|
|
unsigned *q;
|
|
|
|
if ( set_nil(e) ) return;
|
|
if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
|
|
fprintf(f, "{");
|
|
while ( *p != nil )
|
|
{
|
|
fprintf(f, " %s", TerminalString(*p));
|
|
p++;
|
|
}
|
|
fprintf(f, " }");
|
|
free((char *)q);
|
|
}
|
|
|
|
/* Return the token name or regular expression for a token number. */
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
TerminalString( int token )
|
|
#else
|
|
TerminalString( token )
|
|
int token;
|
|
#endif
|
|
{
|
|
int j;
|
|
static char imag_name[25];
|
|
|
|
/* look in all lexclasses for the token */
|
|
if ( TokenString(token) != NULL ) return TokenString(token);
|
|
for (j=0; j<NumLexClasses; j++)
|
|
{
|
|
lexmode(j);
|
|
if ( ExprString(token) != NULL ) return ExprString(token);
|
|
}
|
|
|
|
if (1) {
|
|
snprintf(imag_name, 25, "UnknownToken#%d", token); /* MR13 */
|
|
return imag_name; /* MR13 */
|
|
}
|
|
|
|
require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
|
|
return "invalid";
|
|
}
|
|
|
|
/* S i m p l e I n t S t a c k */
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
pushint( int i )
|
|
#else
|
|
pushint( i )
|
|
int i;
|
|
#endif
|
|
{
|
|
require(isp>0, "pushint: stack overflow");
|
|
istack[--isp] = i;
|
|
}
|
|
|
|
int
|
|
#ifdef __USE_PROTOS
|
|
popint( void )
|
|
#else
|
|
popint( )
|
|
#endif
|
|
{
|
|
require(isp<MAX_INT_STACK, "popint: stack underflow");
|
|
return istack[isp++];
|
|
}
|
|
|
|
int
|
|
#ifdef __USE_PROTOS
|
|
istacksize( void )
|
|
#else
|
|
istacksize( )
|
|
#endif
|
|
{
|
|
return MAX_INT_STACK-isp;
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
istackreset( void )
|
|
#else
|
|
istackreset( )
|
|
#endif
|
|
{
|
|
isp = MAX_INT_STACK;
|
|
}
|
|
|
|
int
|
|
#ifdef __USE_PROTOS
|
|
istackempty( void )
|
|
#else
|
|
istackempty( )
|
|
#endif
|
|
{
|
|
return isp==MAX_INT_STACK;
|
|
}
|
|
|
|
int
|
|
#ifdef __USE_PROTOS
|
|
topint( void )
|
|
#else
|
|
topint( )
|
|
#endif
|
|
{
|
|
require(isp<MAX_INT_STACK, "topint: stack underflow");
|
|
return istack[isp];
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
ProcessArgs( int argc, char **argv, Opt *options )
|
|
#else
|
|
ProcessArgs( argc, argv, options )
|
|
int argc;
|
|
char **argv;
|
|
Opt *options;
|
|
#endif
|
|
{
|
|
Opt *p;
|
|
require(argv!=NULL, "ProcessArgs: command line NULL");
|
|
|
|
while ( argc-- > 0 )
|
|
{
|
|
p = options;
|
|
while ( p->option != NULL )
|
|
{
|
|
if ( strcmp(p->option, "*") == 0 ||
|
|
ci_strequ(p->option, *argv) == 1 )
|
|
{
|
|
if ( p->arg )
|
|
{
|
|
/* MR9 26-Sep-97 Check for argv valid */
|
|
if (argc-- > 0) {
|
|
(*p->process)( *argv, *(argv+1) );
|
|
argv++;
|
|
} else {
|
|
fprintf(stderr,"error: required argument for option %s omitted\n",*argv);
|
|
exit(PCCTS_EXIT_FAILURE);
|
|
};
|
|
}
|
|
else
|
|
(*p->process)( *argv );
|
|
break;
|
|
}
|
|
p++;
|
|
}
|
|
argv++;
|
|
}
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
CompleteContextGuards(void)
|
|
#else
|
|
CompleteContextGuards()
|
|
#endif
|
|
{
|
|
ListNode * p;
|
|
Predicate * pred;
|
|
|
|
if (ContextGuardPredicateList == NULL) return;
|
|
|
|
for (p=ContextGuardPredicateList->next; p != NULL; p=p->next) {
|
|
pred=(Predicate *)p->elem;
|
|
recomputeContextGuard(pred);
|
|
}
|
|
}
|
|
|
|
/* Go back into the syntax diagram and compute all meta tokens; i.e.
|
|
* turn all '.', ranges, token class refs etc... into actual token sets
|
|
*/
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
CompleteTokenSetRefs(void)
|
|
#else
|
|
CompleteTokenSetRefs()
|
|
#endif
|
|
{
|
|
ListNode *p;
|
|
|
|
if ( MetaTokenNodes==NULL ) return;
|
|
for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
|
|
{
|
|
set a,b;
|
|
|
|
TokNode *q = (TokNode *)p->elem;
|
|
if ( q->wild_card )
|
|
{
|
|
q->tset = all_tokens;
|
|
}
|
|
else if ( q->tclass!=NULL )
|
|
{
|
|
if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
|
|
else q->tset = q->tclass->tset;
|
|
}
|
|
else if ( q->upper_range!=0 )
|
|
{
|
|
/* we have a range on our hands: make a set from q->token .. q->upper_range */
|
|
int i;
|
|
a = empty;
|
|
for (i=q->token; i<=q->upper_range; i++) { set_orel(i, &a); } /* MR13 */
|
|
|
|
/* MR13 */ if (q->complement) {
|
|
/* MR13 */ q->tset = set_dif(all_tokens, a);
|
|
/* MR13 */ set_free(a);
|
|
/* MR13 */ } else {
|
|
/* MR13 */ q->tset = a;
|
|
/* MR13 */ }
|
|
|
|
}
|
|
|
|
/* at this point, it can only be a complemented single token */
|
|
else if ( q->complement )
|
|
{
|
|
a = set_of(q->token);
|
|
b = set_dif(all_tokens, a);
|
|
set_free(a);
|
|
q->tset=b;
|
|
}
|
|
else fatal("invalid meta token");
|
|
}
|
|
}
|
|
|
|
/* MR10: Jeff Vincent
|
|
MR10: Changed to remove directory information from n only if
|
|
MR10: if OutputDirectory was changed by user (-o option)
|
|
*/
|
|
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
OutMetaName(char *n)
|
|
#else
|
|
OutMetaName(n)
|
|
char *n;
|
|
#endif
|
|
{
|
|
static char *dir_sym = DirectorySymbol;
|
|
static char newname[MaxFileName+1];
|
|
char *p;
|
|
|
|
/* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */
|
|
if (strcmp(OutputDirectory, TopDirectory) == 0) /* TopDirectory is "." on Unix. */
|
|
return n;
|
|
|
|
/* p will point to filename without path information */
|
|
if ((p = strrchr(n, *dir_sym)) != NULL) /* Directory symbol is "/" on Unix. */
|
|
p++;
|
|
else
|
|
p = n;
|
|
|
|
/* Copy new output directory into newname[] */
|
|
strcpy(newname, OutputDirectory);
|
|
|
|
/* if new output directory does not have trailing dir_sym, add it! */
|
|
if (newname[strlen(newname)-1] != *dir_sym) {
|
|
strcat(newname, dir_sym);
|
|
}
|
|
strcat(newname, p);
|
|
return newname;
|
|
}
|
|
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
pcctsBaseName(char *n) /* MR32 */
|
|
#else
|
|
pcctsBaseName(n)
|
|
char *n;
|
|
#endif
|
|
{
|
|
static char newname[MaxFileName+1];
|
|
static char* dir_sym = DirectorySymbol;
|
|
int count = 0;
|
|
char *p;
|
|
|
|
p = n;
|
|
|
|
while ( *p != '\0' ) {p++;} /* go to end of string */
|
|
while ( (*p != *dir_sym) && (p != n) ) {--p;} /* Find last DirectorySymbol */
|
|
while ( *p == *dir_sym) p++; /* step forward if we're on a dir symbol */
|
|
while ( *p != '\0' && *p != '.')
|
|
{
|
|
newname[count++] = *p;
|
|
p++;
|
|
} /* create a new name */
|
|
newname[count] = '\0';
|
|
return newname;
|
|
}
|
|
|
|
static void
|
|
#ifdef __USE_PROTOS
|
|
ensure_no_C_file_collisions(char *class_c_file)
|
|
#else
|
|
ensure_no_C_file_collisions(class_c_file)
|
|
char *class_c_file;
|
|
#endif
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i<NumFiles; i++)
|
|
{
|
|
|
|
#ifdef PCCTS_CASE_INSENSITIVE_FILE_NAME
|
|
/* assume that file names are case insensitive */
|
|
if ( STRICMP(outname(FileStr[i]), class_c_file)==0 )
|
|
#else
|
|
if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
|
|
#endif
|
|
{
|
|
fatal(eMsg1("class def output file conflicts with parser output file: %s",
|
|
outname(FileStr[i])));
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
warnNoFL(char *err)
|
|
#else
|
|
warnNoFL(err)
|
|
char *err;
|
|
#endif
|
|
{
|
|
fprintf(stderr, "warning: %s\n", err);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
warnFL(char *err,char *f,int l)
|
|
#else
|
|
warnFL(err,f,l)
|
|
char *f;
|
|
int l;
|
|
char *err;
|
|
#endif
|
|
{
|
|
fprintf(stderr, ErrHdr, f, l);
|
|
fprintf(stderr, " warning: %s\n", err);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
warn(char *err)
|
|
#else
|
|
warn(err)
|
|
char *err;
|
|
#endif
|
|
{
|
|
/* back up the file number if we hit an error at the end of the last file */
|
|
if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
|
|
fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
|
|
fprintf(stderr, " warning: %s\n", err);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
warnNoCR( char *err )
|
|
#else
|
|
warnNoCR( err )
|
|
char *err;
|
|
#endif
|
|
{
|
|
/* back up the file number if we hit an error at the end of the last file */
|
|
if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
|
|
fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
|
|
fprintf(stderr, " warning: %s", err);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
errNoFL(char *err)
|
|
#else
|
|
errNoFL(err)
|
|
char *err;
|
|
#endif
|
|
{
|
|
fprintf(stderr, "error: %s\n", err);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
errFL(char *err,char *f,int l)
|
|
#else
|
|
errFL(err,f,l)
|
|
char *err;
|
|
char *f;
|
|
int l;
|
|
#endif
|
|
{
|
|
fprintf(stderr, ErrHdr, f, l);
|
|
fprintf(stderr, " error: %s\n", err);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
err(char *err)
|
|
#else
|
|
err(err)
|
|
char *err;
|
|
#endif
|
|
{
|
|
/* back up the file number if we hit an error at the end of the last file */
|
|
if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
|
|
fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
|
|
fprintf(stderr, " error: %s\n", err);
|
|
}
|
|
|
|
void
|
|
#ifdef __USE_PROTOS
|
|
errNoCR( char *err )
|
|
#else
|
|
errNoCR( err )
|
|
char *err;
|
|
#endif
|
|
{
|
|
/* back up the file number if we hit an error at the end of the last file */
|
|
if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
|
|
fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
|
|
fprintf(stderr, " error: %s", err);
|
|
}
|
|
|
|
UserAction *
|
|
#ifdef __USE_PROTOS
|
|
newUserAction(char *s)
|
|
#else
|
|
newUserAction(s)
|
|
char *s;
|
|
#endif
|
|
{
|
|
UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));
|
|
require(ua!=NULL, "cannot allocate UserAction");
|
|
|
|
ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
|
|
strcpy(ua->action, s);
|
|
return ua;
|
|
}
|
|
|
|
/* Added by TJP September 1994 */
|
|
/* Take in file.h and return file_h; names w/o '.'s are left alone */
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
gate_symbol(char *name)
|
|
#else
|
|
gate_symbol(name)
|
|
char *name;
|
|
#endif
|
|
{
|
|
static char buf[100];
|
|
char *p;
|
|
sprintf(buf, "%s", name);
|
|
|
|
for (p=buf; *p!='\0'; p++)
|
|
{
|
|
if ( *p=='.' ) *p = '_';
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
char *
|
|
#ifdef __USE_PROTOS
|
|
makeAltID(int blockid, int altnum)
|
|
#else
|
|
makeAltID(blockid, altnum)
|
|
int blockid;
|
|
int altnum;
|
|
#endif
|
|
{
|
|
static char buf[100];
|
|
char *p;
|
|
sprintf(buf, "_blk%d_alt%d", blockid, altnum);
|
|
p = (char *)malloc(strlen(buf)+1);
|
|
strcpy(p, buf);
|
|
return p;
|
|
}
|