mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-11 14:28:08 +01:00
b1264ef1e3
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
1748 lines
52 KiB
C
Executable File
1748 lines
52 KiB
C
Executable File
/*
|
|
* 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[20];
|
|
|
|
/* 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) {
|
|
sprintf(imag_name,"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;
|
|
}
|