/* * genmk -- a program to make makefiles for PCCTS * * ANTLR 1.33MR23 * Terence John Parr 1989 - 2000 * Purdue University * U of MN */ #include #include #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_sors0 ) { 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; i0) { 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) { printf("SFLAGS = -CPP"); if ( strcmp(outdir,".")!=0 ) printf(" -out-dir %s", outdir); printf(" $(SOTHER)\n"); } printf("GRM = "); pfiles(files, n, NULL); printf("\n"); printf("SRC = "); if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT); else pfiles(files, n, "c"); if ( gen_CPP ) { printf(" \\\n\t"); pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT); printf(" \\\n\t"); printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C); if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C); if ( gen_trees ) { printf(" \\\n\t"); printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C); printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C); /* printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */ printf(" \\\n\t"); } printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C); } if ( !user_lexer ) { if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX); else printf(" %s$(SCAN).c", DIR()); } if ( !gen_CPP ) printf(" $(ERR).c"); for (i=0;i0) printf(" \\\n\t$(SOR_LIB)%sSTreeParser.cpp", DirectorySymbol); if (num_cfiles>0) { printf(" \\\n\t"); pfiles(cfiles,num_cfiles,NULL); } printf("\n\n"); printf("OBJ = "); pfiles(files, n, "o"); if ( gen_CPP ) { printf(" \\\n\t"); pclasses(classes, num_classes, "o"); printf(" \\\n\t"); printf("%s%s", DIR(), APARSER_O); if ( !user_lexer ) { printf(" %s%s", DIR(), DLEXERBASE_O); } if ( gen_trees ) { printf(" \\\n\t"); printf("%s%s", DIR(), ASTBASE_O); printf(" %s%s", DIR(), PCCTSAST_O); /* printf(" %s%s", DIR(), LIST_O); */ printf(" \\\n\t"); } printf(" %s%s", DIR(), ATOKENBUFFER_O); } if ( !user_lexer ) { if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX); else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX); } if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX); for (i=0;i0) printf(" \\\n\tSTreeParser.o"); if (num_cfiles>0) { printf(" \\\n\t"); pfiles(cfiles,num_cfiles,"o"); } printf("\n\n"); printf("ANTLR_SPAWN = "); if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT); else pfiles(files, n, "c"); if ( gen_CPP ) { printf(" "); pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT); printf(" \\\n\t\t"); pclasses(classes, num_classes, "h"); if ( strcmp(hdr,"stdpccts.h")!=0 ) { printf(" \\\n\t\t"); printf("$(HDR_FILE) stdpccts.h"); } } if ( user_lexer ) { if ( !user_token_types ) printf(" $(TOKENS)"); } else { printf(" $(DLG_FILE)"); if ( !user_token_types ) printf(" $(TOKENS)"); } if ( !gen_CPP ) printf(" $(ERR).c"); printf("\n"); if ( !user_lexer ) { if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX); else printf("DLG_SPAWN = %s$(SCAN).c", DIR()); if ( gen_CPP ) printf(" $(SCAN).h"); if ( !gen_CPP ) printf(" $(MOD_FILE)"); printf("\n"); } if ( gen_CPP ) { if ( !nondef_comp ) printf("ifdef CXX\nCCC = $(CXX)\nendif\n\nifndef CCC\n"); printf("CCC = %s\n",compilerCCC); if ( !nondef_comp ) printf("endif\n\n"); } else { if ( !nondef_comp ) printf("ifndef CC\n"); printf("CC = %s\n",compilerCC); if ( !nondef_comp ) printf("endif\n\n"); } /* set up dependencies */ printf("\n%s : $(SRC) $(OBJ)\n", project); printf("\t%s %s %s $(CFLAGS) $(OBJ)\n", gen_CPP?"$(CCC)":"$(CC)", RENAME_EXE_FLAG, project); printf("\n"); /* implicit rules */ /* if(gen_CPP) printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n"); printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n", gen_CPP?"$(CCC)":"$(CC)"); */ /* how to compile parser files */ for (i=0; i0) { printf("STreeParser%s : $(SOR_LIB)%sSTreeParser.cpp\n", OBJ_FILE_SUFFIX,DirectorySymbol); printf("\t%s -c $(CFLAGS) %s ", gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG); printf("STreeParser%s ",OBJ_FILE_SUFFIX); printf("$(SOR_LIB)%sSTreeParser.cpp\n\n",DirectorySymbol); } printf("$(ANTLR_SPAWN) : $(GRM)\n"); printf("\t$(ANTLR) $(AFLAGS) $(GRM)\n"); if ( !user_lexer ) { printf("\n"); printf("$(DLG_SPAWN) : $(DLG_FILE)\n"); if ( gen_CPP ) printf("\t$(DLG) $(DFLAGS) $(DLG_FILE)\n"); else printf("\t$(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n"); } /* do the makes for ANTLR/DLG support */ if ( gen_CPP ) { printf("\n"); printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C); printf("\t%s -c $(CFLAGS) %s ", gen_CPP?"$(CCC)":"$(CC)", RENAME_OBJ_FLAG); printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C); printf("\n"); printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C); printf("\t%s -c $(CFLAGS) %s ", gen_CPP?"$(CCC)":"$(CC)", RENAME_OBJ_FLAG); printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C); if ( !user_lexer ) { printf("\n"); printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C); printf("\t%s -c $(CFLAGS) %s ", gen_CPP?"$(CCC)":"$(CC)", RENAME_OBJ_FLAG); printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C); } if ( gen_trees ) { printf("\n"); printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C); printf("\t%s -c $(CFLAGS) %s ", gen_CPP?"$(CCC)":"$(CC)", RENAME_OBJ_FLAG); printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C); printf("\n"); printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C); printf("\t%s -c $(CFLAGS) %s ", gen_CPP?"$(CCC)":"$(CC)", RENAME_OBJ_FLAG); printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C); printf("\n"); /* printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C); printf("\t%s -c $(CFLAGS) %s ", gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG); printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C); */ } } /* clean and scrub targets */ printf("\nclean:\n"); printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); printf("\n"); printf("\nscrub: clean\n"); /* printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); */ /* if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); */ printf("\trm -f $(ANTLR_SPAWN)"); if ( !user_lexer ) printf(" $(DLG_SPAWN)"); for (i=0;i0 ) { char *p = &(*files)[strlen(*files)-1]; if ( !first ) putchar(' '); first=0; while ( p > *files && *p != '.' ) --p; if ( p == *files ) { fprintf(stderr, "genmk: filenames must be file.suffix format: %s\n", *files); exit(-1); } if ( suffix == NULL ) printf("%s", *files); else { *p = '\0'; printf("%s", DIR()); if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX); else printf("%s.%s", *files, suffix); *p = '.'; } files++; --n; } } #ifdef __STDC__ pclasses(char **classes, int n, char *suffix) #else pclasses(classes, n, suffix) char **classes; int n; char *suffix; #endif { int first=1; while ( n>0 ) { if ( !first ) putchar(' '); first=0; if ( suffix == NULL ) printf("%s", *classes); else { printf("%s", DIR()); if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX); else printf("%s.%s", *classes, suffix); } classes++; --n; } } static void #ifdef __STDC__ 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 || strcmp(p->option, *argv) == 0 ) { if ( p->arg ) { (*p->process)( *argv, *(argv+1) ); argv++; argc--; } else (*p->process)( *argv ); break; } p++; } argv++; } } #ifdef __STDC__ void fatal( char *err_) #else void fatal( err_) char *err_; #endif { fprintf(stderr, "genmk: %s\n", err_); exit(1); } #ifdef __STDC__ void warn( char *err_) #else void warn( err_) char *err_; #endif { fprintf(stderr, "genmk: %s\n", err_); } #ifdef __STDC__ char *DIR(void) #else char *DIR() #endif { static char buf[200+1]; if ( strcmp(outdir,TopDirectory)==0 ) return ""; sprintf(buf, "%s%s", outdir, DirectorySymbol); return buf; }