genmk.c

来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 1,064 行 · 第 1/2 页

C
1,064
字号
/*
 * genmk -- a program to make makefiles for PCCTS
 *
 * ANTLR 1.33MR23
 * Terence John Parr 1989 - 2000
 * Purdue University
 * U of MN
 */

#include <stdio.h>
#include <string.h>
#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */

#ifdef VAXC
#define DIE		return 0;
#define DONE	return 1;
#else
#define DIE		return 1;
#define DONE	return 0;
#endif

#ifndef require
#define require(expr, err) {if ( !(expr) ) fatal(err);}
#endif

#define MAX_FILES	50
#define MAX_CFILES	1600
#define MAX_SFILES	50
#define MAX_SORS	50
#define MAX_CLASSES	50

char *RENAME_OBJ_FLAG="-o",
     *RENAME_EXE_FLAG="-o";

char *dlg = "parser.dlg";
char *err = "err.c";
char *hdr = "stdpccts.h";
char *tok = "tokens.h";
char *mode = "mode.h";
char *scan = "scan";

char ATOKENBUFFER_O[100];
char APARSER_O[100];
char ASTBASE_O[100];
char PCCTSAST_O[100];
char LIST_O[100];
char DLEXERBASE_O[100];

/* Option flags */
static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES];
static char *cfiles[MAX_CFILES];
static char *sfiles[MAX_SORS][MAX_SFILES],*sclasses[MAX_SORS];
static int  num_sfiles[MAX_SORS]; /*sorcerer files in group */
static int  num_sors = 0; /*sorcerer groups */
static int  num_files = 0; /* grammar files */
static int  num_cfiles = 0; /* additional C/C++ files */
static int  num_classes = 0; /* ANTLR classes */
static int  user_lexer = 0;
static char *user_token_types = NULL;
static int  gen_CPP = 0;
static char *outdir=".";
static char *dlg_class = "DLGLexer";
static int  gen_trees = 0;
static int  gen_hoist = 0;
static int  nondef_comp = 0; /* 1=compiler is non default */
static char *compilerCCC="CC";
static char *compilerCC="cc";
static char *pccts_path="/usr/local/pccts";

#ifdef __STDC__
void help(void);
void mk(char *project, char **files, int n, int argc, char **argv);
void pfiles(char **files, int n, char *suffix);
void fatal(char *msg);
void warn(char *msg);
#else
void help();
void mk();
void pfiles();
void fatal();
void warn();
#endif

typedef struct _Opt {
			char *option;
			int arg;
#ifdef __cplusplus
			void (*process)(...);
#else
			void (*process)();
#endif
			char *descr;
		} Opt;

#ifdef __STDC__
static void ProcessArgs(int, char **, Opt *);
#else
static void ProcessArgs();
#endif

static void
#ifdef __STDC__
pProj(char *s, char *t )
#else
pProj( s, t )
char *s;
char *t;
#endif
{
	project = t;
}

static void
#ifdef __STDC__
pUL( char *s )
#else
pUL( s )
char *s;
#endif
{
	user_lexer = 1;
}

static void
#ifdef __STDC__
pCPP( char *s )
#else
pCPP( s )
char *s;
#endif
{
	gen_CPP = 1;
}

static void
#ifdef __STDC__
pUT( char *s, char *t )
#else
pUT( s, t )
char *s;
char *t;
#endif
{
	user_token_types = t;
}

static void
#ifdef __STDC__
pTrees( char *s )
#else
pTrees( s )
char *s;
#endif
{
	gen_trees = 1;
}

static void
#ifdef __STDC__
pHoist( char *s )
#else
pHoist( s )
char *s;
#endif
{
	gen_hoist = 1;
}

static void
#ifdef __STDC__
pSor( char *s )
#else
pSor( s )
char *s;
#endif
{
	require(num_sors<MAX_SORS, "exceeded max # of sorcerer groups");
	num_sors++;
	pTrees(NULL); /* silently turn on tree generation */
}

static void
#ifdef __STDC__
pSFiles( char *s, char *t )
#else
pSFiles( s, t )
char *s;
char *t;
#endif
{
	if (num_sors==0)
	{
		pSor(NULL);
		warn("sorcerer input file before any '-sor' option");
	}
		
	require(num_sfiles[num_sors-1]<MAX_SFILES,
		 "exceeded max # of sorcerer input files");
	sfiles[num_sors-1][num_sfiles[num_sors-1]++] = t;
}

static void
#ifdef __STDC__
pCFiles( char *s, char *t )
#else
pCFiles( s, t )
char *s;
char *t;
#endif
{
	require(num_cfiles<MAX_CFILES, "exceeded max # of C/C++ input files");
	cfiles[num_cfiles++] = t;
}

int
#ifdef __STDC__
isKnownSuffix( char *s )
#else
isKnownSuffix( s )
	char *s;
#endif
{
	if(s==NULL) return 0;
	if (strcasecmp(s,".c")==0) return 1;
	if (strcasecmp(s,".cc")==0) return 1;
	if (strcasecmp(s,".cpp")==0) return 1;
	if (strcasecmp(s,".cxx")==0) return 1;
	if (strcasecmp(s,CPP_FILE_SUFFIX)==0) return 1;
	if (strcasecmp(s,".sor")==0) return 2;
	return 0;
}

static void
#ifdef __STDC__
pFile( char *s )
#else
pFile( s )
char *s;
#endif
{
	if ( *s=='-' )
	{
		fprintf(stderr, "invalid option: '%s'; ignored...",s);
		return;
	}
	switch(isKnownSuffix(strrchr(s,'.')))
	{
	 case 1: /* c/c++ */
		pCFiles("-cfiles",s);
		return;
	 case 2: /* sorcerer */
		pSFiles("",s);
		return;
	 default: /* grammar (ANTLR) */
		break;
	}
	require(num_files<MAX_FILES, "exceeded max # of input files");
	files[num_files++] = s;
}

static void
#ifdef __STDC__
pClass( char *s, char *t )
#else
pClass( s, t )
char *s;
char *t;
#endif
{
	if (num_sors==0)
	{
		require(num_classes<MAX_CLASSES, "exceeded max # of grammar classes");
		classes[num_classes++] = t;
	} else
	{
		sclasses[num_sors-1] = t; /* one class per sorcerer group (last valid) */
	}
}

static void
#ifdef __STDC__
pDLGClass( char *s, char *t )
#else
pDLGClass( s, t )
char *s;
char *t;
#endif
{
	if ( !gen_CPP ) {
		fprintf(stderr, "-dlg-class makes no sense without C++ mode; ignored...");
	}
	else dlg_class = t;
}

static void
#ifdef __STDC__
pOdir( char *s, char *t )
#else
pOdir( s, t )
char *s;
char *t;
#endif
{
	outdir = t;
}

static void
#ifdef __STDC__
pHdr( char *s, char *t )
#else
pHdr( s, t )
char *s;
char *t;
#endif
{
	hdr = t;
}

static void
#ifdef __STDC__
pCompiler( char *s, char *t )
#else
pCompiler( s, t )
char *s;
char *t;
#endif
{
	compilerCCC = t;
	compilerCC = t;
	nondef_comp = 1;
}

static void
#ifdef __STDC__
ppccts_path( char *s, char *t )
#else
ppccts_path( s, t )
char *s;
char *t;
#endif
{
	pccts_path = t;
}

Opt options[] = {
	{ "-CC", 0,	pCPP,			"Generate C++ output"},
	{ "-class", 1,	pClass,		"Name of a grammar class defined in grammar (if C++)"},
	{ "-dlg-class", 1,pDLGClass,"Name of DLG lexer class (default=DLGLexer) (if C++)"},
	{ "-header", 1,pHdr,		"Name of ANTLR standard header info (default=no file)"},
	{ "-o", 1,	pOdir,			"Directory where output files should go (default=\".\")"},
	{ "-project", 1,	pProj,	"Name of executable to create (default=t)"},
	{ "-token-types", 1, pUT,	"Token types are in this file (don't use tokens.h)"},
	{ "-trees", 0, pTrees,		"Generate ASTs"},
	{ "-user-lexer", 0,	pUL,	"Do not create a DLG-based scanner"},
	{ "-mrhoist",0,pHoist,      "Maintenance release style hoisting"},
	{ "-cfiles",1,pCFiles,      "Additional files in C or C++ to compile"},
	{ "-sor",0,pSor,           "Start of sorcerer group"},
	{ "-pccts_path",1,ppccts_path,
			"Path for $PCCTS directory (default is /usr/local/pccts)"},
	{ "-compiler",1,pCompiler,
			"Default compiler (default is CC/cc)"},
	{ "*", 0,pFile, 	        "" },	/* anything else is a file */
	{ NULL, 0, NULL, NULL }
};

#ifdef __STDC__
extern char *DIR(void);
#else
extern char *DIR();
#endif

#ifdef __STDC__
int main(int argc, char **argv)
#else
int main(argc, argv)
int argc;
char **argv;
#endif
{
	int i;
	
	if ( argc == 1 ) { help(); DIE; }
	for(i=0;i<MAX_SORS;i++) num_sfiles[i]=0;
	
	ProcessArgs(argc-1, &(argv[1]), options);

	strcpy(ATOKENBUFFER_O, ATOKENBUFFER_C);
	ATOKENBUFFER_O[strlen(ATOKENBUFFER_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
	strcat(ATOKENBUFFER_O, OBJ_FILE_SUFFIX);
	strcpy(APARSER_O, APARSER_C);
	APARSER_O[strlen(APARSER_O)-strlen(CPP_FILE_SUFFIX)] = '\0';
	strcat(APARSER_O, OBJ_FILE_SUFFIX);

	strcpy(ASTBASE_O, ASTBASE_C);
	ASTBASE_O[strlen(ASTBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
	strcat(ASTBASE_O, OBJ_FILE_SUFFIX);

	strcpy(PCCTSAST_O, PCCTSAST_C);
	PCCTSAST_O[strlen(PCCTSAST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
	strcat(PCCTSAST_O, OBJ_FILE_SUFFIX);

	strcpy(LIST_O, LIST_C);
	LIST_O[strlen(LIST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
	strcat(LIST_O, OBJ_FILE_SUFFIX);

	strcpy(DLEXERBASE_O, DLEXERBASE_C);
	DLEXERBASE_O[strlen(DLEXERBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
	strcat(DLEXERBASE_O, OBJ_FILE_SUFFIX);

	if ( num_files == 0 ) fatal("no grammar files specified; exiting...");
	if ( !gen_CPP && num_classes>0 ) {
		warn("can't define classes w/o C++ mode; turning on C++ mode...\n");
		gen_CPP=1;
	}
	if (!gen_CPP && num_sors) {
		warn("can't define sorcerer group in C mode (yet); turning on C++ mode...\n");
		gen_CPP=1;
	}
	if ( gen_CPP && num_classes==0 ) {
		fatal("must define classes >0 grammar classes in C++ mode\n");
	}

	mk(project, files, num_files, argc, argv);
	DONE;
}

#ifdef __STDC__
void help(void)
#else
void help()
#endif
{
	Opt *p = options;
	static char buf[1000+1];

	fprintf(stderr, "genmk [options] f1.g ... fn.g\n");
	while ( p->option!=NULL && *(p->option) != '*' )
	{
		buf[0]='\0';
		if ( p->arg ) sprintf(buf, "%s ___", p->option);
		else strcpy(buf, p->option);
		fprintf(stderr, "\t%-16s   %s\n", buf, p->descr);
		p++;
	}
}

#ifdef __STDC__
void mk(char *project, char **files, int n, int argc, char **argv)
#else
void mk(project, files, n, argc, argv)
char *project;
char **files;
int n;
int argc;
char **argv;
#endif
{
	int i,j;

	printf("#\n");
	printf("# PCCTS makefile for: ");
	pfiles(files, n, NULL);
	printf("\n");
	printf("#\n");
	printf("# Created from:");
	for (i=0; i<argc; i++) printf(" %s", argv[i]);
	printf("\n");
	printf("#\n");
	printf("# PCCTS release 1.33MR23\n");
	printf("# Project: %s\n", project);
	if ( gen_CPP ) printf("# C++ output\n");
	else printf("# C output\n");
	if ( user_lexer ) printf("# User-defined scanner\n");
	else printf("# DLG scanner\n");
	if ( user_token_types!=NULL ) printf("# User-defined token types in '%s'\n", user_token_types);
	else printf("# ANTLR-defined token types\n");
	printf("#\n");
/***********
	printf(".SUFFIXES:\n.SUFFIXES:\t.o .cpp .c .h .g .i .dlg .sor\n"); 
 ***********/
	if ( user_token_types!=NULL ) {
		printf("# Make sure #tokdefs directive in ANTLR grammar lists this file:\n");
		printf("TOKENS = %s", user_token_types);
	}
	else printf("TOKENS = %stokens.h", DIR());
	printf("\n");
	printf("#\n");
	printf("# The following filenames must be consistent with ANTLR/DLG flags\n");
	printf("DLG_FILE = %s%s\n", DIR(), dlg);
	printf("ERR = %serr\n", DIR());
	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf("HDR_FILE = %s%s\n", DIR(), hdr);
	else printf("HDR_FILE =\n");
	if ( !gen_CPP ) printf("MOD_FILE = %s%s\n", DIR(), mode);
	if ( !gen_CPP ) printf("SCAN = %s\n", scan);
	else printf("SCAN = %s%s\n", DIR(), dlg_class);

	printf("PCCTS = %s\n",pccts_path);
	printf("ANTLR_H = $(PCCTS)%sh\n", DirectorySymbol);
	if (num_sors>0) {
		printf("SOR_H = $(PCCTS)%ssorcerer%sh\n", DirectorySymbol, DirectorySymbol);
		printf("SOR_LIB = $(PCCTS)%ssorcerer%slib\n",
			 	DirectorySymbol, DirectorySymbol);
	}
	printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol);
	printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol);
	printf("DLG = $(BIN)%sdlg\n", DirectorySymbol);
	if (num_sors>0) printf("SOR = $(BIN)%ssor\n", DirectorySymbol);
	printf("CFLAGS = -I. -I$(ANTLR_H)");
	if (num_sors>0) printf(" -I$(SOR_H)");
	if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir);
	printf(" $(COTHER)");
	printf("\n");
	printf("AFLAGS =");
	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
	if ( user_lexer ) printf(" -gx");
	if ( gen_CPP ) printf(" -CC");
	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr);
	if ( gen_trees ) printf(" -gt");
	if ( gen_hoist ) {
		printf(" -mrhoist on") ;
	} else {
		printf(" -mrhoist off");
	};
	printf(" $(AOTHER)");
	printf("\n");
	printf("DFLAGS = -C2 -i");
	if ( gen_CPP ) printf(" -CC");
	if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class);
	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
	printf(" $(DOTHER)");
	printf("\n");
	if (num_sors>0)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?