OSDN Git Service

* pretty-print.c: Include tree.h.
[pf3gnuchains/gcc-fork.git] / gcc / treelang / parse.y
1 /* -*- c -*- emacs mode c */
2 /* TREELANG Compiler parser.  
3
4 ---------------------------------------------------------------------
5
6 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
7 Free Software Foundation, Inc.
8
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
23
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them.   Help stamp out software-hoarding!  
27
28 ---------------------------------------------------------------------
29
30 Written by Tim Josling 1999-2001, based in part on other parts of
31 the GCC compiler.  */
32
33 /* Grammar Conflicts
34    *****************
35    There are no conflicts in this grammar.  Please keep it that way.  */
36
37 %{ 
38 #include "config.h"
39 #include "system.h"
40 #include "coretypes.h"
41 #include "tm.h"
42 #include "errors.h"
43 #include "timevar.h"
44
45 #include "treelang.h"
46 #include "treetree.h"
47
48 #define YYDEBUG 1
49 #define YYPRINT(file, type, value) print_token (file, type, value) 
50 #define YYERROR_VERBOSE YES
51
52   /* My yylex routine used to intercept calls to flex generated code, to
53      record lex time.  */
54   int yylex (void);
55   static inline int my_yylex (void);
56
57   /* Call lex, but ensure time is charged to TV_LEX.  */ 
58   static inline int
59     my_yylex (void)
60     {
61       int res;
62       timevar_push (TV_LEX);
63       res = yylex ();
64       timevar_pop (TV_LEX);
65       return res;
66     }
67 #define yylex my_yylex
68
69   extern int option_parser_trace;
70
71   /* Local prototypes.  */
72   static void yyerror (const char *error_message);
73   int yyparse (void);
74   void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED,
75                     YYSTYPE value);
76   static struct prod_token_parm_item *reverse_prod_list
77     (struct prod_token_parm_item *old_first);
78   static void ensure_not_void (unsigned int type,
79                                struct prod_token_parm_item* name);
80   static int check_type_match (int type_num, struct prod_token_parm_item *exp);
81   static int get_common_type (struct prod_token_parm_item *type1,
82                               struct prod_token_parm_item *type2);
83   static struct prod_token_parm_item *make_integer_constant
84     (struct prod_token_parm_item* value);
85   static struct prod_token_parm_item *make_plus_expression
86     (struct prod_token_parm_item* tok, struct prod_token_parm_item* op1,
87      struct prod_token_parm_item* op2, int type_code, int prod_code);
88   static void set_storage (struct prod_token_parm_item *prod);
89
90   /* File global variables.  */
91   static struct prod_token_parm_item *current_function = NULL;
92 %}
93
94 /* Not %raw - seems to have bugs.  */
95 %token_table
96
97 /* Punctuation.  */
98 %token RIGHT_BRACE
99 %token LEFT_BRACE
100 %token RIGHT_SQUARE_BRACKET
101 %token LEFT_SQUARE_BRACKET
102 %token RIGHT_PARENTHESIS
103 %token LEFT_PARENTHESIS
104 %token SEMICOLON
105 %token ASTERISK
106 %token COMMA
107 %right EQUALS
108 %right ASSIGN
109 %left  tl_PLUS
110 %left  tl_MINUS
111
112 /* Literals.  */
113 %token INTEGER
114
115 /* Keywords.  */
116 %token IF
117 %token ELSE
118 %token tl_RETURN
119 %token CHAR
120 %token INT
121 %token UNSIGNED
122 %token VOID
123 %token TYPEDEF
124 %token NAME
125 %token STATIC
126 %token AUTOMATIC
127 %token EXTERNAL_DEFINITION
128 %token EXTERNAL_REFERENCE
129
130 /* Tokens not passed to parser.  */
131 %token WHITESPACE
132 %token COMMENT
133
134 /* Pseudo tokens - productions.  */
135 %token PROD_VARIABLE_NAME
136 %token PROD_TYPE_NAME
137 %token PROD_FUNCTION_NAME
138 %token PROD_INTEGER_CONSTANT
139 %token PROD_PLUS_EXPRESSION
140 %token PROD_MINUS_EXPRESSION
141 %token PROD_ASSIGN_EXPRESSION
142 %token PROD_VARIABLE_REFERENCE_EXPRESSION
143 %token PROD_PARAMETER
144 %token PROD_FUNCTION_INVOCATION
145 %expect 0 
146 %% 
147
148 file:
149 /* Nil.   */ {
150   /* Nothing to do.  */
151 }
152 |declarations {
153   /* Nothing to do.  */
154 }
155 ;
156
157
158 declarations:
159 declaration {
160   /* Nothing to do.  */
161 }
162 | declarations declaration {
163   /* Nothing to do.  */
164 }
165 ;
166
167 declaration:
168 variable_def {
169   /* Nothing to do.  */
170 }
171 |function_prototype {
172   /* Nothing to do.  */
173 }
174 |function {
175   /* Nothing to do.  */
176 }
177 ;
178
179 variable_def:
180 storage typename NAME init_opt SEMICOLON {
181   struct prod_token_parm_item* tok;
182   struct prod_token_parm_item *prod;
183   tok = $3;
184   prod = make_production (PROD_VARIABLE_NAME, tok);
185   SYMBOL_TABLE_NAME (prod) = tok;
186   EXPRESSION_TYPE (prod) = $2;
187   VAR_INIT (prod) = $4;
188   NUMERIC_TYPE (prod) = 
189     NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
190   ensure_not_void (NUMERIC_TYPE (prod), tok);
191   if (insert_tree_name (prod))
192     {
193       YYERROR;
194     }
195   STORAGE_CLASS_TOKEN (prod) = $1;
196   set_storage (prod);
197
198   if (VAR_INIT (prod))
199     {
200       gcc_assert (((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code);
201       if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
202         {
203           error("%HExternal reference variable %q.*s has an initial value.",
204                 &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
205           YYERROR;
206           VAR_INIT (prod) = NULL;
207         }
208
209     }
210
211   prod->tp.pro.code = tree_code_create_variable
212     (STORAGE_CLASS (prod), 
213      ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
214      ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
215      NUMERIC_TYPE (prod),
216      VAR_INIT (prod) ?
217      ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code : NULL,
218      tok->tp.tok.location);
219   gcc_assert (prod->tp.pro.code);
220 }
221 ;
222
223 storage:
224 STATIC
225 |AUTOMATIC
226 |EXTERNAL_DEFINITION
227 |EXTERNAL_REFERENCE
228 ;
229
230 parameter:
231 typename NAME {
232   struct prod_token_parm_item* tok;
233   struct prod_token_parm_item *prod;
234   struct prod_token_parm_item *prod2;
235   tok = $2;
236   prod = make_production (PROD_VARIABLE_NAME, tok);
237   SYMBOL_TABLE_NAME (prod) = $2;
238   EXPRESSION_TYPE (prod) = $1;
239   NUMERIC_TYPE (prod) =
240     NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
241   ensure_not_void (NUMERIC_TYPE (prod), tok);
242   if (insert_tree_name (prod))
243     {
244       YYERROR;
245     }
246   prod2 = make_production (PROD_PARAMETER, tok);
247   VARIABLE (prod2) = prod;
248   $$ = prod2;
249 }
250 ;
251
252 function_prototype:
253 storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLON {
254   struct prod_token_parm_item* tok;
255   struct prod_token_parm_item *prod;
256   struct prod_token_parm_item *type;
257   struct prod_token_parm_item* first_parms;
258   struct prod_token_parm_item* last_parms;
259   struct prod_token_parm_item* this_parms;
260   struct prod_token_parm_item *this_parm;
261   struct prod_token_parm_item *this_parm_var;
262   tok = $3;
263   prod = make_production (PROD_FUNCTION_NAME, $3);
264   SYMBOL_TABLE_NAME (prod) = $3;
265   EXPRESSION_TYPE (prod) = $2;
266   NUMERIC_TYPE (prod) =
267     NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
268   PARAMETERS (prod) = reverse_prod_list ($5); 
269   insert_tree_name (prod);
270   STORAGE_CLASS_TOKEN (prod) = $1;
271   set_storage (prod);
272   switch (STORAGE_CLASS (prod))
273     { 
274     case STATIC_STORAGE:
275     case EXTERNAL_DEFINITION_STORAGE:
276       break;
277       
278     case AUTOMATIC_STORAGE:
279       error ("%HFunction %q.*s cannot be automatic.",
280              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
281       YYERROR;
282       break;
283
284     default:
285       gcc_unreachable ();
286     }
287   type = EXPRESSION_TYPE (prod);
288   /* Create a parameter list in a non-front end specific format.  */
289   for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
290        this_parm;
291        this_parm = this_parm->tp.pro.next)
292     {
293       gcc_assert (this_parm->category == production_category);
294       this_parm_var = VARIABLE (this_parm);
295
296       gcc_assert (this_parm_var);
297       gcc_assert (this_parm_var->category == production_category);
298       gcc_assert (this_parm_var->tp.pro.main_token);
299
300       this_parms = my_malloc (sizeof (struct prod_token_parm_item));
301
302       this_parms->tp.par.variable_name =
303         this_parm_var->tp.pro.main_token->tp.tok.chars;
304       this_parms->category = parameter_category;
305       this_parms->type = NUMERIC_TYPE 
306         (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
307       if (last_parms)
308         {
309           last_parms->tp.par.next = this_parms;
310           last_parms = this_parms;
311         }
312       else
313         {
314           first_parms = this_parms;
315           last_parms = this_parms;
316         }
317       this_parms->tp.par.where_to_put_var_tree = 
318         & (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
319     }
320   FIRST_PARMS (prod) = first_parms;
321
322   prod->tp.pro.code =
323     tree_code_create_function_prototype (tok->tp.tok.chars,
324                                          STORAGE_CLASS (prod),
325                                          NUMERIC_TYPE (type),
326                                          first_parms, tok->tp.tok.location);
327 }
328 ;
329
330 function:
331 NAME LEFT_BRACE {
332   struct prod_token_parm_item *proto;
333   struct prod_token_parm_item search_prod;
334   struct prod_token_parm_item* tok;
335   struct prod_token_parm_item *this_parm;
336   tok = $1;
337   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
338   search_prod.category = token_category;
339   current_function = proto = lookup_tree_name (&search_prod);
340   if (!proto)
341     {
342       error ("%HNo prototype found for %q.*s", &tok->tp.tok.location,
343              tok->tp.tok.length, tok->tp.tok.chars);
344       YYERROR;
345     }
346
347   gcc_assert (proto->tp.pro.code);
348
349   tree_code_create_function_initial (proto->tp.pro.code, tok->tp.tok.location,
350                                      FIRST_PARMS (current_function));
351
352 #ifdef ENABLE_CHECKING
353   /* Check all the parameters have code.  */
354   for (this_parm = PARAMETERS (proto);
355        this_parm;
356        this_parm = this_parm->tp.pro.next)
357     {
358       gcc_assert ((struct prod_token_parm_item*)VARIABLE (this_parm));
359       gcc_assert (((struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
360     }
361 #endif
362 }
363 variable_defs_opt statements_opt RIGHT_BRACE {
364   struct prod_token_parm_item* tok;
365   tok = $1;
366   tree_code_create_function_wrapup (tok->tp.tok.location);
367   current_function = NULL;
368 }
369 ;
370
371 variable_defs_opt:
372 /* Nil.   */ {
373   $$ = 0;
374 }
375 |variable_defs {
376   $$ = $1;
377 }
378 ;
379
380 statements_opt:
381 /* Nil.   */ {
382   $$ = 0;
383 }
384 |statements {
385   $$ = $1;
386 }
387 ;
388
389 variable_defs:
390 variable_def {
391   /* Nothing to do.  */
392 }
393 |variable_defs variable_def {
394   /* Nothing to do.  */
395 }
396 ;
397
398 typename:
399 INT {
400   struct prod_token_parm_item* tok;
401   struct prod_token_parm_item *prod;
402   tok = $1;
403   prod = make_production (PROD_TYPE_NAME, tok);
404   NUMERIC_TYPE (prod) = SIGNED_INT;
405   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
406   $$ = prod;
407 }
408 |UNSIGNED INT {
409   struct prod_token_parm_item* tok;
410   struct prod_token_parm_item *prod;
411   tok = $1;
412   prod = make_production (PROD_TYPE_NAME, tok);
413   NUMERIC_TYPE (prod) = UNSIGNED_INT;
414   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
415   $$ = prod;
416 }
417 |CHAR {
418   struct prod_token_parm_item* tok;
419   struct prod_token_parm_item *prod;
420   tok = $1;
421   prod = make_production (PROD_TYPE_NAME, tok);
422   NUMERIC_TYPE (prod) = SIGNED_CHAR;
423   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
424   $$ = prod;
425 }
426 |UNSIGNED CHAR {
427   struct prod_token_parm_item* tok;
428   struct prod_token_parm_item *prod;
429   tok = $1;
430   prod = make_production (PROD_TYPE_NAME, tok);
431   NUMERIC_TYPE (prod) = UNSIGNED_CHAR;
432   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
433   $$ = prod;
434 }
435 |VOID {
436   struct prod_token_parm_item* tok;
437   struct prod_token_parm_item *prod;
438   tok = $1;
439   prod = make_production (PROD_TYPE_NAME, tok);
440   NUMERIC_TYPE (prod) = VOID_TYPE;
441   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
442   $$ = prod;
443 }
444 ;
445
446 parameters_opt:
447 /* Nothing to do.  */ {
448  $$ = 0;
449 }
450 | parameters {
451  $$ = $1;
452 }
453
454 parameters:
455 parameter {
456   /* Nothing to do.  */
457   $$ = $1;
458 }
459 |parameters COMMA parameter {
460   struct prod_token_parm_item *prod1;
461   prod1 = $3;
462   prod1->tp.pro.next = $1; /* Insert in reverse order.  */
463   $$ = prod1;
464 }
465 ;
466
467 statements:
468 statement {
469   /* Nothing to do.  */
470 }
471 |statements statement {
472   /* Nothing to do.  */
473 }
474 ;
475
476 statement:
477 expression SEMICOLON {
478   struct prod_token_parm_item *exp;
479   exp = $1;
480   tree_code_output_expression_statement (exp->tp.pro.code,
481                                          exp->tp.pro.main_token->tp.tok.location);
482 }
483 |return SEMICOLON {
484   /* Nothing to do.  */
485 }
486 |if_statement {
487   /* Nothing to do.  */
488 }
489 ;
490
491 if_statement:
492 IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
493   struct prod_token_parm_item* tok;
494   struct prod_token_parm_item *exp;
495   tok = $1;
496   exp = $3;
497   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
498   tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
499 }
500 LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
501   /* Just let the statements flow.  */
502 }
503 ELSE {
504   struct prod_token_parm_item* tok;
505   tok = $1;
506   tree_code_if_else (tok->tp.tok.location);
507 }
508 LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
509   struct prod_token_parm_item* tok;
510   tok = $1;
511   tree_code_if_end (tok->tp.tok.location);
512 }
513 ;
514
515
516 return:
517 tl_RETURN expression_opt {
518   struct prod_token_parm_item *type_prod;
519   struct prod_token_parm_item *ret_tok = $1;
520   struct prod_token_parm_item *exp = $2;
521
522   type_prod = EXPRESSION_TYPE (current_function);
523   if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
524     if (exp == NULL)
525       tree_code_generate_return (type_prod->tp.pro.code, NULL);
526     else
527       {
528         warning ("%HRedundant expression in return.",
529                  &ret_tok->tp.tok.location, ret_tok->tp.tok.length,
530                  ret_tok->tp.tok.chars);
531         tree_code_generate_return (type_prod->tp.pro.code, NULL);
532        }
533   else
534     if (exp == NULL)
535         error ("%HExpression missing in return.", &ret_tok->tp.tok.location);
536     else
537       {
538         /* Check same type.  */
539         if (check_type_match (NUMERIC_TYPE (type_prod), exp))
540           {
541             gcc_assert (type_prod->tp.pro.code);
542             gcc_assert (exp->tp.pro.code);
543
544             /* Generate the code. */
545             tree_code_generate_return (type_prod->tp.pro.code,
546                                        exp->tp.pro.code);
547           }
548       }
549 }
550 ;
551
552 expression_opt:
553 /* Nil.   */ {
554   $$ = 0;
555 }
556 |expression {
557   struct prod_token_parm_item *exp;
558   exp = $1;
559   gcc_assert (exp->tp.pro.code);
560   
561   $$ = $1;
562 }
563 ;
564
565 expression:
566 INTEGER {
567   $$ = make_integer_constant ($1);
568 }
569 |variable_ref {
570   $$ = $1;
571 }
572 |expression tl_PLUS expression {
573   struct prod_token_parm_item *tok = $2;
574   struct prod_token_parm_item *op1 = $1;
575   struct prod_token_parm_item *op2 = $3;
576   int type_code = get_common_type (op1, op2);
577   if (!type_code)
578     YYERROR;
579   $$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
580 }
581 |expression tl_MINUS expression %prec tl_PLUS {
582   struct prod_token_parm_item *tok = $2;
583   struct prod_token_parm_item *op1 = $1;
584   struct prod_token_parm_item *op2 = $3;
585   int type_code = get_common_type (op1, op2);
586   if (!type_code)
587     YYERROR;
588   $$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
589 }
590 |expression EQUALS expression {
591   struct prod_token_parm_item *tok = $2;
592   struct prod_token_parm_item *op1 = $1;
593   struct prod_token_parm_item *op2 = $3;
594   $$ = make_plus_expression
595      (tok, op1, op2, SIGNED_INT, EXP_EQUALS);
596 }
597 |variable_ref ASSIGN expression {
598   struct prod_token_parm_item *tok = $2;
599   struct prod_token_parm_item *op1 = $1;
600   struct prod_token_parm_item *op2 = $3;
601   int type_code = NUMERIC_TYPE (op1);
602   if (!type_code)
603     YYERROR;
604   $$ = make_plus_expression
605      (tok, op1, op2, type_code, EXP_ASSIGN);
606 }
607 |function_invocation {
608   $$ = $1;
609 }
610 ;
611
612 function_invocation:
613 NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
614   struct prod_token_parm_item *prod;
615   struct prod_token_parm_item* tok;
616   struct prod_token_parm_item search_prod;
617   struct prod_token_parm_item *proto;
618   struct prod_token_parm_item *exp;
619   struct prod_token_parm_item *exp_proto;
620   struct prod_token_parm_item *var;
621   int exp_proto_count;
622   int exp_count;
623   tree parms;
624   tree type;
625   
626   tok = $1;
627   prod = make_production (PROD_FUNCTION_INVOCATION, tok);
628   SYMBOL_TABLE_NAME (prod) = tok;
629   PARAMETERS (prod) = reverse_prod_list ($3);
630   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
631   search_prod.category = token_category;
632   proto = lookup_tree_name (&search_prod);
633   if (!proto)
634     {
635       error ("%HFunction prototype not found for %q.*%s.",
636              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
637       YYERROR;
638     }
639   EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
640   NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
641   /* Count the expressions and ensure they match the prototype.  */
642   for (exp_proto_count = 0, exp_proto = PARAMETERS (proto); 
643        exp_proto; exp_proto = exp_proto->tp.pro.next)
644     exp_proto_count++;
645
646   for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
647     exp_count++;
648
649   if (exp_count !=  exp_proto_count)
650     {
651       error ("%HExpression count mismatch %q.*s with prototype.",
652              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
653       YYERROR;
654     }
655   parms = tree_code_init_parameters ();
656   for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
657        exp_proto;
658        exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
659     {
660       gcc_assert (exp);
661       gcc_assert (exp_proto);
662       gcc_assert (exp->tp.pro.code);
663
664       var = VARIABLE (exp_proto);
665
666       gcc_assert (var);
667       gcc_assert (var->tp.pro.code);
668
669       parms = tree_code_add_parameter (parms, var->tp.pro.code,
670                                        exp->tp.pro.code);
671     }
672   type = tree_code_get_type (NUMERIC_TYPE (prod));
673   prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
674                                                 proto->tp.pro.code, parms,
675                                                 NULL);
676   $$ = prod;
677 }
678 ;
679
680 expressions_with_commas:
681 expression {
682   struct prod_token_parm_item *exp;
683   exp = $1;
684   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
685   $$ = $1;
686 }
687 |expressions_with_commas COMMA expression {
688   struct prod_token_parm_item *exp;
689   exp = $3;
690   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
691   exp->tp.pro.next = $1; /* Reverse order.  */
692   $$ = exp;
693 }
694 ;
695
696 variable_ref:
697 NAME {
698   struct prod_token_parm_item search_prod;
699   struct prod_token_parm_item *prod;
700   struct prod_token_parm_item *symbol_table_entry;
701   struct prod_token_parm_item* tok;
702   tree type;
703
704   tok = $1;
705   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
706   search_prod.category = token_category;
707   symbol_table_entry = lookup_tree_name (&search_prod);
708   if (!symbol_table_entry)
709     {
710       error ("%HVariable %q.*s not defined.",
711              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
712       YYERROR;
713     }
714
715   prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
716   NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
717   type = tree_code_get_type (NUMERIC_TYPE (prod));
718   if (!NUMERIC_TYPE (prod))
719     YYERROR;
720   OP1 (prod) = $1;
721   
722   prod->tp.pro.code =
723     tree_code_get_expression (EXP_REFERENCE, type, 
724                               symbol_table_entry->tp.pro.code, NULL, NULL);
725   $$ = prod;
726 }
727 ;
728
729 init_opt:
730 /* Nil.   */ {
731   $$ = 0;
732 }
733 |init {
734   /* Nothing to do.  */
735 };
736
737 init:
738 ASSIGN init_element {
739   $$ = $2;
740 }
741 ;
742
743 init_element:
744 INTEGER {
745   $$ = make_integer_constant ($1);
746 }
747 ;
748
749 %%
750
751 /* Print a token VALUE to file FILE.  Ignore TYPE which is the token
752    type. */
753
754 void
755 print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value) 
756 {
757   struct prod_token_parm_item *tok;
758   unsigned int  ix;
759
760   tok  =  value;
761   fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
762   for (ix  =  0; ix < tok->tp.tok.length; ix++)
763     fprintf (file, "%c", tok->tp.tok.chars[ix]);
764
765   fprintf (file, "\"");
766 }
767
768 /* Output a message ERROR_MESSAGE from the parser.  */
769 static void
770 yyerror (const char *error_message)
771 {
772   struct prod_token_parm_item *tok;
773
774   tok = yylval;
775   if (tok)
776     error ("%H%s", &tok->tp.tok.location, error_message);
777   else
778     error ("%s", error_message);
779 }
780
781 /* Reverse the order of a token list, linked by parse_next, old first
782    token is OLD_FIRST.  */
783
784 static struct prod_token_parm_item*
785 reverse_prod_list (struct prod_token_parm_item *old_first)
786 {
787   struct prod_token_parm_item *current;
788   struct prod_token_parm_item *next;
789   struct prod_token_parm_item *prev = NULL;
790   
791   current = old_first;
792   prev = NULL;
793
794   while (current) 
795     {
796       gcc_assert (current->category == production_category);
797
798       next = current->tp.pro.next;
799       current->tp.pro.next = prev;
800       prev = current;
801       current = next; 
802     }
803   return prev;
804 }
805
806 /* Ensure TYPE is not VOID. Use NAME as the token for the error location.  */
807
808 static void
809 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
810 {
811   if (type == VOID_TYPE)
812     error ("%HType must not be void in this context.",
813            &name->tp.tok.location);
814 }
815
816 /* Check TYPE1 and TYPE2 which are integral types.  Return the lowest
817    common type (min is signed int).  */
818
819 static int 
820 get_common_type (struct prod_token_parm_item *type1,
821                  struct prod_token_parm_item *type2)
822 {
823   if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
824     return UNSIGNED_INT;
825   if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
826     return UNSIGNED_INT;
827
828   return SIGNED_INT;
829 }
830
831 /* Check type (TYPE_NUM) and expression (EXP) match.  Return the 1 if
832    OK else 0.  Must be exact match - same name unless it is an
833    integral type.  */
834
835 static int 
836 check_type_match (int type_num, struct prod_token_parm_item *exp)
837 {
838   switch (type_num)
839     {
840     case SIGNED_INT:
841     case UNSIGNED_INT:
842     case SIGNED_CHAR:
843     case UNSIGNED_CHAR:
844       switch (NUMERIC_TYPE (exp))
845         {
846         case SIGNED_INT:
847         case UNSIGNED_INT:
848         case SIGNED_CHAR:
849         case UNSIGNED_CHAR:
850           return 1;
851           
852         case VOID_TYPE:
853         default: 
854           gcc_unreachable ();
855         }
856       break;
857       
858     case VOID_TYPE:
859     default:
860       gcc_unreachable ();
861       
862     }
863 }
864
865 /* Make a production for an integer constant VALUE.  */
866
867 static struct prod_token_parm_item *
868 make_integer_constant (struct prod_token_parm_item* value)
869 {
870   struct prod_token_parm_item* tok;
871   struct prod_token_parm_item *prod;
872   tok = value;
873   prod = make_production (PROD_INTEGER_CONSTANT, tok);
874   if ((tok->tp.tok.chars[0] == (unsigned char)'-')
875       || (tok->tp.tok.chars[0] == (unsigned char)'+'))
876     NUMERIC_TYPE (prod) = SIGNED_INT;
877   else
878     NUMERIC_TYPE (prod) = UNSIGNED_INT;
879   prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
880                                                    tok->tp.tok.length);
881   return prod;
882 }
883
884
885 /* Build a PROD_PLUS_EXPRESSION.  This is uses for PLUS, MINUS, ASSIGN
886    and EQUALS expressions.  */
887
888 static struct prod_token_parm_item *
889 make_plus_expression (struct prod_token_parm_item* tok,
890                       struct prod_token_parm_item* op1,
891                       struct prod_token_parm_item* op2,
892                       int type_code, int prod_code)
893 {
894   struct prod_token_parm_item *prod;
895   tree type;
896
897   ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
898   ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
899
900   prod = make_production (PROD_PLUS_EXPRESSION, tok);
901
902   NUMERIC_TYPE (prod) = type_code;
903   type = tree_code_get_type (type_code);
904
905   gcc_assert (type);
906
907   OP1 (prod) = op1;
908   OP2 (prod) = op2;
909       
910   prod->tp.pro.code = tree_code_get_expression (prod_code, type,
911                                                 op1->tp.pro.code,
912                                                 op2->tp.pro.code, NULL);
913
914   return prod;
915 }
916
917
918 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN.  */
919
920 static void
921 set_storage (struct prod_token_parm_item *prod)
922 {
923   struct prod_token_parm_item* stg_class;
924   stg_class = STORAGE_CLASS_TOKEN (prod);
925   switch (stg_class->type)
926     {
927     case STATIC:
928       STORAGE_CLASS (prod) = STATIC_STORAGE;
929       break;
930       
931     case AUTOMATIC:
932       STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
933       break;
934       
935     case EXTERNAL_DEFINITION:
936       STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
937       break;
938
939     case EXTERNAL_REFERENCE:
940       STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
941       break;
942
943     default:
944       gcc_unreachable ();
945     }
946 }
947
948 /* Set parse trace.  */
949
950 void
951 treelang_debug (void)
952 {
953   if (option_parser_trace)
954     yydebug = 1;
955 }
956
957 #ifdef __XGETTEXT__
958 /* Depending on the version of Bison used to compile this grammar,
959    it may issue generic diagnostics spelled "syntax error" or
960    "parse error".  To prevent this from changing the translation
961    template randomly, we list all the variants of this particular
962    diagnostic here.  Translators: there is no fine distinction
963    between diagnostics with "syntax error" in them, and diagnostics
964    with "parse error" in them.  It's okay to give them both the same
965    translation.  */
966 const char d1[] = N_("syntax error");
967 const char d2[] = N_("parse error");
968 const char d3[] = N_("syntax error; also virtual memory exhausted");
969 const char d4[] = N_("parse error; also virtual memory exhausted");
970 const char d5[] = N_("syntax error: cannot back up");
971 const char d6[] = N_("parse error: cannot back up");
972 #endif