]>
Commit | Line | Data |
---|---|---|
093e265a | 1 | /* |
2 | ||
3 | TREELANG Compiler almost main (tree1) | |
4 | Called by GCC's toplev.c | |
5 | ||
6 | Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify it | |
9 | under the terms of the GNU General Public License as published by the | |
10 | Free Software Foundation; either version 2, or (at your option) any | |
11 | later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
20 | Foundation, 59 Temple Place - Suite 330, | |
21 | Boston, MA 02111-1307, USA. | |
22 | ||
23 | In other words, you are welcome to use, share and improve this program. | |
24 | You are forbidden to forbid anyone else to use, share and improve | |
25 | what you give them. Help stamp out software-hoarding! | |
26 | ||
27 | --------------------------------------------------------------------------- | |
28 | ||
29 | Written by Tim Josling 1999, 2000, 2001, based in part on other | |
30 | parts of the GCC compiler. | |
31 | ||
32 | */ | |
33 | ||
34 | #include "config.h" | |
35 | #include "system.h" | |
805e22b2 | 36 | #include "coretypes.h" |
37 | #include "tm.h" | |
093e265a | 38 | #include "flags.h" |
093e265a | 39 | #include "toplev.h" |
40 | ||
41 | #include "ggc.h" | |
42 | #include "tree.h" | |
43 | #include "diagnostic.h" | |
44 | ||
093e265a | 45 | #include "treelang.h" |
46 | #include "treetree.h" | |
47 | ||
48 | extern int yyparse (void); | |
805e22b2 | 49 | |
093e265a | 50 | /* Linked list of symbols - all must be unique in treelang. */ |
51 | ||
4d26f199 | 52 | static GTY(()) struct prod_token_parm_item *symbol_table = NULL; |
093e265a | 53 | |
54 | /* Language for usage for messages. */ | |
55 | ||
56 | const char *const language_string = "TREELANG - sample front end for GCC "; | |
57 | ||
58 | /* Local prototypes. */ | |
59 | ||
60 | void version (void); | |
61 | ||
093e265a | 62 | /* Global variables. */ |
63 | ||
64 | extern struct cbl_tree_struct_parse_tree_top* parse_tree_top; | |
65 | ||
66 | /* | |
67 | Options. | |
68 | */ | |
69 | ||
70 | /* Trace the parser. */ | |
71 | unsigned int option_parser_trace = 0; | |
72 | ||
73 | /* Trace the lexical analysis. */ | |
74 | ||
75 | unsigned int option_lexer_trace = 0; | |
76 | ||
77 | /* Warning levels. */ | |
78 | ||
79 | /* Local variables. */ | |
80 | ||
81 | unsigned char *in_fname = NULL; /* Input file name. */ | |
82 | ||
83 | /* This is 1 if we have output the version string. */ | |
84 | ||
85 | static int version_done = 0; | |
86 | ||
87 | /* Variable nesting level. */ | |
88 | ||
89 | static unsigned int work_nesting_level = 0; | |
90 | ||
91 | /* Process one switch - called by toplev.c. */ | |
92 | ||
93 | int | |
94 | treelang_decode_option (num_options_left, first_option_left) | |
95 | int num_options_left ATTRIBUTE_UNUSED; | |
96 | char** first_option_left; | |
97 | { | |
98 | ||
99 | /* | |
100 | Process options - bear in mind I may get options that are really | |
101 | meant for someone else (eg the main compiler) so I have to be very | |
102 | permissive. | |
103 | ||
104 | */ | |
105 | ||
106 | if (first_option_left[0][0] != '-') | |
107 | return 0; | |
108 | ||
109 | switch (first_option_left[0][1]) | |
110 | { | |
111 | case '-': | |
112 | if (!strcmp (first_option_left[0],"--help")) | |
113 | { | |
114 | if (!version_done) | |
115 | { | |
116 | fputs (language_string, stdout); | |
117 | fputs (version_string, stdout); | |
118 | fputs ("\n", stdout); | |
119 | version_done = 1; | |
120 | } | |
121 | fprintf (stdout, "Usage: tree1 [switches] -o output input\n"); | |
122 | return 1; | |
123 | } | |
124 | case 'v': | |
125 | if (!strcmp (first_option_left[0],"-v")) | |
126 | { | |
127 | if (!version_done) | |
128 | { | |
129 | fputs (language_string, stdout); | |
130 | fputs (version_string, stdout); | |
131 | fputs ("\n", stdout); | |
132 | version_done = 1; | |
133 | } | |
134 | return 1; | |
135 | } | |
136 | case 'y': | |
137 | if (!strcmp (first_option_left[0],"-y")) | |
138 | { | |
139 | option_lexer_trace = 1; | |
140 | option_parser_trace = 1; | |
141 | return 1; | |
142 | } | |
143 | case 'f': | |
144 | if (!strcmp (first_option_left[0],"-fparser-trace")) | |
145 | { | |
146 | option_parser_trace = 1; | |
147 | return 1; | |
148 | } | |
149 | if (!strcmp (first_option_left[0],"-flexer-trace")) | |
150 | { | |
151 | option_lexer_trace = 1; | |
152 | return 1; | |
153 | } | |
154 | return 0; | |
155 | ||
156 | case 'w': | |
157 | if (!strcmp (first_option_left[0],"-w")) | |
158 | { | |
159 | /* Tolerate this option but ignore it - we always put out | |
160 | all warnings. */ | |
161 | return 1; | |
162 | } | |
163 | return 0; | |
164 | ||
165 | case 'W': | |
166 | if (!strcmp (first_option_left[0],"-Wall")) | |
167 | { | |
168 | return 1; | |
169 | } | |
170 | return 0; | |
171 | ||
172 | default: | |
173 | return 0; | |
174 | } | |
175 | ||
176 | return 0; | |
177 | ||
178 | } | |
179 | ||
180 | /* Language dependent parser setup. */ | |
181 | ||
182 | const char* | |
183 | treelang_init (const char* filename) | |
184 | { | |
093e265a | 185 | /* Set up the declarations needed for this front end. */ |
186 | ||
187 | input_filename = ""; | |
188 | lineno = 0; | |
189 | ||
190 | treelang_init_decl_processing (); | |
191 | ||
192 | /* This error will not happen from GCC as it will always create a | |
193 | fake input file. */ | |
194 | if (!filename || (filename[0] == ' ') || (!filename[0])) | |
195 | { | |
196 | if (!version_done) | |
197 | { | |
198 | fprintf (stderr, "No input file specified, try --help for help\n"); | |
199 | exit (1); | |
200 | } | |
201 | ||
202 | in_fname = NULL; | |
203 | return NULL; | |
204 | } | |
205 | yyin = fopen (filename, "r"); | |
206 | if (!yyin) | |
207 | { | |
208 | fprintf (stderr, "Unable to open input file %s\n", filename); | |
209 | exit (1); | |
210 | } | |
211 | input_filename = filename; | |
212 | return (char*) (in_fname = (unsigned char*)filename); | |
213 | } | |
214 | ||
215 | /* Language dependent wrapup. */ | |
216 | ||
217 | void | |
218 | treelang_finish (void) | |
219 | { | |
220 | fclose (yyin); | |
221 | } | |
222 | ||
223 | /* Parse a file. Debug flag doesn't seem to work. */ | |
224 | ||
225 | void | |
226 | treelang_parse_file (int debug_flag ATTRIBUTE_UNUSED) | |
227 | { | |
228 | treelang_debug (); | |
229 | yyparse (); | |
230 | } | |
231 | ||
093e265a | 232 | /* Allocate SIZE bytes and clear them. */ |
233 | ||
234 | void * | |
235 | my_malloc (size_t size) | |
236 | { | |
237 | void *mem; | |
238 | mem = ggc_alloc (size); | |
239 | if (!mem) | |
240 | { | |
241 | fprintf (stderr, "\nOut of memory\n"); | |
242 | abort (); | |
243 | } | |
244 | memset (mem, 0, size); | |
245 | return mem; | |
246 | } | |
247 | ||
248 | /* Look up a name in PROD->SYMBOL_TABLE_NAME in the symbol table; | |
249 | return the symbol table entry from the symbol table if found there, | |
250 | else 0. */ | |
251 | ||
4d26f199 | 252 | struct prod_token_parm_item* |
253 | lookup_tree_name (struct prod_token_parm_item *prod) | |
093e265a | 254 | { |
4d26f199 | 255 | struct prod_token_parm_item *this; |
256 | struct prod_token_parm_item *this_tok; | |
257 | struct prod_token_parm_item *tok; | |
093e265a | 258 | tok = SYMBOL_TABLE_NAME (prod); |
4d26f199 | 259 | for (this = symbol_table; this; this = this->tp.pro.next) |
093e265a | 260 | { |
4d26f199 | 261 | this_tok = this->tp.pro.main_token; |
262 | if (tok->tp.tok.length != this_tok->tp.tok.length) | |
093e265a | 263 | continue; |
4d26f199 | 264 | if (memcmp (tok->tp.tok.chars, this_tok->tp.tok.chars, this_tok->tp.tok.length)) |
093e265a | 265 | continue; |
266 | if (option_parser_trace) | |
4d26f199 | 267 | fprintf (stderr, "Found symbol %s (%i:%i) as %i \n", tok->tp.tok.chars, |
268 | tok->tp.tok.lineno, tok->tp.tok.charno, NUMERIC_TYPE (this)); | |
093e265a | 269 | return this; |
270 | } | |
271 | if (option_parser_trace) | |
4d26f199 | 272 | fprintf (stderr, "Not found symbol %s (%i:%i) as %i \n", tok->tp.tok.chars, |
273 | tok->tp.tok.lineno, tok->tp.tok.charno, tok->type); | |
093e265a | 274 | return NULL; |
275 | } | |
276 | ||
277 | /* Insert name PROD into the symbol table. Return 1 if duplicate, 0 if OK. */ | |
278 | ||
279 | int | |
4d26f199 | 280 | insert_tree_name (struct prod_token_parm_item *prod) |
093e265a | 281 | { |
4d26f199 | 282 | struct prod_token_parm_item *tok; |
093e265a | 283 | tok = SYMBOL_TABLE_NAME (prod); |
284 | if (lookup_tree_name (prod)) | |
285 | { | |
4d26f199 | 286 | fprintf (stderr, "%s:%i:%i duplicate name %s\n", in_fname, tok->tp.tok.lineno, |
287 | tok->tp.tok.charno, tok->tp.tok.chars); | |
093e265a | 288 | errorcount++; |
289 | return 1; | |
290 | } | |
4d26f199 | 291 | prod->tp.pro.next = symbol_table; |
093e265a | 292 | NESTING_LEVEL (prod) = work_nesting_level; |
293 | symbol_table = prod; | |
294 | return 0; | |
295 | } | |
296 | ||
297 | /* Create a struct productions of type TYPE, main token MAIN_TOK. */ | |
298 | ||
4d26f199 | 299 | struct prod_token_parm_item * |
300 | make_production (int type, struct prod_token_parm_item *main_tok) | |
093e265a | 301 | { |
4d26f199 | 302 | struct prod_token_parm_item *prod; |
303 | prod = my_malloc (sizeof (struct prod_token_parm_item)); | |
093e265a | 304 | prod->category = production_category; |
305 | prod->type = type; | |
4d26f199 | 306 | prod->tp.pro.main_token = main_tok; |
093e265a | 307 | return prod; |
308 | } | |
309 | ||
310 | ||
4d26f199 | 311 | /* New garbage collection regime see gty.texi. */ |
312 | #include "gt-treelang-tree1.h" | |
313 | /*#include "gt-treelang-treelang.h"*/ | |
314 | #include "gtype-treelang.h" |