OSDN Git Service

2005-04-05 Thomas Fitzsimmons <fitzsim@redhat.com>
[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
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     case EXTERNAL_REFERENCE_STORAGE:
277       break;
278       
279     case AUTOMATIC_STORAGE:
280       error ("%HFunction %q.*s cannot be automatic.",
281              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
282       YYERROR;
283       break;
284
285     default:
286       gcc_unreachable ();
287     }
288   type = EXPRESSION_TYPE (prod);
289   /* Create a parameter list in a non-front end specific format.  */
290   for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
291        this_parm;
292        this_parm = this_parm->tp.pro.next)
293     {
294       gcc_assert (this_parm->category == production_category);
295       this_parm_var = VARIABLE (this_parm);
296
297       gcc_assert (this_parm_var);
298       gcc_assert (this_parm_var->category == production_category);
299       gcc_assert (this_parm_var->tp.pro.main_token);
300
301       this_parms = my_malloc (sizeof (struct prod_token_parm_item));
302
303       this_parms->tp.par.variable_name =
304         this_parm_var->tp.pro.main_token->tp.tok.chars;
305       this_parms->category = parameter_category;
306       this_parms->type = NUMERIC_TYPE 
307         (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
308       if (last_parms)
309         {
310           last_parms->tp.par.next = this_parms;
311           last_parms = this_parms;
312         }
313       else
314         {
315           first_parms = this_parms;
316           last_parms = this_parms;
317         }
318       this_parms->tp.par.where_to_put_var_tree = 
319         & (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
320     }
321   FIRST_PARMS (prod) = first_parms;
322
323   prod->tp.pro.code =
324     tree_code_create_function_prototype (tok->tp.tok.chars,
325                                          STORAGE_CLASS (prod),
326                                          NUMERIC_TYPE (type),
327                                          first_parms, tok->tp.tok.location);
328
329 #ifdef ENABLE_CHECKING
330   /* Check all the parameters have code.  */
331   for (this_parm = PARAMETERS (prod);
332        this_parm;
333        this_parm = this_parm->tp.pro.next)
334     {
335       gcc_assert ((struct prod_token_parm_item*)VARIABLE (this_parm));
336       gcc_assert (((struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
337     }
338 #endif
339 }
340 ;
341
342 function:
343 NAME LEFT_BRACE {
344   struct prod_token_parm_item *proto;
345   struct prod_token_parm_item search_prod;
346   struct prod_token_parm_item* tok;
347   tok = $1;
348   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
349   search_prod.category = token_category;
350   current_function = proto = lookup_tree_name (&search_prod);
351   if (!proto)
352     {
353       error ("%HNo prototype found for %q.*s", &tok->tp.tok.location,
354              tok->tp.tok.length, tok->tp.tok.chars);
355       YYERROR;
356     }
357
358   gcc_assert (proto->tp.pro.code);
359
360   tree_code_create_function_initial (proto->tp.pro.code, tok->tp.tok.location);
361 }
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   int type_code = NUMERIC_TYPE (op1);
595   if (!type_code)
596     YYERROR;
597   $$ = make_plus_expression
598      (tok, op1, op2, type_code, EXP_EQUALS);
599 }
600 |variable_ref ASSIGN expression {
601   struct prod_token_parm_item *tok = $2;
602   struct prod_token_parm_item *op1 = $1;
603   struct prod_token_parm_item *op2 = $3;
604   int type_code = NUMERIC_TYPE (op1);
605   if (!type_code)
606     YYERROR;
607   $$ = make_plus_expression
608      (tok, op1, op2, type_code, EXP_ASSIGN);
609 }
610 |function_invocation {
611   $$ = $1;
612 }
613 ;
614
615 function_invocation:
616 NAME LEFT_PARENTHESIS expressions_with_commas_opt RIGHT_PARENTHESIS {
617   struct prod_token_parm_item *prod;
618   struct prod_token_parm_item* tok;
619   struct prod_token_parm_item search_prod;
620   struct prod_token_parm_item *proto;
621   struct prod_token_parm_item *exp;
622   struct prod_token_parm_item *exp_proto;
623   struct prod_token_parm_item *var;
624   int exp_proto_count;
625   int exp_count;
626   tree parms;
627   tree type;
628   
629   tok = $1;
630   prod = make_production (PROD_FUNCTION_INVOCATION, tok);
631   SYMBOL_TABLE_NAME (prod) = tok;
632   PARAMETERS (prod) = reverse_prod_list ($3);
633   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
634   search_prod.category = token_category;
635   proto = lookup_tree_name (&search_prod);
636   if (!proto)
637     {
638       error ("%HFunction prototype not found for %q.*%s.",
639              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
640       YYERROR;
641     }
642   EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
643   NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
644   /* Count the expressions and ensure they match the prototype.  */
645   for (exp_proto_count = 0, exp_proto = PARAMETERS (proto); 
646        exp_proto; exp_proto = exp_proto->tp.pro.next)
647     exp_proto_count++;
648
649   for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
650     exp_count++;
651
652   if (exp_count !=  exp_proto_count)
653     {
654       error ("%HExpression count mismatch %q.*s with prototype.",
655              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
656       YYERROR;
657     }
658   parms = tree_code_init_parameters ();
659   for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
660        exp_proto;
661        exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
662     {
663       gcc_assert (exp);
664       gcc_assert (exp_proto);
665       gcc_assert (exp->tp.pro.code);
666
667       var = VARIABLE (exp_proto);
668
669       gcc_assert (var);
670       gcc_assert (var->tp.pro.code);
671
672       parms = tree_code_add_parameter (parms, var->tp.pro.code,
673                                        exp->tp.pro.code);
674     }
675   type = tree_code_get_type (NUMERIC_TYPE (prod));
676   prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
677                                                 proto->tp.pro.code, parms,
678                                                 NULL, tok->tp.tok.location);
679   $$ = prod;
680 }
681 ;
682
683 expressions_with_commas_opt: 
684 /* Nil.  */ {
685 $$ = 0
686 }
687 |expressions_with_commas { $$ = $1 }
688 ;
689
690 expressions_with_commas:
691 expression {
692   struct prod_token_parm_item *exp;
693   exp = $1;
694   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
695   $$ = $1;
696 }
697 |expressions_with_commas COMMA expression {
698   struct prod_token_parm_item *exp;
699   exp = $3;
700   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
701   exp->tp.pro.next = $1; /* Reverse order.  */
702   $$ = exp;
703 }
704 ;
705
706 variable_ref:
707 NAME {
708   struct prod_token_parm_item search_prod;
709   struct prod_token_parm_item *prod;
710   struct prod_token_parm_item *symbol_table_entry;
711   struct prod_token_parm_item* tok;
712   tree type;
713
714   tok = $1;
715   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
716   search_prod.category = token_category;
717   symbol_table_entry = lookup_tree_name (&search_prod);
718   if (!symbol_table_entry)
719     {
720       error ("%HVariable %q.*s not defined.",
721              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
722       YYERROR;
723     }
724
725   prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
726   NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
727   type = tree_code_get_type (NUMERIC_TYPE (prod));
728   if (!NUMERIC_TYPE (prod))
729     YYERROR;
730   OP1 (prod) = $1;
731   
732   prod->tp.pro.code =
733     tree_code_get_expression (EXP_REFERENCE, type,
734                               symbol_table_entry->tp.pro.code, NULL, NULL,
735                               tok->tp.tok.location);
736   $$ = prod;
737 }
738 ;
739
740 init_opt:
741 /* Nil.  */ {
742   $$ = 0;
743 }
744 |init {
745   /* Pass the initialization value up.  */
746   $$ = $1;
747 };
748
749 init:
750 ASSIGN init_element {
751   $$ = $2;
752 }
753 ;
754
755 init_element:
756 INTEGER {
757   $$ = make_integer_constant ($1);
758 }
759 ;
760
761 %%
762
763 /* Print a token VALUE to file FILE.  Ignore TYPE which is the token
764    type. */
765
766 void
767 print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value) 
768 {
769   struct prod_token_parm_item *tok;
770   unsigned int  ix;
771
772   tok  =  value;
773   fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
774   for (ix  =  0; ix < tok->tp.tok.length; ix++)
775     fprintf (file, "%c", tok->tp.tok.chars[ix]);
776
777   fprintf (file, "\"");
778 }
779
780 /* Output a message ERROR_MESSAGE from the parser.  */
781 static void
782 yyerror (const char *error_message)
783 {
784   struct prod_token_parm_item *tok;
785
786   tok = yylval;
787   if (tok)
788     error ("%H%s", &tok->tp.tok.location, error_message);
789   else
790     error ("%s", error_message);
791 }
792
793 /* Reverse the order of a token list, linked by parse_next, old first
794    token is OLD_FIRST.  */
795
796 static struct prod_token_parm_item*
797 reverse_prod_list (struct prod_token_parm_item *old_first)
798 {
799   struct prod_token_parm_item *current;
800   struct prod_token_parm_item *next;
801   struct prod_token_parm_item *prev = NULL;
802   
803   current = old_first;
804   prev = NULL;
805
806   while (current) 
807     {
808       gcc_assert (current->category == production_category);
809
810       next = current->tp.pro.next;
811       current->tp.pro.next = prev;
812       prev = current;
813       current = next; 
814     }
815   return prev;
816 }
817
818 /* Ensure TYPE is not VOID. Use NAME as the token for the error location.  */
819
820 static void
821 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
822 {
823   if (type == VOID_TYPE)
824     error ("%HType must not be void in this context.",
825            &name->tp.tok.location);
826 }
827
828 /* Check TYPE1 and TYPE2 which are integral types.  Return the lowest
829    common type (min is signed int).  */
830
831 static int 
832 get_common_type (struct prod_token_parm_item *type1,
833                  struct prod_token_parm_item *type2)
834 {
835   if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
836     return UNSIGNED_INT;
837   if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
838     return UNSIGNED_INT;
839
840   return SIGNED_INT;
841 }
842
843 /* Check type (TYPE_NUM) and expression (EXP) match.  Return the 1 if
844    OK else 0.  Must be exact match - same name unless it is an
845    integral type.  */
846
847 static int 
848 check_type_match (int type_num, struct prod_token_parm_item *exp)
849 {
850   switch (type_num)
851     {
852     case SIGNED_INT:
853     case UNSIGNED_INT:
854     case SIGNED_CHAR:
855     case UNSIGNED_CHAR:
856       switch (NUMERIC_TYPE (exp))
857         {
858         case SIGNED_INT:
859         case UNSIGNED_INT:
860         case SIGNED_CHAR:
861         case UNSIGNED_CHAR:
862           return 1;
863           
864         case VOID_TYPE:
865         default: 
866           gcc_unreachable ();
867         }
868       break;
869       
870     case VOID_TYPE:
871     default:
872       gcc_unreachable ();
873       
874     }
875 }
876
877 /* Make a production for an integer constant VALUE.  */
878
879 static struct prod_token_parm_item *
880 make_integer_constant (struct prod_token_parm_item* value)
881 {
882   struct prod_token_parm_item* tok;
883   struct prod_token_parm_item *prod;
884   tok = value;
885   prod = make_production (PROD_INTEGER_CONSTANT, tok);
886   if ((tok->tp.tok.chars[0] == (unsigned char)'-')
887       || (tok->tp.tok.chars[0] == (unsigned char)'+'))
888     NUMERIC_TYPE (prod) = SIGNED_INT;
889   else
890     NUMERIC_TYPE (prod) = UNSIGNED_INT;
891   prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
892                                                    tok->tp.tok.length);
893   return prod;
894 }
895
896
897 /* Build a PROD_PLUS_EXPRESSION.  This is uses for PLUS, MINUS, ASSIGN
898    and EQUALS expressions.  */
899
900 static struct prod_token_parm_item *
901 make_plus_expression (struct prod_token_parm_item* tok,
902                       struct prod_token_parm_item* op1,
903                       struct prod_token_parm_item* op2,
904                       int type_code, int prod_code)
905 {
906   struct prod_token_parm_item *prod;
907   tree type;
908
909   ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
910   ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
911
912   prod = make_production (PROD_PLUS_EXPRESSION, tok);
913
914   NUMERIC_TYPE (prod) = type_code;
915   type = tree_code_get_type (type_code);
916
917   gcc_assert (type);
918
919   OP1 (prod) = op1;
920   OP2 (prod) = op2;
921       
922   prod->tp.pro.code = tree_code_get_expression (prod_code, type,
923                                                 op1->tp.pro.code,
924                                                 op2->tp.pro.code, NULL,
925                                                 tok->tp.tok.location);
926
927   return prod;
928 }
929
930
931 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN.  */
932
933 static void
934 set_storage (struct prod_token_parm_item *prod)
935 {
936   struct prod_token_parm_item* stg_class;
937   stg_class = STORAGE_CLASS_TOKEN (prod);
938   switch (stg_class->type)
939     {
940     case STATIC:
941       STORAGE_CLASS (prod) = STATIC_STORAGE;
942       break;
943       
944     case AUTOMATIC:
945       STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
946       break;
947       
948     case EXTERNAL_DEFINITION:
949       STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
950       break;
951
952     case EXTERNAL_REFERENCE:
953       STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
954       break;
955
956     default:
957       gcc_unreachable ();
958     }
959 }
960
961 /* Set parse trace.  */
962
963 void
964 treelang_debug (void)
965 {
966   if (option_parser_trace)
967     yydebug = 1;
968 }
969
970 #ifdef __XGETTEXT__
971 /* Depending on the version of Bison used to compile this grammar,
972    it may issue generic diagnostics spelled "syntax error" or
973    "parse error".  To prevent this from changing the translation
974    template randomly, we list all the variants of this particular
975    diagnostic here.  Translators: there is no fine distinction
976    between diagnostics with "syntax error" in them, and diagnostics
977    with "parse error" in them.  It's okay to give them both the same
978    translation.  */
979 const char d1[] = N_("syntax error");
980 const char d2[] = N_("parse error");
981 const char d3[] = N_("syntax error; also virtual memory exhausted");
982 const char d4[] = N_("parse error; also virtual memory exhausted");
983 const char d5[] = N_("syntax error: cannot back up");
984 const char d6[] = N_("parse error: cannot back up");
985 #endif