Home | History | Annotate | Download | only in dlg
      1 /* Main function for dlg version
      2  *
      3  * SOFTWARE RIGHTS
      4  *
      5  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
      6  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
      7  * company may do whatever they wish with source code distributed with
      8  * PCCTS or the code generated by PCCTS, including the incorporation of
      9  * PCCTS, or its output, into commerical software.
     10  *
     11  * We encourage users to develop software with PCCTS.  However, we do ask
     12  * that credit is given to us for developing PCCTS.  By "credit",
     13  * we mean that if you incorporate our source code into one of your
     14  * programs (commercial product, research project, or otherwise) that you
     15  * acknowledge this fact somewhere in the documentation, research report,
     16  * etc...  If you like PCCTS and have developed a nice tool with the
     17  * output, please mention that you developed it using PCCTS.  In
     18  * addition, we ask that this header remain intact in our source code.
     19  * As long as these guidelines are kept, we expect to continue enhancing
     20  * this system and expect to make other tools available as they are
     21  * completed.
     22  *
     23  * DLG 1.33
     24  * Will Cohen
     25  * With mods by Terence Parr; AHPCRC, University of Minnesota
     26  * 1989-2001
     27  */
     28 
     29 #include <stdio.h>
     30 #include "stdpccts.h"
     31 
     32 char	program[] = "dlg";
     33 char	version[] = "1.33MR33";					/* MRXXX */
     34 int	numfiles = 0;
     35 char	*file_str[2] = {NULL, NULL};
     36 char	*mode_file = "mode.h";
     37 char	*class_name = DEFAULT_CLASSNAME;
     38 char	*OutputDirectory = TopDirectory;
     39 
     40 /* Option variables */
     41 int comp_level = 0;
     42 int interactive = FALSE;
     43 int case_insensitive = FALSE;
     44 int warn_ambig = FALSE;
     45 int gen_cpp = FALSE;
     46 
     47 #ifdef __USE_PROTOS
     48 static int ci_strequ(char *a,char *b)
     49 #else
     50 static int ci_strequ(a,b)
     51   char  *a;
     52   char  *b;
     53 #endif
     54 {
     55   for ( ;*a != 0 && *b != 0; a++, b++) {
     56     if (toupper(*a) != toupper(*b)) return 0;
     57   }
     58   return (*a == *b);
     59 }
     60 
     61 /* Option List Stuff */
     62 #ifdef __USE_PROTOS
     63 void p_comp0(void)		{comp_level = 0;}
     64 void p_comp1(void)		{comp_level = 1;}
     65 void p_comp2(void)		{comp_level = 2;}
     66 void p_stdio(void)		{ file_str[numfiles++] = NULL;}
     67 void p_file(char *s) 	{ file_str[numfiles++] = s;}
     68 void p_cl_name(char *s, char *t)
     69 	{
     70 		if ( gen_cpp ) {
     71 			class_name = t;
     72 		}
     73 		else {
     74 			warning("-cl only valid in C++ mode; -cl ignored...",0);
     75 		}
     76 	}
     77 void p_mode_file(char *s, char *t){mode_file=t;}
     78 void p_outdir(char *s,char *t) {OutputDirectory=t;}
     79 void p_ansi(void)		{gen_ansi = TRUE;}
     80 void p_interactive(void)	{interactive = TRUE;}
     81 void p_case_s(void)		{ case_insensitive = FALSE; }
     82 void p_case_i(void)		{ case_insensitive = TRUE; }
     83 void p_warn_ambig(void)	{ warn_ambig = TRUE; }
     84 void p_cpp(void)		{ gen_cpp = TRUE; }
     85 #else
     86 void p_comp0()		{comp_level = 0;}
     87 void p_comp1()		{comp_level = 1;}
     88 void p_comp2()		{comp_level = 2;}
     89 void p_stdio()		{ file_str[numfiles++] = NULL;}
     90 void p_file(s) char *s;	{ file_str[numfiles++] = s;}
     91 void p_cl_name(s,t)
     92 	char *s, *t;
     93 	{
     94 		if ( gen_cpp ) {
     95 			class_name = t;
     96 		}
     97 		else {
     98 			warning("-cl only valid in C++ mode; -cl ignored...",0);
     99 		}
    100 	}
    101 void p_mode_file(s,t) char *s,*t;{mode_file=t;}
    102 void p_outdir(s,t) char *s,*t;{OutputDirectory=t;}
    103 void p_ansi()		{gen_ansi = TRUE;}
    104 void p_interactive()	{interactive = TRUE;}
    105 void p_case_s()		{ case_insensitive = FALSE; }
    106 void p_case_i()		{ case_insensitive = TRUE; }
    107 void p_warn_ambig()	{ warn_ambig = TRUE; }
    108 void p_cpp()		{ gen_cpp = TRUE; }
    109 #endif
    110 
    111 #ifdef __cplusplus
    112 typedef void (*WildFunc)(...);
    113 #else
    114 typedef void (*WildFunc)();
    115 #endif
    116 
    117 typedef struct {
    118 			char *option;
    119 			int  arg;
    120 			WildFunc process;
    121 			char *descr;
    122 		} Opt;
    123 
    124 Opt options[] = {
    125 	{ "-CC", 0, (WildFunc)p_cpp, "Generate C++ output" },
    126 	{ "-C0", 0, (WildFunc)p_comp0, "No compression (default)" },
    127 	{ "-C1", 0, (WildFunc)p_comp1, "Compression level 1" },
    128 	{ "-C2", 0, (WildFunc)p_comp2, "Compression level 2" },
    129 	{ "-ga", 0, (WildFunc)p_ansi, "Generate ansi C"},
    130 	{ "-Wambiguity", 0, (WildFunc)p_warn_ambig, "Warn if expressions ambiguous"},
    131 	{ "-m", 1, (WildFunc)p_mode_file, "Rename lexical mode output file"},
    132 	{ "-i", 0, (WildFunc)p_interactive, "Build interactive scanner (not valid for C++ mode)"},
    133 	{ "-ci", 0, (WildFunc)p_case_i, "Make lexical analyzer case insensitive"},
    134 	{ "-cl", 1, (WildFunc)p_cl_name, "Rename lexer class (DLGLexer); only used for -CC"},
    135 	{ "-cs", 0, (WildFunc)p_case_s, "Make lexical analyzer case sensitive (default)"},
    136 	{ "-o",  1, (WildFunc)p_outdir, OutputDirectoryOption},
    137 	{ "-", 0, (WildFunc)p_stdio, "Use standard i/o rather than file"},
    138 	{ "*", 0, (WildFunc)p_file, ""}, /* anything else is a file */
    139 	{ NULL, 0, NULL }
    140  };
    141 
    142 #ifdef __USE_PROTOS
    143 void ProcessArgs(int argc, char **argv, Opt *options)
    144 #else
    145 void ProcessArgs(argc, argv, options)
    146 int argc;
    147 char **argv;
    148 Opt *options;
    149 #endif
    150 {
    151 	Opt *p;
    152 
    153 	while ( argc-- > 0 )
    154 	{
    155 		p = options;
    156 		while ( p->option != NULL )
    157 		{
    158 			if ( strcmp(p->option, "*") == 0 ||
    159 				 ci_strequ(p->option,*argv) )
    160 			{
    161 				if ( p->arg )
    162 				{
    163 					(*p->process)( *argv, *(argv+1) );
    164 					argv++;
    165 					argc--;
    166 				}
    167 				else
    168 					(*p->process)( *argv );
    169 				break;
    170 			}
    171 			p++;
    172 		}
    173 		argv++;
    174 	}
    175 }
    176 
    177 #ifdef __USE_PROTOS
    178 int main(int argc, char *argv[])
    179 #else
    180 int main(argc, argv)
    181 int argc;
    182 char *argv[];
    183 #endif
    184 {
    185 	init();
    186 	fprintf(stderr, "%s  Version %s   1989-2001\n", &(program[0]),
    187 		&(version[0]));
    188 	if ( argc == 1 )
    189 	{
    190 		Opt *p = options;
    191 		fprintf(stderr, "%s [options] f1 f2 ... fn\n",argv[0]);
    192 		while ( *(p->option) != '*' )
    193 		{
    194 			fprintf(stderr, "\t%s %s\t%s\n",
    195 							p->option,
    196 							(p->arg)?"___":"   ",
    197 							p->descr);
    198 			p++;
    199 		}
    200 	}else{
    201 		ProcessArgs(argc-1, &(argv[1]), options);
    202 		if (interactive && gen_cpp) {
    203 			fprintf(stderr,"\n");
    204 /***  MR21a This statement is wrong ! ***/
    205 #if 0
    206 ***			fprintf(stderr,"Interactive lexer option (\"-i\") has no effect when in C++ mode\n");
    207 ***			fprintf(stderr,"because of extra buffering provided by ANTLRTokenBuffer class.\n");
    208 ***			fprintf(stderr,"\n");
    209 #endif
    210 		}
    211 		input_stream = read_stream(file_str[0]);
    212 		if (input_stream) {
    213 			/* don't overwrite unless input okay */
    214 			if ( gen_cpp ) {
    215 				output_stream = write_stream(ClassName(CPP_FILE_SUFFIX));
    216 				if ( file_str[1]!=NULL ) {
    217 					warning("output file implicit in C++ mode; ignored...",0);
    218 				}
    219 				class_stream = write_stream(ClassName(".h"));
    220 				mode_stream = class_stream;
    221 			}
    222 			else {
    223 				output_stream = write_stream(file_str[1]);
    224 				mode_stream = write_stream(mode_file);
    225 			}
    226 		}
    227 		/* make sure that error reporting routines in grammar
    228 		   know what the file really is */
    229 		/* make sure that reading and writing somewhere */
    230 		if (input_stream && output_stream && mode_stream){
    231 			ANTLR(grammar(), input_stream);
    232 		}
    233 		p_class_def2();			/* MR1 */
    234 	}
    235 	if ( output_stream!=NULL ) fclose(output_stream);
    236 	if ( !gen_cpp && mode_stream!=NULL ) fclose(mode_stream);
    237 	if ( class_stream!=NULL ) fclose(class_stream);
    238 	exit(PCCTS_EXIT_SUCCESS);
    239 	return 0;		/* get rid of warning message MR1 */
    240 }
    241 
    242 /* initialize all the variables */
    243 void
    244 #ifdef __USE_PROTOS
    245 init(void)
    246 #else
    247 init()
    248 #endif
    249 {
    250 	register int i;
    251 
    252 #ifdef SPECIAL_INITS
    253 	special_inits();					/* MR1 */
    254 #endif
    255 	used_chars = empty;
    256 	used_classes = empty;
    257 	/* make the valid character set */
    258 	normal_chars = empty;
    259 	/* NOTE: MIN_CHAR is EOF */
    260 	/* NOTE: EOF is not quite a valid char, it is special. Skip it*/
    261 	for (i = 1; i<CHAR_RANGE; ++i){
    262 		set_orel(i,&normal_chars);
    263 	}
    264 	make_nfa_model_node();
    265 	clear_hash();
    266 	/* NOTE: need to set this flag before the lexer starts getting */
    267 	/* tokens */
    268    	func_action = FALSE;
    269 }
    270 
    271 /* stuff that needs to be reset when a new automaton is being built */
    272 void
    273 #ifdef __USE_PROTOS
    274 new_automaton_mode(void)					/* MR1 */
    275 #else
    276 new_automaton_mode()					/* MR1 */
    277 #endif
    278 {
    279 	set_free(used_chars);
    280 	clear_hash();
    281 }
    282