]> pd.if.org Git - pccts/blob - dlg/main.c
auto commit for import
[pccts] / dlg / main.c
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-1995
27  */
28
29 #include <stdio.h>
30 #include "stdpccts.h"
31
32 char    program[] = "dlg";
33 char    version[] = "1.33";
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    *outdir = 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 /* Option List Stuff */
48 void p_comp0()          {comp_level = 0;}
49 void p_comp1()          {comp_level = 1;}
50 void p_comp2()          {comp_level = 2;}
51 void p_stdio()          { file_str[numfiles++] = NULL;}
52 void p_file(s) char *s; { file_str[numfiles++] = s;}
53 void p_cl_name(s,t)
54         char *s, *t;
55         {
56                 if ( gen_cpp ) {
57                         class_name = t;
58                 }
59                 else {
60                         warning("-cl only valid in C++ mode; -cl ignored...",0);
61                 }
62         }
63 void p_mode_file(s,t) char *s,*t;{mode_file=t;}
64 void p_outdir(s,t) char *s,*t;{outdir=t;}
65 void p_ansi()           {gen_ansi = TRUE;}
66 void p_interactive()    {interactive = TRUE;}
67 void p_case_s()         { case_insensitive = FALSE; }
68 void p_case_i()         { case_insensitive = TRUE; }
69 void p_warn_ambig()     { warn_ambig = TRUE; }
70 void p_cpp()            { gen_cpp = TRUE; }
71
72 typedef struct {
73                         char *option;
74                         int  arg;
75                         void (*process)();
76                         char *descr;
77                 } Opt;
78
79 Opt options[] = {
80         { "-CC", 0, p_cpp, "Generate C++ output" },
81         { "-C0", 0, p_comp0, "No compression (default)" },
82         { "-C1", 0, p_comp1, "Compression level 1" },
83         { "-C2", 0, p_comp2, "Compression level 2" },
84         { "-ga", 0, p_ansi, "Generate ansi C"},
85         { "-Wambiguity", 0, p_warn_ambig, "Warn if expressions ambiguous"},
86         { "-m", 1, p_mode_file, "Rename lexical mode output file"},
87         { "-i", 0, p_interactive, "Build interactive scanner"},
88         { "-ci", 0, p_case_i, "Make lexical analyzer case insensitive"},
89         { "-cl", 1, p_cl_name, "Rename lexer class (DLGLexer); only used for -CC"},
90         { "-cs", 0, p_case_s, "Make lexical analyzer case sensitive (default)"},
91         { "-o",  1, p_outdir, OutputDirectoryOption},
92         { "-", 0, p_stdio, "Use standard i/o rather than file"},
93         { "*", 0, p_file, ""}, /* anything else is a file */
94         { NULL, 0, NULL }       
95 };
96
97 int main(argc,argv)
98 int argc;
99 char *argv[];
100 {
101         init();
102         fprintf(stderr, "%s  Version %s   1989-1995\n", &(program[0]),
103                 &(version[0]));
104         if ( argc == 1 ) 
105         {
106                 Opt *p = options;
107                 fprintf(stderr, "%s [options] f1 f2 ... fn\n",argv[0]);
108                 while ( *(p->option) != '*' )
109                 {
110                         fprintf(stderr, "\t%s %s\t%s\n",
111                                                         p->option,
112                                                         (p->arg)?"___":"   ",
113                                                         p->descr);
114                         p++;
115                 }
116         }else{
117                 ProcessArgs(argc-1, &(argv[1]), options);
118                 if (input_stream = read_stream(file_str[0])) {
119                         /* don't overwrite unless input okay */
120                         if ( gen_cpp ) {
121                                 output_stream = write_stream(ClassName(CPP_FILE_SUFFIX));
122                                 if ( file_str[1]!=NULL ) {
123                                         warning("output file implicit in C++ mode; ignored...",0);
124                                 }
125                                 class_stream = write_stream(ClassName(".h"));
126                                 mode_stream = class_stream;
127                         }
128                         else {
129                                 output_stream = write_stream(file_str[1]);
130                                 mode_stream = write_stream(mode_file);
131                         }
132                 }
133                 /* make sure that error reporting routines in grammar
134                    know what the file really is */
135                 /* make sure that reading and writing somewhere */
136                 if (input_stream && output_stream && mode_stream){
137                         ANTLR(grammar(), input_stream);
138                 }
139                 p_class_def();
140         }
141         if ( output_stream!=NULL ) fclose(output_stream);
142         if ( !gen_cpp && mode_stream!=NULL ) fclose(mode_stream);
143         if ( class_stream!=NULL ) fclose(class_stream);
144         exit(PCCTS_EXIT_SUCCESS);
145 }
146
147
148 ProcessArgs(argc, argv, options)
149 int argc;
150 char **argv;
151 Opt *options;
152 {
153         Opt *p;
154         
155         while ( argc-- > 0 )
156         {
157                 p = options;
158                 while ( p->option != NULL )
159                 {
160                         if ( strcmp(p->option, "*") == 0 ||
161                                  strcmp(p->option, *argv) == 0 )
162                         {
163                                 if ( p->arg )
164                                 {
165                                         (*p->process)( *argv, *(argv+1) );
166                                         argv++;
167                                         argc--;
168                                 }
169                                 else
170                                         (*p->process)( *argv );
171                                 break;
172                         }
173                         p++;
174                 }
175                 argv++;
176         }
177 }
178
179 /* initialize all the variables */
180 init()
181 {
182         register int i;
183
184         special_inits();
185
186         used_chars = empty;
187         used_classes = empty;
188         /* make the valid character set */
189         normal_chars = empty;
190         /* NOTE: MIN_CHAR is EOF */
191         /* NOTE: EOF is not quite a valid char, it is special. Skip it*/
192         for (i = 1; i<CHAR_RANGE; ++i){
193                 set_orel(i,&normal_chars);
194         }
195         make_nfa_model_node();
196         clear_hash();
197         /* NOTE: need to set this flag before the lexer starts getting */
198         /* tokens */
199         func_action = FALSE;    
200 }
201
202 /* stuff that needs to be reset when a new automaton is being built */
203 new_automaton_mode()
204 {
205         set_free(used_chars);
206         clear_hash();
207 }