OSDN Git Service

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