]> gcc.gnu.org Git - gcc.git/blob - gcc/treelang/tree1.c
Added new sample language treelang.
[gcc.git] / gcc / treelang / tree1.c
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"
36 #include "ansidecl.h"
37 #include "flags.h"
38 #include "output.h"
39 #include "toplev.h"
40
41 #include "ggc.h"
42 #include "tree.h"
43 #include "diagnostic.h"
44
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <ctype.h>
48 #include <stdarg.h>
49 #include <string.h>
50 #include <stdio.h>
51
52 #include "treelang.h"
53 #include "treetree.h"
54
55 extern int yyparse (void);
56 /* Linked list of symbols - all must be unique in treelang. */
57
58 struct production *symbol_table = NULL;
59
60 /* Language for usage for messages. */
61
62 const char *const language_string = "TREELANG - sample front end for GCC ";
63
64 /* Local prototypes. */
65
66 void version (void);
67
68 /* GC routine for symbol table. */
69 static void symbol_table_ggc (void *m);
70
71 /* Global variables. */
72
73 extern struct cbl_tree_struct_parse_tree_top* parse_tree_top;
74
75 /*
76 Options.
77 */
78
79 /* Trace the parser. */
80 unsigned int option_parser_trace = 0;
81
82 /* Trace the lexical analysis. */
83
84 unsigned int option_lexer_trace = 0;
85
86 /* Warning levels. */
87
88 /* Local variables. */
89
90 unsigned char *in_fname = NULL; /* Input file name. */
91
92 /* This is 1 if we have output the version string. */
93
94 static int version_done = 0;
95
96 /* Variable nesting level. */
97
98 static unsigned int work_nesting_level = 0;
99
100 /* Process one switch - called by toplev.c. */
101
102 int
103 treelang_decode_option (num_options_left, first_option_left)
104 int num_options_left ATTRIBUTE_UNUSED;
105 char** first_option_left;
106 {
107
108 /*
109 Process options - bear in mind I may get options that are really
110 meant for someone else (eg the main compiler) so I have to be very
111 permissive.
112
113 */
114
115 if (first_option_left[0][0] != '-')
116 return 0;
117
118 switch (first_option_left[0][1])
119 {
120 case '-':
121 if (!strcmp (first_option_left[0],"--help"))
122 {
123 if (!version_done)
124 {
125 fputs (language_string, stdout);
126 fputs (version_string, stdout);
127 fputs ("\n", stdout);
128 version_done = 1;
129 }
130 fprintf (stdout, "Usage: tree1 [switches] -o output input\n");
131 return 1;
132 }
133 case 'v':
134 if (!strcmp (first_option_left[0],"-v"))
135 {
136 if (!version_done)
137 {
138 fputs (language_string, stdout);
139 fputs (version_string, stdout);
140 fputs ("\n", stdout);
141 version_done = 1;
142 }
143 return 1;
144 }
145 case 'y':
146 if (!strcmp (first_option_left[0],"-y"))
147 {
148 option_lexer_trace = 1;
149 option_parser_trace = 1;
150 return 1;
151 }
152 case 'f':
153 if (!strcmp (first_option_left[0],"-fparser-trace"))
154 {
155 option_parser_trace = 1;
156 return 1;
157 }
158 if (!strcmp (first_option_left[0],"-flexer-trace"))
159 {
160 option_lexer_trace = 1;
161 return 1;
162 }
163 return 0;
164
165 case 'w':
166 if (!strcmp (first_option_left[0],"-w"))
167 {
168 /* Tolerate this option but ignore it - we always put out
169 all warnings. */
170 return 1;
171 }
172 return 0;
173
174 case 'W':
175 if (!strcmp (first_option_left[0],"-Wall"))
176 {
177 return 1;
178 }
179 return 0;
180
181 default:
182 return 0;
183 }
184
185 return 0;
186
187 }
188
189 /* Language dependent parser setup. */
190
191 const char*
192 treelang_init (const char* filename)
193 {
194
195 /* Define my garbage collection routines. */
196 ggc_add_root (&symbol_table, 1,
197 /* Unused size. */ sizeof (void*), symbol_table_ggc);
198 /* Note: only storage that has to be kept across functions needs to
199 be protected from GC. */
200 /* Define my garbage collection routines. */
201 ggc_add_root (&symbol_table, 1,
202 /* Unused size. */ sizeof (void*), symbol_table_ggc);
203 /* Note: only storage that has to be kept across functions needs to
204 be protected from GC. */
205
206 /* Set up the declarations needed for this front end. */
207
208 input_filename = "";
209 lineno = 0;
210
211 treelang_init_decl_processing ();
212
213 /* This error will not happen from GCC as it will always create a
214 fake input file. */
215 if (!filename || (filename[0] == ' ') || (!filename[0]))
216 {
217 if (!version_done)
218 {
219 fprintf (stderr, "No input file specified, try --help for help\n");
220 exit (1);
221 }
222
223 in_fname = NULL;
224 return NULL;
225 }
226 yyin = fopen (filename, "r");
227 if (!yyin)
228 {
229 fprintf (stderr, "Unable to open input file %s\n", filename);
230 exit (1);
231 }
232 input_filename = filename;
233 return (char*) (in_fname = (unsigned char*)filename);
234 }
235
236 /* Language dependent wrapup. */
237
238 void
239 treelang_finish (void)
240 {
241 fclose (yyin);
242 }
243
244 /* Parse a file. Debug flag doesn't seem to work. */
245
246 void
247 treelang_parse_file (int debug_flag ATTRIBUTE_UNUSED)
248 {
249 treelang_debug ();
250 yyparse ();
251 }
252
253
254 /* Scan the symbol table* M, marking storage used. */
255
256 static void
257 symbol_table_ggc (void *m)
258 {
259 struct production *pp;
260 pp = * (struct production**)m;
261 /* Actually it is a pointer to a pointer, to allow reallocation and
262 relinking. */
263 mark_production_used (pp);
264 }
265
266 /* Mark a production PP as used so it wont be garbage collected. */
267
268 void
269 mark_production_used (struct production *pp)
270 {
271 int sub_ix;
272 loop:
273 if (!pp)
274 return;
275 ggc_mark (pp);
276
277 if (pp->category == token_category)
278 {
279 mark_token_used ((struct token*)pp);
280 return;
281 }
282 if (pp->category != production_category)
283 abort ();
284 mark_token_used (pp->main_token);
285 for (sub_ix = 0; sub_ix < SUB_COUNT; sub_ix++)
286 mark_production_used (pp->sub[sub_ix]);
287 /* The macro tests for NULL so I don't need to. */
288 ggc_mark_tree (pp->code);
289 pp = pp->next;
290 goto loop;
291 }
292
293 /* Mark a token TT as used so it wont be garbage collected. */
294
295 void
296 mark_token_used (struct token* tt)
297 {
298 if (!tt)
299 return;
300 ggc_mark (tt);
301 if (tt->chars)
302 ggc_mark (tt->chars);
303 }
304
305 /* Allocate SIZE bytes and clear them. */
306
307 void *
308 my_malloc (size_t size)
309 {
310 void *mem;
311 mem = ggc_alloc (size);
312 if (!mem)
313 {
314 fprintf (stderr, "\nOut of memory\n");
315 abort ();
316 }
317 memset (mem, 0, size);
318 return mem;
319 }
320
321 /* Look up a name in PROD->SYMBOL_TABLE_NAME in the symbol table;
322 return the symbol table entry from the symbol table if found there,
323 else 0. */
324
325 struct production*
326 lookup_tree_name (struct production *prod)
327 {
328 struct production *this;
329 struct token* this_tok;
330 struct token* tok;
331 tok = SYMBOL_TABLE_NAME (prod);
332 for (this = symbol_table; this; this = this->next)
333 {
334 this_tok = this->main_token;
335 if (tok->length != this_tok->length)
336 continue;
337 if (memcmp (tok->chars, this_tok->chars, this_tok->length))
338 continue;
339 if (option_parser_trace)
340 fprintf (stderr, "Found symbol %s (%i:%i) as %i \n", tok->chars,
341 tok->lineno, tok->charno, NUMERIC_TYPE (this));
342 return this;
343 }
344 if (option_parser_trace)
345 fprintf (stderr, "Not found symbol %s (%i:%i) as %i \n", tok->chars,
346 tok->lineno, tok->charno, tok->type);
347 return NULL;
348 }
349
350 /* Insert name PROD into the symbol table. Return 1 if duplicate, 0 if OK. */
351
352 int
353 insert_tree_name (struct production *prod)
354 {
355 struct token* tok;
356 tok = SYMBOL_TABLE_NAME (prod);
357 if (lookup_tree_name (prod))
358 {
359 fprintf (stderr, "%s:%i:%i duplicate name %s\n", in_fname, tok->lineno, tok->charno, tok->chars);
360 errorcount++;
361 return 1;
362 }
363 prod->next = symbol_table;
364 NESTING_LEVEL (prod) = work_nesting_level;
365 symbol_table = prod;
366 return 0;
367 }
368
369 /* Create a struct productions of type TYPE, main token MAIN_TOK. */
370
371 struct production *
372 make_production (int type, struct token* main_tok)
373 {
374 struct production *prod;
375 prod = my_malloc (sizeof (struct production));
376 prod->category = production_category;
377 prod->type = type;
378 prod->main_token = main_tok;
379 return prod;
380 }
381
382
This page took 0.052725 seconds and 5 git commands to generate.