OSDN Git Service

2007-10-19 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[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, 2005, 2007
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 3, 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; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.
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-2001, based in part on other parts of
30 the GCC compiler.  */
31
32 /* Grammar Conflicts
33    *****************
34    There are no conflicts in this grammar.  Please keep it that way.  */
35
36 %{
37 #include "config.h"
38 #include "system.h"
39 #include "coretypes.h"
40 #include "tm.h"
41 #include "timevar.h"
42 #include "tree.h"
43
44 #include "treelang.h"
45 #include "treetree.h"
46 #include "toplev.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 *)
201                    VAR_INIT (prod))->tp.pro.code);
202       if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
203         {
204           error("%Hexternal reference variable %q.*s has an initial value",
205                 &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
206           YYERROR;
207           VAR_INIT (prod) = NULL;
208         }
209
210     }
211
212   prod->tp.pro.code = tree_code_create_variable
213     (STORAGE_CLASS (prod),
214      ((struct prod_token_parm_item *)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
215      ((struct prod_token_parm_item *)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
216      NUMERIC_TYPE (prod),
217      VAR_INIT (prod) ?
218      ((struct prod_token_parm_item *)VAR_INIT (prod))->tp.pro.code : NULL,
219      tok->tp.tok.location);
220   gcc_assert (prod->tp.pro.code);
221 }
222 ;
223
224 storage:
225 STATIC
226 |AUTOMATIC
227 |EXTERNAL_DEFINITION
228 |EXTERNAL_REFERENCE
229 ;
230
231 parameter:
232 typename NAME {
233   struct prod_token_parm_item *tok;
234   struct prod_token_parm_item *prod;
235   struct prod_token_parm_item *prod2;
236   tok = $2;
237   prod = make_production (PROD_VARIABLE_NAME, tok);
238   SYMBOL_TABLE_NAME (prod) = $2;
239   EXPRESSION_TYPE (prod) = $1;
240   NUMERIC_TYPE (prod) =
241     NUMERIC_TYPE (( (struct prod_token_parm_item *)EXPRESSION_TYPE (prod)));
242   ensure_not_void (NUMERIC_TYPE (prod), tok);
243   if (insert_tree_name (prod))
244     {
245       YYERROR;
246     }
247   prod2 = make_production (PROD_PARAMETER, tok);
248   VARIABLE (prod2) = prod;
249   $$ = prod2;
250 }
251 ;
252
253 function_prototype:
254 storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLON {
255   struct prod_token_parm_item *tok;
256   struct prod_token_parm_item *prod;
257   struct prod_token_parm_item *type;
258   struct prod_token_parm_item *first_parms;
259   struct prod_token_parm_item *last_parms;
260   struct prod_token_parm_item *this_parms;
261   struct prod_token_parm_item *this_parm;
262   struct prod_token_parm_item *this_parm_var;
263   tok = $3;
264   prod = make_production (PROD_FUNCTION_NAME, $3);
265   SYMBOL_TABLE_NAME (prod) = $3;
266   EXPRESSION_TYPE (prod) = $2;
267   NUMERIC_TYPE (prod) =
268     NUMERIC_TYPE (( (struct prod_token_parm_item *)EXPRESSION_TYPE (prod)));
269   PARAMETERS (prod) = reverse_prod_list ($5);
270   insert_tree_name (prod);
271   STORAGE_CLASS_TOKEN (prod) = $1;
272   set_storage (prod);
273   switch (STORAGE_CLASS (prod))
274     {
275     case STATIC_STORAGE:
276     case EXTERNAL_DEFINITION_STORAGE:
277     case EXTERNAL_REFERENCE_STORAGE:
278       break;
279
280     case AUTOMATIC_STORAGE:
281       error ("%Hfunction %q.*s cannot be automatic",
282              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
283       YYERROR;
284       break;
285
286     default:
287       gcc_unreachable ();
288     }
289   type = EXPRESSION_TYPE (prod);
290   /* Create a parameter list in a non-front end specific format.  */
291   for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
292        this_parm;
293        this_parm = this_parm->tp.pro.next)
294     {
295       gcc_assert (this_parm->category == production_category);
296       this_parm_var = VARIABLE (this_parm);
297
298       gcc_assert (this_parm_var);
299       gcc_assert (this_parm_var->category == production_category);
300       gcc_assert (this_parm_var->tp.pro.main_token);
301
302       this_parms = my_malloc (sizeof (struct prod_token_parm_item));
303
304       this_parms->tp.par.variable_name =
305         this_parm_var->tp.pro.main_token->tp.tok.chars;
306       this_parms->category = parameter_category;
307       this_parms->type = NUMERIC_TYPE
308         (( (struct prod_token_parm_item *)EXPRESSION_TYPE (this_parm_var)));
309       if (last_parms)
310         {
311           last_parms->tp.par.next = this_parms;
312           last_parms = this_parms;
313         }
314       else
315         {
316           first_parms = this_parms;
317           last_parms = this_parms;
318         }
319       this_parms->tp.par.where_to_put_var_tree =
320         & (((struct prod_token_parm_item *)VARIABLE (this_parm))->tp.pro.code);
321     }
322   FIRST_PARMS (prod) = first_parms;
323
324   prod->tp.pro.code =
325     tree_code_create_function_prototype (tok->tp.tok.chars,
326                                          STORAGE_CLASS (prod),
327                                          NUMERIC_TYPE (type),
328                                          first_parms, tok->tp.tok.location);
329
330 #ifdef ENABLE_CHECKING
331   /* Check all the parameters have code.  */
332   for (this_parm = PARAMETERS (prod);
333        this_parm;
334        this_parm = this_parm->tp.pro.next)
335     {
336       gcc_assert ((struct prod_token_parm_item *)VARIABLE (this_parm));
337       gcc_assert (((struct prod_token_parm_item *)
338                    VARIABLE (this_parm))->tp.pro.code);
339     }
340 #endif
341 }
342 ;
343
344 function:
345 NAME LEFT_BRACE {
346   struct prod_token_parm_item *proto;
347   struct prod_token_parm_item search_prod;
348   struct prod_token_parm_item *tok;
349   tok = $1;
350   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
351   search_prod.category = token_category;
352   current_function = proto = lookup_tree_name (&search_prod);
353   if (!proto)
354     {
355       error ("%Hno prototype found for %q.*s", &tok->tp.tok.location,
356              tok->tp.tok.length, tok->tp.tok.chars);
357       YYERROR;
358     }
359
360   gcc_assert (proto->tp.pro.code);
361
362   tree_code_create_function_initial (proto->tp.pro.code, tok->tp.tok.location);
363 }
364
365 variable_defs_opt statements_opt RIGHT_BRACE {
366   struct prod_token_parm_item *tok;
367   tok = $1;
368   tree_code_create_function_wrapup (tok->tp.tok.location);
369   current_function = NULL;
370 }
371 ;
372
373 variable_defs_opt:
374 /* Nil.  */ {
375   $$ = 0;
376 }
377 |variable_defs {
378   $$ = $1;
379 }
380 ;
381
382 statements_opt:
383 /* Nil.  */ {
384   $$ = 0;
385 }
386 |statements {
387   $$ = $1;
388 }
389 ;
390
391 variable_defs:
392 variable_def {
393   /* Nothing to do.  */
394 }
395 |variable_defs variable_def {
396   /* Nothing to do.  */
397 }
398 ;
399
400 typename:
401 INT {
402   struct prod_token_parm_item *tok;
403   struct prod_token_parm_item *prod;
404   tok = $1;
405   prod = make_production (PROD_TYPE_NAME, tok);
406   NUMERIC_TYPE (prod) = SIGNED_INT;
407   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
408   $$ = prod;
409 }
410 |UNSIGNED INT {
411   struct prod_token_parm_item *tok;
412   struct prod_token_parm_item *prod;
413   tok = $1;
414   prod = make_production (PROD_TYPE_NAME, tok);
415   NUMERIC_TYPE (prod) = UNSIGNED_INT;
416   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
417   $$ = prod;
418 }
419 |CHAR {
420   struct prod_token_parm_item *tok;
421   struct prod_token_parm_item *prod;
422   tok = $1;
423   prod = make_production (PROD_TYPE_NAME, tok);
424   NUMERIC_TYPE (prod) = SIGNED_CHAR;
425   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
426   $$ = prod;
427 }
428 |UNSIGNED CHAR {
429   struct prod_token_parm_item *tok;
430   struct prod_token_parm_item *prod;
431   tok = $1;
432   prod = make_production (PROD_TYPE_NAME, tok);
433   NUMERIC_TYPE (prod) = UNSIGNED_CHAR;
434   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
435   $$ = prod;
436 }
437 |VOID {
438   struct prod_token_parm_item *tok;
439   struct prod_token_parm_item *prod;
440   tok = $1;
441   prod = make_production (PROD_TYPE_NAME, tok);
442   NUMERIC_TYPE (prod) = VOID_TYPE;
443   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
444   $$ = prod;
445 }
446 ;
447
448 parameters_opt:
449 /* Nothing to do.  */ {
450  $$ = 0;
451 }
452 | parameters {
453  $$ = $1;
454 }
455 ;
456
457 parameters:
458 parameter {
459   /* Nothing to do.  */
460   $$ = $1;
461 }
462 |parameters COMMA parameter {
463   struct prod_token_parm_item *prod1;
464   prod1 = $3;
465   prod1->tp.pro.next = $1; /* Insert in reverse order.  */
466   $$ = prod1;
467 }
468 ;
469
470 statements:
471 statement {
472   /* Nothing to do.  */
473 }
474 |statements statement {
475   /* Nothing to do.  */
476 }
477 ;
478
479 statement:
480 expression SEMICOLON {
481   struct prod_token_parm_item *exp;
482   exp = $1;
483   tree_code_output_expression_statement (exp->tp.pro.code,
484                                          exp->tp.pro.main_token->tp.tok.location);
485 }
486 |return SEMICOLON {
487   /* Nothing to do.  */
488 }
489 |if_statement {
490   /* Nothing to do.  */
491 }
492 ;
493
494 if_statement:
495 IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
496   struct prod_token_parm_item *tok;
497   struct prod_token_parm_item *exp;
498   tok = $1;
499   exp = $3;
500   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
501   tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
502 }
503 LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
504   /* Just let the statements flow.  */
505 }
506 ELSE {
507   struct prod_token_parm_item *tok;
508   tok = $1;
509   tree_code_if_else (tok->tp.tok.location);
510 }
511 LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
512   struct prod_token_parm_item *tok;
513   tok = $1;
514   tree_code_if_end (tok->tp.tok.location);
515 }
516 ;
517
518
519 return:
520 tl_RETURN expression_opt {
521   struct prod_token_parm_item *type_prod;
522   struct prod_token_parm_item *ret_tok = $1;
523   struct prod_token_parm_item *exp = $2;
524
525   type_prod = EXPRESSION_TYPE (current_function);
526   if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
527     if (exp == NULL)
528       tree_code_generate_return (type_prod->tp.pro.code, NULL);
529     else
530       {
531         warning (0, "%Hredundant expression in return",
532                  &ret_tok->tp.tok.location);
533         tree_code_generate_return (type_prod->tp.pro.code, NULL);
534        }
535   else
536     if (exp == NULL)
537         error ("%Hexpression missing in return", &ret_tok->tp.tok.location);
538     else
539       {
540         /* Check same type.  */
541         if (check_type_match (NUMERIC_TYPE (type_prod), exp))
542           {
543             gcc_assert (type_prod->tp.pro.code);
544             gcc_assert (exp->tp.pro.code);
545
546             /* Generate the code. */
547             tree_code_generate_return (type_prod->tp.pro.code,
548                                        exp->tp.pro.code);
549           }
550       }
551 }
552 ;
553
554 expression_opt:
555 /* Nil.  */ {
556   $$ = 0;
557 }
558 |expression {
559   struct prod_token_parm_item *exp;
560   exp = $1;
561   gcc_assert (exp->tp.pro.code);
562
563   $$ = $1;
564 }
565 ;
566
567 expression:
568 INTEGER {
569   $$ = make_integer_constant ($1);
570 }
571 |variable_ref {
572   $$ = $1;
573 }
574 |expression tl_PLUS expression {
575   struct prod_token_parm_item *tok = $2;
576   struct prod_token_parm_item *op1 = $1;
577   struct prod_token_parm_item *op2 = $3;
578   int type_code = get_common_type (op1, op2);
579   if (!type_code)
580     YYERROR;
581   $$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
582 }
583 |expression tl_MINUS expression %prec tl_PLUS {
584   struct prod_token_parm_item *tok = $2;
585   struct prod_token_parm_item *op1 = $1;
586   struct prod_token_parm_item *op2 = $3;
587   int type_code = get_common_type (op1, op2);
588   if (!type_code)
589     YYERROR;
590   $$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
591 }
592 |expression EQUALS expression {
593   struct prod_token_parm_item *tok = $2;
594   struct prod_token_parm_item *op1 = $1;
595   struct prod_token_parm_item *op2 = $3;
596   int type_code = NUMERIC_TYPE (op1);
597   if (!type_code)
598     YYERROR;
599   $$ = make_plus_expression
600      (tok, op1, op2, type_code, EXP_EQUALS);
601 }
602 |variable_ref ASSIGN expression {
603   struct prod_token_parm_item *tok = $2;
604   struct prod_token_parm_item *op1 = $1;
605   struct prod_token_parm_item *op2 = $3;
606   int type_code = NUMERIC_TYPE (op1);
607   if (!type_code)
608     YYERROR;
609   $$ = make_plus_expression
610      (tok, op1, op2, type_code, EXP_ASSIGN);
611 }
612 |function_invocation {
613   $$ = $1;
614 }
615 ;
616
617 function_invocation:
618 NAME LEFT_PARENTHESIS expressions_with_commas_opt RIGHT_PARENTHESIS {
619   struct prod_token_parm_item *prod;
620   struct prod_token_parm_item *tok;
621   struct prod_token_parm_item search_prod;
622   struct prod_token_parm_item *proto;
623   struct prod_token_parm_item *exp;
624   struct prod_token_parm_item *exp_proto;
625   struct prod_token_parm_item *var;
626   int exp_proto_count;
627   int exp_count;
628   tree parms;
629   tree type;
630
631   tok = $1;
632   prod = make_production (PROD_FUNCTION_INVOCATION, tok);
633   SYMBOL_TABLE_NAME (prod) = tok;
634   PARAMETERS (prod) = reverse_prod_list ($3);
635   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
636   search_prod.category = token_category;
637   proto = lookup_tree_name (&search_prod);
638   if (!proto)
639     {
640       error ("%Hfunction prototype not found for %q.*s",
641              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
642       YYERROR;
643     }
644   EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
645   NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
646   /* Count the expressions and ensure they match the prototype.  */
647   for (exp_proto_count = 0, exp_proto = PARAMETERS (proto);
648        exp_proto; exp_proto = exp_proto->tp.pro.next)
649     exp_proto_count++;
650
651   for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
652     exp_count++;
653
654   if (exp_count !=  exp_proto_count)
655     {
656       error ("%Hexpression count mismatch %q.*s with prototype",
657              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
658       YYERROR;
659     }
660   parms = tree_code_init_parameters ();
661   for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
662        exp_proto;
663        exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
664     {
665       gcc_assert (exp);
666       gcc_assert (exp_proto);
667       gcc_assert (exp->tp.pro.code);
668
669       var = VARIABLE (exp_proto);
670
671       gcc_assert (var);
672       gcc_assert (var->tp.pro.code);
673
674       parms = tree_code_add_parameter (parms, var->tp.pro.code,
675                                        exp->tp.pro.code);
676     }
677   type = tree_code_get_type (NUMERIC_TYPE (prod));
678   prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
679                                                 proto->tp.pro.code,
680                                                 nreverse (parms),
681                                                 NULL, tok->tp.tok.location);
682   $$ = prod;
683 }
684 ;
685
686 expressions_with_commas_opt:
687 /* Nil.  */ {
688 $$ = 0
689 }
690 |expressions_with_commas { $$ = $1 }
691 ;
692
693 expressions_with_commas:
694 expression {
695   struct prod_token_parm_item *exp;
696   exp = $1;
697   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
698   $$ = $1;
699 }
700 |expressions_with_commas COMMA expression {
701   struct prod_token_parm_item *exp;
702   exp = $3;
703   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
704   exp->tp.pro.next = $1; /* Reverse order.  */
705   $$ = exp;
706 }
707 ;
708
709 variable_ref:
710 NAME {
711   struct prod_token_parm_item search_prod;
712   struct prod_token_parm_item *prod;
713   struct prod_token_parm_item *symbol_table_entry;
714   struct prod_token_parm_item *tok;
715   tree type;
716
717   tok = $1;
718   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
719   search_prod.category = token_category;
720   symbol_table_entry = lookup_tree_name (&search_prod);
721   if (!symbol_table_entry)
722     {
723       error ("%Hvariable %q.*s not defined",
724              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
725       YYERROR;
726     }
727
728   prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
729   NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
730   type = tree_code_get_type (NUMERIC_TYPE (prod));
731   if (!NUMERIC_TYPE (prod))
732     YYERROR;
733   OP1 (prod) = $1;
734
735   prod->tp.pro.code =
736     tree_code_get_expression (EXP_REFERENCE, type,
737                               symbol_table_entry->tp.pro.code, NULL, NULL,
738                               tok->tp.tok.location);
739   $$ = prod;
740 }
741 ;
742
743 init_opt:
744 /* Nil.  */ {
745   $$ = 0;
746 }
747 |init {
748   /* Pass the initialization value up.  */
749   $$ = $1;
750 };
751
752 init:
753 ASSIGN init_element {
754   $$ = $2;
755 }
756 ;
757
758 init_element:
759 INTEGER {
760   $$ = make_integer_constant ($1);
761 }
762 ;
763
764 %%
765
766 /* Print a token VALUE to file FILE.  Ignore TYPE which is the token
767    type. */
768
769 void
770 print_token (FILE *file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
771 {
772   struct prod_token_parm_item *tok;
773   unsigned int  ix;
774
775   tok  =  value;
776   fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
777   for (ix  =  0; ix < tok->tp.tok.length; ix++)
778     fprintf (file, "%c", tok->tp.tok.chars[ix]);
779
780   fprintf (file, "\"");
781 }
782
783 /* Output a message ERROR_MESSAGE from the parser.  */
784 static void
785 yyerror (const char *error_message)
786 {
787   struct prod_token_parm_item *tok;
788
789   tok = yylval;
790   if (tok)
791     error ("%H%s", &tok->tp.tok.location, error_message);
792   else
793     error ("%s", error_message);
794 }
795
796 /* Reverse the order of a token list, linked by parse_next, old first
797    token is OLD_FIRST.  */
798
799 static struct prod_token_parm_item*
800 reverse_prod_list (struct prod_token_parm_item *old_first)
801 {
802   struct prod_token_parm_item *current;
803   struct prod_token_parm_item *next;
804   struct prod_token_parm_item *prev = NULL;
805
806   current = old_first;
807   prev = NULL;
808
809   while (current)
810     {
811       gcc_assert (current->category == production_category);
812
813       next = current->tp.pro.next;
814       current->tp.pro.next = prev;
815       prev = current;
816       current = next;
817     }
818   return prev;
819 }
820
821 /* Ensure TYPE is not VOID. Use NAME as the token for the error location.  */
822
823 static void
824 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
825 {
826   if (type == VOID_TYPE)
827     error ("%Htype must not be void in this context",
828            &name->tp.tok.location);
829 }
830
831 /* Check TYPE1 and TYPE2 which are integral types.  Return the lowest
832    common type (min is signed int).  */
833
834 static int
835 get_common_type (struct prod_token_parm_item *type1,
836                  struct prod_token_parm_item *type2)
837 {
838   if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
839     return UNSIGNED_INT;
840   if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
841     return UNSIGNED_INT;
842
843   return SIGNED_INT;
844 }
845
846 /* Check type (TYPE_NUM) and expression (EXP) match.  Return the 1 if
847    OK else 0.  Must be exact match - same name unless it is an
848    integral type.  */
849
850 static int
851 check_type_match (int type_num, struct prod_token_parm_item *exp)
852 {
853   switch (type_num)
854     {
855     case SIGNED_INT:
856     case UNSIGNED_INT:
857     case SIGNED_CHAR:
858     case UNSIGNED_CHAR:
859       switch (NUMERIC_TYPE (exp))
860         {
861         case SIGNED_INT:
862         case UNSIGNED_INT:
863         case SIGNED_CHAR:
864         case UNSIGNED_CHAR:
865           return 1;
866
867         case VOID_TYPE:
868         default:
869           gcc_unreachable ();
870         }
871       break;
872
873     case VOID_TYPE:
874     default:
875       gcc_unreachable ();
876
877     }
878 }
879
880 /* Make a production for an integer constant VALUE.  */
881
882 static struct prod_token_parm_item *
883 make_integer_constant (struct prod_token_parm_item* value)
884 {
885   struct prod_token_parm_item *tok;
886   struct prod_token_parm_item *prod;
887   tok = value;
888   prod = make_production (PROD_INTEGER_CONSTANT, tok);
889   if ((tok->tp.tok.chars[0] == (unsigned char)'-')
890       || (tok->tp.tok.chars[0] == (unsigned char)'+'))
891     NUMERIC_TYPE (prod) = SIGNED_INT;
892   else
893     NUMERIC_TYPE (prod) = UNSIGNED_INT;
894   prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
895                                                    tok->tp.tok.length);
896   return prod;
897 }
898
899
900 /* Build a PROD_PLUS_EXPRESSION.  This is uses for PLUS, MINUS, ASSIGN
901    and EQUALS expressions.  */
902
903 static struct prod_token_parm_item *
904 make_plus_expression (struct prod_token_parm_item *tok,
905                       struct prod_token_parm_item *op1,
906                       struct prod_token_parm_item *op2,
907                       int type_code, int prod_code)
908 {
909   struct prod_token_parm_item *prod;
910   tree type;
911
912   ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
913   ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
914
915   prod = make_production (PROD_PLUS_EXPRESSION, tok);
916
917   NUMERIC_TYPE (prod) = type_code;
918   type = tree_code_get_type (type_code);
919
920   gcc_assert (type);
921
922   OP1 (prod) = op1;
923   OP2 (prod) = op2;
924
925   prod->tp.pro.code = tree_code_get_expression (prod_code, type,
926                                                 op1->tp.pro.code,
927                                                 op2->tp.pro.code, NULL,
928                                                 tok->tp.tok.location);
929
930   return prod;
931 }
932
933
934 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN.  */
935
936 static void
937 set_storage (struct prod_token_parm_item *prod)
938 {
939   struct prod_token_parm_item *stg_class;
940   stg_class = STORAGE_CLASS_TOKEN (prod);
941   switch (stg_class->type)
942     {
943     case STATIC:
944       STORAGE_CLASS (prod) = STATIC_STORAGE;
945       break;
946
947     case AUTOMATIC:
948       STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
949       break;
950
951     case EXTERNAL_DEFINITION:
952       STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
953       break;
954
955     case EXTERNAL_REFERENCE:
956       STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
957       break;
958
959     default:
960       gcc_unreachable ();
961     }
962 }
963
964 /* Set parse trace.  */
965
966 void
967 treelang_debug (void)
968 {
969   if (option_parser_trace)
970     yydebug = 1;
971 }
972
973 #ifdef __XGETTEXT__
974 /* Depending on the version of Bison used to compile this grammar,
975    it may issue generic diagnostics spelled "syntax error" or
976    "parse error".  To prevent this from changing the translation
977    template randomly, we list all the variants of this particular
978    diagnostic here.  Translators: there is no fine distinction
979    between diagnostics with "syntax error" in them, and diagnostics
980    with "parse error" in them.  It's okay to give them both the same
981    translation.  */
982 const char d1[] = N_("syntax error");
983 const char d2[] = N_("parse error");
984 const char d3[] = N_("syntax error; also virtual memory exhausted");
985 const char d4[] = N_("parse error; also virtual memory exhausted");
986 const char d5[] = N_("syntax error: cannot back up");
987 const char d6[] = N_("parse error: cannot back up");
988 #endif