xref: /openbsd/gnu/usr.bin/gcc/gcc/treelang/tree1.c (revision c87b03e5)
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 "toplev.h"
39 
40 #include "ggc.h"
41 #include "tree.h"
42 #include "diagnostic.h"
43 
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <ctype.h>
47 #include <stdarg.h>
48 #include <string.h>
49 #include <stdio.h>
50 
51 #include "treelang.h"
52 #include "treetree.h"
53 
54 extern int yyparse (void);
55 /* Linked list of symbols - all must be unique in treelang.  */
56 
57 static GTY(()) struct prod_token_parm_item *symbol_table = NULL;
58 
59 /* Language for usage for messages.  */
60 
61 const char *const language_string = "TREELANG - sample front end for GCC ";
62 
63 /* Local prototypes.  */
64 
65 void version (void);
66 
67 /* Global variables.  */
68 
69 extern struct cbl_tree_struct_parse_tree_top* parse_tree_top;
70 
71 /*
72    Options.
73 */
74 
75 /* Trace the parser.  */
76 unsigned int option_parser_trace = 0;
77 
78 /* Trace the lexical analysis.  */
79 
80 unsigned int option_lexer_trace = 0;
81 
82 /* Warning levels.  */
83 
84 /* Local variables.  */
85 
86 unsigned char *in_fname = NULL;	/* Input file name.  */
87 
88 /* This is 1 if we have output the version string.  */
89 
90 static int version_done = 0;
91 
92 /* Variable nesting level.  */
93 
94 static unsigned int work_nesting_level = 0;
95 
96 /* Process one switch - called by toplev.c.  */
97 
98 int
treelang_decode_option(num_options_left,first_option_left)99 treelang_decode_option (num_options_left, first_option_left)
100      int num_options_left ATTRIBUTE_UNUSED;
101      char** first_option_left;
102 {
103 
104   /*
105     Process options - bear in mind I may get options that are really
106     meant for someone else (eg the main compiler) so I have to be very
107     permissive.
108 
109   */
110 
111   if (first_option_left[0][0] != '-')
112     return 0;
113 
114   switch (first_option_left[0][1])
115     {
116     case '-':
117       if (!strcmp (first_option_left[0],"--help"))
118         {
119           if (!version_done)
120             {
121               fputs (language_string, stdout);
122               fputs (version_string, stdout);
123               fputs ("\n", stdout);
124               version_done = 1;
125             }
126           fprintf (stdout, "Usage: tree1 [switches] -o output input\n");
127           return 1;
128         }
129     case 'v':
130       if (!strcmp (first_option_left[0],"-v"))
131         {
132           if (!version_done)
133             {
134               fputs (language_string, stdout);
135               fputs (version_string, stdout);
136               fputs ("\n", stdout);
137               version_done = 1;
138             }
139           return 1;
140         }
141     case 'y':
142       if (!strcmp (first_option_left[0],"-y"))
143         {
144           option_lexer_trace = 1;
145           option_parser_trace = 1;
146           return 1;
147         }
148     case 'f':
149       if (!strcmp (first_option_left[0],"-fparser-trace"))
150         {
151           option_parser_trace = 1;
152           return 1;
153         }
154       if (!strcmp (first_option_left[0],"-flexer-trace"))
155         {
156           option_lexer_trace = 1;
157           return 1;
158         }
159       return 0;
160 
161     case 'w':
162       if (!strcmp (first_option_left[0],"-w"))
163         {
164           /* Tolerate this option but ignore it - we always put out
165              all warnings.  */
166           return 1;
167         }
168       return 0;
169 
170     case 'W':
171       if (!strcmp (first_option_left[0],"-Wall"))
172         {
173           return 1;
174         }
175       return 0;
176 
177     default:
178       return 0;
179     }
180 
181   return 0;
182 
183 }
184 
185 /* Language dependent parser setup.  */
186 
187 const char*
treelang_init(const char * filename)188 treelang_init (const char* filename)
189 {
190   /* Set up the declarations needed for this front end.  */
191 
192   input_filename = "";
193   lineno = 0;
194 
195   treelang_init_decl_processing ();
196 
197   /* This error will not happen from GCC as it will always create a
198      fake input file.  */
199   if (!filename || (filename[0] == ' ') || (!filename[0]))
200     {
201       if (!version_done)
202         {
203           fprintf (stderr, "No input file specified, try --help for help\n");
204           exit (1);
205         }
206 
207       in_fname = NULL;
208       return NULL;
209     }
210   yyin = fopen (filename, "r");
211   if (!yyin)
212     {
213       fprintf (stderr, "Unable to open input file %s\n", filename);
214       exit (1);
215     }
216   input_filename = filename;
217   return (char*) (in_fname = (unsigned char*)filename);
218 }
219 
220 /* Language dependent wrapup.  */
221 
222 void
treelang_finish(void)223 treelang_finish (void)
224 {
225   fclose (yyin);
226 }
227 
228 /* Parse a file.  Debug flag doesn't seem to work. */
229 
230 void
treelang_parse_file(int debug_flag ATTRIBUTE_UNUSED)231 treelang_parse_file (int debug_flag ATTRIBUTE_UNUSED)
232 {
233   treelang_debug ();
234   yyparse ();
235 }
236 
237 /* Allocate SIZE bytes and clear them.  */
238 
239 void *
my_malloc(size_t size)240 my_malloc (size_t size)
241 {
242   void *mem;
243   mem = ggc_alloc (size);
244   if (!mem)
245     {
246       fprintf (stderr, "\nOut of memory\n");
247       abort ();
248     }
249   memset (mem, 0, size);
250   return mem;
251 }
252 
253 /* Look up a name in PROD->SYMBOL_TABLE_NAME in the symbol table;
254    return the symbol table entry from the symbol table if found there,
255    else 0.  */
256 
257 struct prod_token_parm_item*
lookup_tree_name(struct prod_token_parm_item * prod)258 lookup_tree_name (struct prod_token_parm_item *prod)
259 {
260   struct prod_token_parm_item *this;
261   struct prod_token_parm_item *this_tok;
262   struct prod_token_parm_item *tok;
263   tok = SYMBOL_TABLE_NAME (prod);
264   for (this = symbol_table; this; this = this->tp.pro.next)
265     {
266       this_tok = this->tp.pro.main_token;
267       if (tok->tp.tok.length != this_tok->tp.tok.length)
268         continue;
269       if (memcmp (tok->tp.tok.chars, this_tok->tp.tok.chars, this_tok->tp.tok.length))
270         continue;
271       if (option_parser_trace)
272         fprintf (stderr, "Found symbol %s (%i:%i) as %i \n", tok->tp.tok.chars,
273                 tok->tp.tok.lineno, tok->tp.tok.charno, NUMERIC_TYPE (this));
274       return this;
275     }
276   if (option_parser_trace)
277     fprintf (stderr, "Not found symbol %s (%i:%i) as %i \n", tok->tp.tok.chars,
278             tok->tp.tok.lineno, tok->tp.tok.charno, tok->type);
279   return NULL;
280 }
281 
282 /* Insert name PROD into the symbol table.  Return 1 if duplicate, 0 if OK.  */
283 
284 int
insert_tree_name(struct prod_token_parm_item * prod)285 insert_tree_name (struct prod_token_parm_item *prod)
286 {
287   struct prod_token_parm_item *tok;
288   tok = SYMBOL_TABLE_NAME (prod);
289   if (lookup_tree_name (prod))
290     {
291       fprintf (stderr, "%s:%i:%i duplicate name %s\n", in_fname, tok->tp.tok.lineno,
292                tok->tp.tok.charno, tok->tp.tok.chars);
293       errorcount++;
294       return 1;
295     }
296   prod->tp.pro.next = symbol_table;
297   NESTING_LEVEL (prod) = work_nesting_level;
298   symbol_table = prod;
299   return 0;
300 }
301 
302 /* Create a struct productions of type TYPE, main token MAIN_TOK.  */
303 
304 struct prod_token_parm_item *
make_production(int type,struct prod_token_parm_item * main_tok)305 make_production (int type, struct prod_token_parm_item *main_tok)
306 {
307   struct prod_token_parm_item *prod;
308   prod = my_malloc (sizeof (struct prod_token_parm_item));
309   prod->category = production_category;
310   prod->type = type;
311   prod->tp.pro.main_token = main_tok;
312   return prod;
313 }
314 
315 
316 /* New garbage collection regime see gty.texi.  */
317 #include "gt-treelang-tree1.h"
318 /*#include "gt-treelang-treelang.h"*/
319 #include "gtype-treelang.h"
320