OSDN Git Service

2005-06-07 Jerry DeLisle <jvdelisle@verizon.net>
[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 "timevar.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*)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
455 parameters:
456 parameter {
457   /* Nothing to do.  */
458   $$ = $1;
459 }
460 |parameters COMMA parameter {
461   struct prod_token_parm_item *prod1;
462   prod1 = $3;
463   prod1->tp.pro.next = $1; /* Insert in reverse order.  */
464   $$ = prod1;
465 }
466 ;
467
468 statements:
469 statement {
470   /* Nothing to do.  */
471 }
472 |statements statement {
473   /* Nothing to do.  */
474 }
475 ;
476
477 statement:
478 expression SEMICOLON {
479   struct prod_token_parm_item *exp;
480   exp = $1;
481   tree_code_output_expression_statement (exp->tp.pro.code,
482                                          exp->tp.pro.main_token->tp.tok.location);
483 }
484 |return SEMICOLON {
485   /* Nothing to do.  */
486 }
487 |if_statement {
488   /* Nothing to do.  */
489 }
490 ;
491
492 if_statement:
493 IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
494   struct prod_token_parm_item* tok;
495   struct prod_token_parm_item *exp;
496   tok = $1;
497   exp = $3;
498   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
499   tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
500 }
501 LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
502   /* Just let the statements flow.  */
503 }
504 ELSE {
505   struct prod_token_parm_item* tok;
506   tok = $1;
507   tree_code_if_else (tok->tp.tok.location);
508 }
509 LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
510   struct prod_token_parm_item* tok;
511   tok = $1;
512   tree_code_if_end (tok->tp.tok.location);
513 }
514 ;
515
516
517 return:
518 tl_RETURN expression_opt {
519   struct prod_token_parm_item *type_prod;
520   struct prod_token_parm_item *ret_tok = $1;
521   struct prod_token_parm_item *exp = $2;
522
523   type_prod = EXPRESSION_TYPE (current_function);
524   if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
525     if (exp == NULL)
526       tree_code_generate_return (type_prod->tp.pro.code, NULL);
527     else
528       {
529         warning (0, "%HRedundant expression in return.",
530                  &ret_tok->tp.tok.location, ret_tok->tp.tok.length,
531                  ret_tok->tp.tok.chars);
532         tree_code_generate_return (type_prod->tp.pro.code, NULL);
533        }
534   else
535     if (exp == NULL)
536         error ("%HExpression missing in return.", &ret_tok->tp.tok.location);
537     else
538       {
539         /* Check same type.  */
540         if (check_type_match (NUMERIC_TYPE (type_prod), exp))
541           {
542             gcc_assert (type_prod->tp.pro.code);
543             gcc_assert (exp->tp.pro.code);
544
545             /* Generate the code. */
546             tree_code_generate_return (type_prod->tp.pro.code,
547                                        exp->tp.pro.code);
548           }
549       }
550 }
551 ;
552
553 expression_opt:
554 /* Nil.  */ {
555   $$ = 0;
556 }
557 |expression {
558   struct prod_token_parm_item *exp;
559   exp = $1;
560   gcc_assert (exp->tp.pro.code);
561   
562   $$ = $1;
563 }
564 ;
565
566 expression:
567 INTEGER {
568   $$ = make_integer_constant ($1);
569 }
570 |variable_ref {
571   $$ = $1;
572 }
573 |expression tl_PLUS expression {
574   struct prod_token_parm_item *tok = $2;
575   struct prod_token_parm_item *op1 = $1;
576   struct prod_token_parm_item *op2 = $3;
577   int type_code = get_common_type (op1, op2);
578   if (!type_code)
579     YYERROR;
580   $$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
581 }
582 |expression tl_MINUS expression %prec tl_PLUS {
583   struct prod_token_parm_item *tok = $2;
584   struct prod_token_parm_item *op1 = $1;
585   struct prod_token_parm_item *op2 = $3;
586   int type_code = get_common_type (op1, op2);
587   if (!type_code)
588     YYERROR;
589   $$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
590 }
591 |expression EQUALS expression {
592   struct prod_token_parm_item *tok = $2;
593   struct prod_token_parm_item *op1 = $1;
594   struct prod_token_parm_item *op2 = $3;
595   int type_code = NUMERIC_TYPE (op1);
596   if (!type_code)
597     YYERROR;
598   $$ = make_plus_expression
599      (tok, op1, op2, type_code, EXP_EQUALS);
600 }
601 |variable_ref ASSIGN expression {
602   struct prod_token_parm_item *tok = $2;
603   struct prod_token_parm_item *op1 = $1;
604   struct prod_token_parm_item *op2 = $3;
605   int type_code = NUMERIC_TYPE (op1);
606   if (!type_code)
607     YYERROR;
608   $$ = make_plus_expression
609      (tok, op1, op2, type_code, EXP_ASSIGN);
610 }
611 |function_invocation {
612   $$ = $1;
613 }
614 ;
615
616 function_invocation:
617 NAME LEFT_PARENTHESIS expressions_with_commas_opt RIGHT_PARENTHESIS {
618   struct prod_token_parm_item *prod;
619   struct prod_token_parm_item* tok;
620   struct prod_token_parm_item search_prod;
621   struct prod_token_parm_item *proto;
622   struct prod_token_parm_item *exp;
623   struct prod_token_parm_item *exp_proto;
624   struct prod_token_parm_item *var;
625   int exp_proto_count;
626   int exp_count;
627   tree parms;
628   tree type;
629   
630   tok = $1;
631   prod = make_production (PROD_FUNCTION_INVOCATION, tok);
632   SYMBOL_TABLE_NAME (prod) = tok;
633   PARAMETERS (prod) = reverse_prod_list ($3);
634   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
635   search_prod.category = token_category;
636   proto = lookup_tree_name (&search_prod);
637   if (!proto)
638     {
639       error ("%HFunction prototype not found for %q.*%s.",
640              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
641       YYERROR;
642     }
643   EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
644   NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
645   /* Count the expressions and ensure they match the prototype.  */
646   for (exp_proto_count = 0, exp_proto = PARAMETERS (proto); 
647        exp_proto; exp_proto = exp_proto->tp.pro.next)
648     exp_proto_count++;
649
650   for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
651     exp_count++;
652
653   if (exp_count !=  exp_proto_count)
654     {
655       error ("%HExpression count mismatch %q.*s with prototype.",
656              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
657       YYERROR;
658     }
659   parms = tree_code_init_parameters ();
660   for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
661        exp_proto;
662        exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
663     {
664       gcc_assert (exp);
665       gcc_assert (exp_proto);
666       gcc_assert (exp->tp.pro.code);
667
668       var = VARIABLE (exp_proto);
669
670       gcc_assert (var);
671       gcc_assert (var->tp.pro.code);
672
673       parms = tree_code_add_parameter (parms, var->tp.pro.code,
674                                        exp->tp.pro.code);
675     }
676   type = tree_code_get_type (NUMERIC_TYPE (prod));
677   prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
678                                                 proto->tp.pro.code, parms,
679                                                 NULL, tok->tp.tok.location);
680   $$ = prod;
681 }
682 ;
683
684 expressions_with_commas_opt: 
685 /* Nil.  */ {
686 $$ = 0
687 }
688 |expressions_with_commas { $$ = $1 }
689 ;
690
691 expressions_with_commas:
692 expression {
693   struct prod_token_parm_item *exp;
694   exp = $1;
695   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
696   $$ = $1;
697 }
698 |expressions_with_commas COMMA expression {
699   struct prod_token_parm_item *exp;
700   exp = $3;
701   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
702   exp->tp.pro.next = $1; /* Reverse order.  */
703   $$ = exp;
704 }
705 ;
706
707 variable_ref:
708 NAME {
709   struct prod_token_parm_item search_prod;
710   struct prod_token_parm_item *prod;
711   struct prod_token_parm_item *symbol_table_entry;
712   struct prod_token_parm_item* tok;
713   tree type;
714
715   tok = $1;
716   SYMBOL_TABLE_NAME ((&search_prod)) = tok;
717   search_prod.category = token_category;
718   symbol_table_entry = lookup_tree_name (&search_prod);
719   if (!symbol_table_entry)
720     {
721       error ("%HVariable %q.*s not defined.",
722              &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
723       YYERROR;
724     }
725
726   prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
727   NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
728   type = tree_code_get_type (NUMERIC_TYPE (prod));
729   if (!NUMERIC_TYPE (prod))
730     YYERROR;
731   OP1 (prod) = $1;
732   
733   prod->tp.pro.code =
734     tree_code_get_expression (EXP_REFERENCE, type,
735                               symbol_table_entry->tp.pro.code, NULL, NULL,
736                               tok->tp.tok.location);
737   $$ = prod;
738 }
739 ;
740
741 init_opt:
742 /* Nil.  */ {
743   $$ = 0;
744 }
745 |init {
746   /* Pass the initialization value up.  */
747   $$ = $1;
748 };
749
750 init:
751 ASSIGN init_element {
752   $$ = $2;
753 }
754 ;
755
756 init_element:
757 INTEGER {
758   $$ = make_integer_constant ($1);
759 }
760 ;
761
762 %%
763
764 /* Print a token VALUE to file FILE.  Ignore TYPE which is the token
765    type. */
766
767 void
768 print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value) 
769 {
770   struct prod_token_parm_item *tok;
771   unsigned int  ix;
772
773   tok  =  value;
774   fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
775   for (ix  =  0; ix < tok->tp.tok.length; ix++)
776     fprintf (file, "%c", tok->tp.tok.chars[ix]);
777
778   fprintf (file, "\"");
779 }
780
781 /* Output a message ERROR_MESSAGE from the parser.  */
782 static void
783 yyerror (const char *error_message)
784 {
785   struct prod_token_parm_item *tok;
786
787   tok = yylval;
788   if (tok)
789     error ("%H%s", &tok->tp.tok.location, error_message);
790   else
791     error ("%s", error_message);
792 }
793
794 /* Reverse the order of a token list, linked by parse_next, old first
795    token is OLD_FIRST.  */
796
797 static struct prod_token_parm_item*
798 reverse_prod_list (struct prod_token_parm_item *old_first)
799 {
800   struct prod_token_parm_item *current;
801   struct prod_token_parm_item *next;
802   struct prod_token_parm_item *prev = NULL;
803   
804   current = old_first;
805   prev = NULL;
806
807   while (current) 
808     {
809       gcc_assert (current->category == production_category);
810
811       next = current->tp.pro.next;
812       current->tp.pro.next = prev;
813       prev = current;
814       current = next; 
815     }
816   return prev;
817 }
818
819 /* Ensure TYPE is not VOID. Use NAME as the token for the error location.  */
820
821 static void
822 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
823 {
824   if (type == VOID_TYPE)
825     error ("%HType must not be void in this context.",
826            &name->tp.tok.location);
827 }
828
829 /* Check TYPE1 and TYPE2 which are integral types.  Return the lowest
830    common type (min is signed int).  */
831
832 static int 
833 get_common_type (struct prod_token_parm_item *type1,
834                  struct prod_token_parm_item *type2)
835 {
836   if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
837     return UNSIGNED_INT;
838   if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
839     return UNSIGNED_INT;
840
841   return SIGNED_INT;
842 }
843
844 /* Check type (TYPE_NUM) and expression (EXP) match.  Return the 1 if
845    OK else 0.  Must be exact match - same name unless it is an
846    integral type.  */
847
848 static int 
849 check_type_match (int type_num, struct prod_token_parm_item *exp)
850 {
851   switch (type_num)
852     {
853     case SIGNED_INT:
854     case UNSIGNED_INT:
855     case SIGNED_CHAR:
856     case UNSIGNED_CHAR:
857       switch (NUMERIC_TYPE (exp))
858         {
859         case SIGNED_INT:
860         case UNSIGNED_INT:
861         case SIGNED_CHAR:
862         case UNSIGNED_CHAR:
863           return 1;
864           
865         case VOID_TYPE:
866         default: 
867           gcc_unreachable ();
868         }
869       break;
870       
871     case VOID_TYPE:
872     default:
873       gcc_unreachable ();
874       
875     }
876 }
877
878 /* Make a production for an integer constant VALUE.  */
879
880 static struct prod_token_parm_item *
881 make_integer_constant (struct prod_token_parm_item* value)
882 {
883   struct prod_token_parm_item* tok;
884   struct prod_token_parm_item *prod;
885   tok = value;
886   prod = make_production (PROD_INTEGER_CONSTANT, tok);
887   if ((tok->tp.tok.chars[0] == (unsigned char)'-')
888       || (tok->tp.tok.chars[0] == (unsigned char)'+'))
889     NUMERIC_TYPE (prod) = SIGNED_INT;
890   else
891     NUMERIC_TYPE (prod) = UNSIGNED_INT;
892   prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
893                                                    tok->tp.tok.length);
894   return prod;
895 }
896
897
898 /* Build a PROD_PLUS_EXPRESSION.  This is uses for PLUS, MINUS, ASSIGN
899    and EQUALS expressions.  */
900
901 static struct prod_token_parm_item *
902 make_plus_expression (struct prod_token_parm_item* tok,
903                       struct prod_token_parm_item* op1,
904                       struct prod_token_parm_item* op2,
905                       int type_code, int prod_code)
906 {
907   struct prod_token_parm_item *prod;
908   tree type;
909
910   ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
911   ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
912
913   prod = make_production (PROD_PLUS_EXPRESSION, tok);
914
915   NUMERIC_TYPE (prod) = type_code;
916   type = tree_code_get_type (type_code);
917
918   gcc_assert (type);
919
920   OP1 (prod) = op1;
921   OP2 (prod) = op2;
922       
923   prod->tp.pro.code = tree_code_get_expression (prod_code, type,
924                                                 op1->tp.pro.code,
925                                                 op2->tp.pro.code, NULL,
926                                                 tok->tp.tok.location);
927
928   return prod;
929 }
930
931
932 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN.  */
933
934 static void
935 set_storage (struct prod_token_parm_item *prod)
936 {
937   struct prod_token_parm_item* stg_class;
938   stg_class = STORAGE_CLASS_TOKEN (prod);
939   switch (stg_class->type)
940     {
941     case STATIC:
942       STORAGE_CLASS (prod) = STATIC_STORAGE;
943       break;
944       
945     case AUTOMATIC:
946       STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
947       break;
948       
949     case EXTERNAL_DEFINITION:
950       STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
951       break;
952
953     case EXTERNAL_REFERENCE:
954       STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
955       break;
956
957     default:
958       gcc_unreachable ();
959     }
960 }
961
962 /* Set parse trace.  */
963
964 void
965 treelang_debug (void)
966 {
967   if (option_parser_trace)
968     yydebug = 1;
969 }
970
971 #ifdef __XGETTEXT__
972 /* Depending on the version of Bison used to compile this grammar,
973    it may issue generic diagnostics spelled "syntax error" or
974    "parse error".  To prevent this from changing the translation
975    template randomly, we list all the variants of this particular
976    diagnostic here.  Translators: there is no fine distinction
977    between diagnostics with "syntax error" in them, and diagnostics
978    with "parse error" in them.  It's okay to give them both the same
979    translation.  */
980 const char d1[] = N_("syntax error");
981 const char d2[] = N_("parse error");
982 const char d3[] = N_("syntax error; also virtual memory exhausted");
983 const char d4[] = N_("parse error; also virtual memory exhausted");
984 const char d5[] = N_("syntax error: cannot back up");
985 const char d6[] = N_("parse error: cannot back up");
986 #endif