OSDN Git Service

Treelang fixes.
[pf3gnuchains/gcc-fork.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, 2003 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 "coretypes.h"
37 #include "tm.h"
38 #include "flags.h"
39 #include "toplev.h"
40
41 #include "ggc.h"
42 #include "tree.h"
43 #include "diagnostic.h"
44
45 #include "treelang.h"
46 #include "treetree.h"
47
48 extern int yyparse (void);
49
50 /* Linked list of symbols - all must be unique in treelang.  */
51
52 static GTY(()) struct prod_token_parm_item *symbol_table = NULL;
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
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 {
185   /* Set up the declarations needed for this front end.  */
186
187   input_filename = "";
188   lineno = 0;
189
190   /* Init decls etc.  */
191
192   treelang_init_decl_processing ();
193
194   /* This error will not happen from GCC as it will always create a
195      fake input file.  */
196   if (!filename || (filename[0] == ' ') || (!filename[0])) 
197     {
198       if (!version_done)
199         {
200           fprintf (stderr, "No input file specified, try --help for help\n");
201           exit (1);
202         }
203
204       in_fname = NULL;
205       return NULL;
206     }
207   yyin = fopen (filename, "r");
208   if (!yyin)
209     {
210       fprintf (stderr, "Unable to open input file %s\n", filename);
211       exit (1);
212     }
213   input_filename = filename;
214   return (char*) (in_fname = (unsigned char*)filename);
215 }
216
217 /* Language dependent wrapup.  */
218
219 void 
220 treelang_finish (void)
221 {
222   fclose (yyin);
223 }
224
225 /* Parse a file.  Debug flag doesn't seem to work. */
226
227 void
228 treelang_parse_file (int debug_flag ATTRIBUTE_UNUSED)
229 {
230   treelang_debug ();
231   yyparse ();
232 }
233
234 /* Allocate SIZE bytes and clear them.  Not to be used for strings
235    which must go in stringpool.  */
236
237 void *
238 my_malloc (size_t size)
239 {
240   void *mem;
241   mem = ggc_alloc (size);
242   if (!mem)
243     {
244       fprintf (stderr, "\nOut of memory\n");
245       abort ();
246     }
247   memset (mem, 0, size);
248   return mem;
249 }
250
251 /* Look up a name in PROD->SYMBOL_TABLE_NAME in the symbol table;
252    return the symbol table entry from the symbol table if found there,
253    else 0.  */
254
255 struct prod_token_parm_item*
256 lookup_tree_name (struct prod_token_parm_item *prod)
257 {
258   struct prod_token_parm_item *this;
259   struct prod_token_parm_item *this_tok;
260   struct prod_token_parm_item *tok;
261
262   sanity_check (prod);
263   
264   tok = SYMBOL_TABLE_NAME (prod);
265   sanity_check (tok);
266   
267   for (this = symbol_table; this; this = this->tp.pro.next)
268     {
269       sanity_check (this);
270       this_tok = this->tp.pro.main_token;
271       sanity_check (this_tok);
272       if (tok->tp.tok.length != this_tok->tp.tok.length) 
273         continue;
274       if (memcmp (tok->tp.tok.chars, this_tok->tp.tok.chars, this_tok->tp.tok.length))
275         continue;
276       if (option_parser_trace)
277         fprintf (stderr, "Found symbol %s (%i:%i) as %i \n", tok->tp.tok.chars, 
278                 tok->tp.tok.lineno, tok->tp.tok.charno, NUMERIC_TYPE (this));
279       return this;
280     }
281   if (option_parser_trace)
282     fprintf (stderr, "Not found symbol %s (%i:%i) as %i \n", tok->tp.tok.chars, 
283             tok->tp.tok.lineno, tok->tp.tok.charno, tok->type);
284   return NULL;
285 }
286
287 /* Insert name PROD into the symbol table.  Return 1 if duplicate, 0 if OK.  */
288
289 int
290 insert_tree_name (struct prod_token_parm_item *prod)
291 {
292   struct prod_token_parm_item *tok;
293   tok = SYMBOL_TABLE_NAME (prod);
294   sanity_check (prod);
295   if (lookup_tree_name (prod))
296     {
297       fprintf (stderr, "%s:%i:%i duplicate name %s\n", in_fname, tok->tp.tok.lineno, 
298                tok->tp.tok.charno, tok->tp.tok.chars);
299       errorcount++;
300       return 1;
301     }
302   prod->tp.pro.next = symbol_table;
303   NESTING_LEVEL (prod) = work_nesting_level;
304   symbol_table = prod;
305   return 0;
306 }
307
308 /* Create a struct productions of type TYPE, main token MAIN_TOK.  */
309
310 struct prod_token_parm_item *
311 make_production (int type, struct prod_token_parm_item *main_tok)
312 {
313   struct prod_token_parm_item *prod;
314   prod = my_malloc (sizeof (struct prod_token_parm_item));
315   prod->category = production_category;
316   prod->type = type;
317   prod->tp.pro.main_token = main_tok;
318   return prod;
319
320
321 /* Abort if ITEM is not a valid structure, based on 'category'.  */
322
323 void
324 sanity_check (struct prod_token_parm_item *item)
325 {
326   switch (item->category)
327     {
328     case   token_category:
329     case production_category:
330     case parameter_category:
331       break;
332       
333     default:
334       abort ();
335     }
336 }  
337
338 /* New garbage collection regime see gty.texi.  */
339 #include "gt-treelang-tree1.h"
340 /*#include "gt-treelang-treelang.h"*/
341 #include "gtype-treelang.h"