Improve support for arm-wince-pe target:
[official-gcc.git] / gcc / treelang / parse.y
blob5222a885dcfa585541c58518fcd65cdfb3e7f891
1 %{ /* -*- c -*- emacs mode c */
2 /*
4 TREELANG Compiler parser.
6 ---------------------------------------------------------------------
8 Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
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.
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.
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.
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!
29 ---------------------------------------------------------------------
31 Written by Tim Josling 1999-2001, based in part on other parts of
32 the GCC compiler.
36 /*
38 Grammar Conflicts
39 *****************
41 There are no conflicts in this grammar. Please keep it that way.
45 #include "config.h"
46 #include "system.h"
47 #include "coretypes.h"
48 #include "tm.h"
49 #include "diagnostic.h"
50 #include "timevar.h"
52 #include "treelang.h"
53 #include "treetree.h"
55 #define YYDEBUG 1
56 #define YYPRINT(file, type, value) print_token (file, type, value)
57 #define YYERROR_VERBOSE YES
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 my_yylex ()
66 int res;
67 timevar_push (TV_LEX);
68 res = yylex ();
69 timevar_pop (TV_LEX);
70 return res;
72 #define yylex my_yylex
74 extern int option_parser_trace;
76 /* Local prototypes. */
78 static void yyerror (const char *error_message);
79 int yyparse (void);
80 void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value);
81 static struct prod_token_parm_item *reverse_prod_list (struct prod_token_parm_item *old_first);
82 static void ensure_not_void (unsigned int type, struct prod_token_parm_item* name);
83 static int check_type_match (int type_num, struct prod_token_parm_item *exp);
84 static int get_common_type (struct prod_token_parm_item *type1,
85 struct prod_token_parm_item *type2);
86 static struct prod_token_parm_item *make_integer_constant (struct prod_token_parm_item* value);
87 static struct prod_token_parm_item *make_plus_expression
88 (struct prod_token_parm_item* tok, struct prod_token_parm_item* op1,
89 struct prod_token_parm_item* op2, int type_code, int prod_code);
90 static void set_storage (struct prod_token_parm_item *prod);
92 /* File global variables. */
94 static struct prod_token_parm_item *current_function=NULL;
98 /* Not %raw - seems to have bugs. */
99 %token_table
101 /* Punctuation. */
102 %token RIGHT_BRACE
103 %token LEFT_BRACE
104 %token RIGHT_SQUARE_BRACKET
105 %token LEFT_SQUARE_BRACKET
106 %token RIGHT_PARENTHESIS
107 %token LEFT_PARENTHESIS
108 %token SEMICOLON
109 %token ASTERISK
110 %token COMMA
111 %right EQUALS
112 %right ASSIGN
113 %left tl_PLUS
114 %left tl_MINUS
116 /* Literals. */
117 %token INTEGER
119 /* Keywords. */
120 %token IF
121 %token ELSE
122 %token tl_RETURN
123 %token CHAR
124 %token INT
125 %token UNSIGNED
126 %token VOID
127 %token TYPEDEF
128 %token NAME
129 %token STATIC
130 %token AUTOMATIC
131 %token EXTERNAL_DEFINITION
132 %token EXTERNAL_REFERENCE
134 /* Tokens not passed to parser. */
135 %token WHITESPACE
136 %token COMMENT
138 /* Pseudo tokens - productions. */
139 %token PROD_VARIABLE_NAME
140 %token PROD_TYPE_NAME
141 %token PROD_FUNCTION_NAME
142 %token PROD_INTEGER_CONSTANT
143 %token PROD_PLUS_EXPRESSION
144 %token PROD_MINUS_EXPRESSION
145 %token PROD_ASSIGN_EXPRESSION
146 %token PROD_VARIABLE_REFERENCE_EXPRESSION
147 %token PROD_PARAMETER
148 %token PROD_FUNCTION_INVOCATION
149 %expect 0
152 file:
153 /* Nil. */ {
154 /* Nothing to do. */
156 |declarations {
157 /* Nothing to do. */
162 declarations:
163 declaration {
164 /* Nothing to do. */
166 | declarations declaration {
167 /* Nothing to do. */
171 declaration:
172 variable_def {
173 /* Nothing to do. */
175 |function_prototype {
176 /* Nothing to do. */
178 |function {
179 /* Nothing to do. */
183 variable_def:
184 storage typename NAME init_opt SEMICOLON {
185 struct prod_token_parm_item* tok;
186 struct prod_token_parm_item *prod;
187 tok = $3;
188 prod = make_production (PROD_VARIABLE_NAME, tok);
189 SYMBOL_TABLE_NAME (prod) = tok;
190 EXPRESSION_TYPE (prod) = $2;
191 VAR_INIT (prod) = $4;
192 NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
193 ensure_not_void (NUMERIC_TYPE (prod), tok);
194 if (insert_tree_name (prod))
196 YYERROR;
198 STORAGE_CLASS_TOKEN (prod) = $1;
199 set_storage (prod);
201 if (VAR_INIT (prod))
203 if (! ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code)
204 abort ();
205 if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
207 fprintf (stderr, "%s:%i:%i: External reference variables may not have initial value\n",
208 tok->tp.tok.location.file,
209 tok->tp.tok.location.line, tok->tp.tok.charno);
210 print_token (stderr, 0, tok);
211 errorcount++;
212 YYERROR;
215 prod->tp.pro.code = tree_code_create_variable
216 (STORAGE_CLASS (prod),
217 ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
218 ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
219 NUMERIC_TYPE (prod),
220 VAR_INIT (prod)? ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code:NULL,
221 tok->tp.tok.location);
222 if (!prod->tp.pro.code)
223 abort ();
227 storage:
228 STATIC
229 |AUTOMATIC
230 |EXTERNAL_DEFINITION
231 |EXTERNAL_REFERENCE
234 parameter:
235 typename NAME {
236 struct prod_token_parm_item* tok;
237 struct prod_token_parm_item *prod;
238 struct prod_token_parm_item *prod2;
239 tok = $2;
240 prod = make_production (PROD_VARIABLE_NAME, tok);
241 SYMBOL_TABLE_NAME (prod) = $2;
242 EXPRESSION_TYPE (prod) = $1;
243 NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
244 ensure_not_void (NUMERIC_TYPE (prod), tok);
245 if (insert_tree_name (prod))
247 YYERROR;
249 prod2 = make_production (PROD_PARAMETER, tok);
250 VARIABLE (prod2) = prod;
251 $$ = prod2;
255 function_prototype:
256 storage typename NAME LEFT_PARENTHESIS parameters RIGHT_PARENTHESIS SEMICOLON {
257 struct prod_token_parm_item* tok;
258 struct prod_token_parm_item *prod;
259 struct prod_token_parm_item *type;
260 struct prod_token_parm_item* first_parms;
261 struct prod_token_parm_item* last_parms;
262 struct prod_token_parm_item* this_parms;
263 struct prod_token_parm_item *this_parm;
264 struct prod_token_parm_item *this_parm_var;
265 tok = $3;
266 prod = make_production (PROD_FUNCTION_NAME, $3);
267 SYMBOL_TABLE_NAME (prod) = $3;
268 EXPRESSION_TYPE (prod) = $2;
269 NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
270 PARAMETERS (prod) = reverse_prod_list ($5);
271 insert_tree_name (prod);
272 STORAGE_CLASS_TOKEN (prod) = $1;
273 set_storage (prod);
274 switch (STORAGE_CLASS (prod))
276 case STATIC_STORAGE:
277 case EXTERNAL_DEFINITION_STORAGE:
278 break;
280 case AUTOMATIC_STORAGE:
281 fprintf (stderr, "%s:%i:%i: A function cannot be automatic\n",
282 tok->tp.tok.location.file,
283 tok->tp.tok.location.line, tok->tp.tok.charno);
284 print_token (stderr, 0, tok);
285 errorcount++;
286 YYERROR;
287 break;
289 default:
290 abort ();
292 type = EXPRESSION_TYPE (prod);
293 /* Create a parameter list in a non-front end specific format. */
294 for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
295 this_parm;
296 this_parm = this_parm->tp.pro.next)
298 if (this_parm->category != production_category)
299 abort ();
300 this_parm_var = VARIABLE (this_parm);
301 if (!this_parm_var)
302 abort ();
303 if (this_parm_var->category != production_category)
304 abort ();
305 this_parms = my_malloc (sizeof (struct prod_token_parm_item));
306 if (!this_parm_var->tp.pro.main_token)
307 abort ();
308 this_parms->tp.par.variable_name = this_parm_var->tp.pro.main_token->tp.tok.chars;
309 this_parms->category = parameter_category;
310 this_parms->type = NUMERIC_TYPE
311 (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
312 if (last_parms)
314 last_parms->tp.par.next = this_parms;
315 last_parms = this_parms;
317 else
319 first_parms = this_parms;
320 last_parms = this_parms;
322 this_parms->tp.par.where_to_put_var_tree =
323 & (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
325 FIRST_PARMS (prod) = first_parms;
327 prod->tp.pro.code = tree_code_create_function_prototype
328 (tok->tp.tok.chars, STORAGE_CLASS (prod), NUMERIC_TYPE (type),
329 first_parms, tok->tp.tok.location);
333 function:
334 NAME LEFT_BRACE {
335 struct prod_token_parm_item *proto;
336 struct prod_token_parm_item search_prod;
337 struct prod_token_parm_item* tok;
338 struct prod_token_parm_item *this_parm;
339 tok = $1;
340 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
341 search_prod.category = token_category;
342 current_function = proto = lookup_tree_name (&search_prod);
343 if (!proto)
345 fprintf (stderr, "%s:%i:%i: Function prototype not found\n",
346 tok->tp.tok.location.file,
347 tok->tp.tok.location.line, tok->tp.tok.charno);
348 print_token (stderr, 0, tok);
349 errorcount++;
350 YYERROR;
352 if (!proto->tp.pro.code)
353 abort ();
354 tree_code_create_function_initial
355 (proto->tp.pro.code, tok->tp.tok.location,
356 FIRST_PARMS (current_function));
358 /* Check all the parameters have code. */
359 for (this_parm = PARAMETERS (proto);
360 this_parm;
361 this_parm = this_parm->tp.pro.next)
363 if (! (struct prod_token_parm_item*)VARIABLE (this_parm))
364 abort ();
365 if (! (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code))
366 abort ();
369 variable_defs_opt statements_opt RIGHT_BRACE {
370 struct prod_token_parm_item* tok;
371 tok = $1;
372 tree_code_create_function_wrapup (tok->tp.tok.location);
373 current_function = NULL;
377 variable_defs_opt:
378 /* Nil. */ {
379 $$ = 0;
381 |variable_defs {
382 $$ = $1;
386 statements_opt:
387 /* Nil. */ {
388 $$ = 0;
390 |statements {
391 $$ = $1;
395 variable_defs:
396 variable_def {
397 /* Nothing to do. */
399 |variable_defs variable_def {
400 /* Nothing to do. */
404 typename:
405 INT {
406 struct prod_token_parm_item* tok;
407 struct prod_token_parm_item *prod;
408 tok = $1;
409 prod = make_production (PROD_TYPE_NAME, tok);
410 NUMERIC_TYPE (prod) = SIGNED_INT;
411 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
412 $$ = prod;
414 |UNSIGNED INT {
415 struct prod_token_parm_item* tok;
416 struct prod_token_parm_item *prod;
417 tok = $1;
418 prod = make_production (PROD_TYPE_NAME, tok);
419 NUMERIC_TYPE (prod) = UNSIGNED_INT;
420 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
421 $$ = prod;
423 |CHAR {
424 struct prod_token_parm_item* tok;
425 struct prod_token_parm_item *prod;
426 tok = $1;
427 prod = make_production (PROD_TYPE_NAME, tok);
428 NUMERIC_TYPE (prod) = SIGNED_CHAR;
429 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
430 $$ = prod;
432 |UNSIGNED CHAR {
433 struct prod_token_parm_item* tok;
434 struct prod_token_parm_item *prod;
435 tok = $1;
436 prod = make_production (PROD_TYPE_NAME, tok);
437 NUMERIC_TYPE (prod) = UNSIGNED_CHAR;
438 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
439 $$ = prod;
441 |VOID {
442 struct prod_token_parm_item* tok;
443 struct prod_token_parm_item *prod;
444 tok = $1;
445 prod = make_production (PROD_TYPE_NAME, tok);
446 NUMERIC_TYPE (prod) = VOID_TYPE;
447 prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
448 $$ = prod;
452 parameters:
453 parameter {
454 /* Nothing to do. */
455 $$ = $1;
457 |parameters COMMA parameter {
458 struct prod_token_parm_item *prod1;
459 prod1 = $3;
460 prod1->tp.pro.next = $1; /* Insert in reverse order. */
461 $$ = prod1;
465 statements:
466 statement {
467 /* Nothing to do. */
469 |statements statement {
470 /* Nothing to do. */
474 statement:
475 expression SEMICOLON {
476 struct prod_token_parm_item *exp;
477 exp = $1;
478 tree_code_output_expression_statement (exp->tp.pro.code,
479 exp->tp.pro.main_token->tp.tok.location);
481 |return SEMICOLON {
482 /* Nothing to do. */
484 |if_statement {
485 /* Nothing to do. */
489 if_statement:
490 IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
491 struct prod_token_parm_item* tok;
492 struct prod_token_parm_item *exp;
493 tok = $1;
494 exp = $3;
495 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
496 tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
498 LEFT_BRACE statements_opt RIGHT_BRACE {
499 /* Just let the statements flow. */
501 ELSE {
502 struct prod_token_parm_item* tok;
503 tok = $1;
504 tree_code_if_else (tok->tp.tok.location);
506 LEFT_BRACE statements_opt RIGHT_BRACE {
507 struct prod_token_parm_item* tok;
508 tok = $12;
509 tree_code_if_end (tok->tp.tok.location);
514 return:
515 tl_RETURN expression_opt {
516 struct prod_token_parm_item *type_prod;
517 struct prod_token_parm_item* ret_tok;
518 ret_tok = $1;
519 type_prod = EXPRESSION_TYPE (current_function);
520 if (NUMERIC_TYPE (type_prod) == VOID)
521 if ($2 == NULL)
522 tree_code_generate_return (type_prod->tp.pro.code, NULL);
523 else
525 fprintf (stderr, "%s:%i:%i: Redundant expression in return\n",
526 ret_tok->tp.tok.location.file,
527 ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno);
528 print_token (stderr, 0, ret_tok);
529 errorcount++;
530 tree_code_generate_return (type_prod->tp.pro.code, NULL);
532 else
533 if ($2 == NULL)
535 fprintf (stderr, "%s:%i:%i: Expression missing in return\n",
536 ret_tok->tp.tok.location.file,
537 ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno);
538 print_token (stderr, 0, ret_tok);
539 errorcount++;
541 else
543 struct prod_token_parm_item *exp;
544 exp = $2;
545 /* Check same type. */
546 if (check_type_match (NUMERIC_TYPE (type_prod), $2))
548 if (!type_prod->tp.pro.code)
549 abort ();
550 if (!exp->tp.pro.code)
551 abort ();
552 /* Generate the code. */
553 tree_code_generate_return (type_prod->tp.pro.code, exp->tp.pro.code);
559 expression_opt:
560 /* Nil. */ {
561 $$ = 0;
563 |expression {
564 struct prod_token_parm_item *exp;
565 exp = $1;
566 if (!exp->tp.pro.code)
567 abort ();
569 $$ = $1;
573 expression:
574 INTEGER {
575 $$ = make_integer_constant ($1);
577 |variable_ref {
578 $$ = $1;
580 |expression tl_PLUS expression {
581 struct prod_token_parm_item *tok = $2;
582 struct prod_token_parm_item *op1 = $1;
583 struct prod_token_parm_item *op2 = $3;
584 int type_code = get_common_type (op1, op2);
585 if (!type_code)
586 YYERROR;
587 $$ = make_plus_expression
588 (tok, op1, op2, type_code, EXP_PLUS);
590 |expression tl_MINUS expression %prec tl_PLUS {
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 = get_common_type (op1, op2);
595 if (!type_code)
596 YYERROR;
597 $$ = make_plus_expression
598 (tok, op1, op2, type_code, EXP_MINUS);
600 |expression EQUALS 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 $$ = make_plus_expression
605 (tok, op1, op2, SIGNED_INT, EXP_EQUALS);
607 |variable_ref ASSIGN expression {
608 struct prod_token_parm_item *tok = $2;
609 struct prod_token_parm_item *op1 = $1;
610 struct prod_token_parm_item *op2 = $3;
611 int type_code = NUMERIC_TYPE (op1);
612 if (!type_code)
613 YYERROR;
614 $$ = make_plus_expression
615 (tok, op1, op2, type_code, EXP_ASSIGN);
617 |function_invocation {
618 $$ = $1;
622 function_invocation:
623 NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
624 struct prod_token_parm_item *prod;
625 struct prod_token_parm_item* tok;
626 struct prod_token_parm_item search_prod;
627 struct prod_token_parm_item *proto;
628 struct prod_token_parm_item *exp;
629 struct prod_token_parm_item *exp_proto;
630 struct prod_token_parm_item *var;
631 int exp_proto_count;
632 int exp_count;
633 tree parms;
634 tree type;
636 tok = $1;
637 prod = make_production (PROD_FUNCTION_INVOCATION, tok);
638 SYMBOL_TABLE_NAME (prod) = tok;
639 PARAMETERS (prod) = reverse_prod_list ($3);
640 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
641 search_prod.category = token_category;
642 proto = lookup_tree_name (&search_prod);
643 if (!proto)
645 fprintf (stderr, "%s:%i:%i: Function prototype not found\n",
646 tok->tp.tok.location.file,
647 tok->tp.tok.location.line, tok->tp.tok.charno);
648 print_token (stderr, 0, tok);
649 errorcount++;
650 YYERROR;
652 EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
653 NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
654 /* Count the expressions and ensure they match the prototype. */
655 for (exp_proto_count = 0, exp_proto = PARAMETERS (proto);
656 exp_proto; exp_proto = exp_proto->tp.pro.next)
657 exp_proto_count++;
659 for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
660 exp_count++;
662 if (exp_count != exp_proto_count)
664 fprintf (stderr, "%s:%i:%i: expression count mismatch with prototype\n",
665 tok->tp.tok.location.file,
666 tok->tp.tok.location.line, tok->tp.tok.charno);
667 print_token (stderr, 0, tok);
668 errorcount++;
669 YYERROR;
671 parms = tree_code_init_parameters ();
672 for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
673 exp_proto;
674 exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
676 if (!exp)
677 abort ();
678 if (!exp_proto)
679 abort ();
680 if (!exp->tp.pro.code)
681 abort ();
682 var = VARIABLE (exp_proto);
683 if (!var)
684 abort ();
685 if (!var->tp.pro.code)
686 abort ();
687 parms = tree_code_add_parameter (parms, var->tp.pro.code, exp->tp.pro.code);
689 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
690 prod->tp.pro.code = tree_code_get_expression
691 (EXP_FUNCTION_INVOCATION, type, proto->tp.pro.code, parms, NULL);
692 $$ = prod;
696 expressions_with_commas:
697 expression {
698 struct prod_token_parm_item *exp;
699 exp = $1;
700 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
701 $$ = $1;
703 |expressions_with_commas COMMA expression {
704 struct prod_token_parm_item *exp;
705 exp = $3;
706 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
707 exp->tp.pro.next = $1; /* Reverse order. */
708 $$ = exp;
712 variable_ref:
713 NAME {
714 struct prod_token_parm_item search_prod;
715 struct prod_token_parm_item *prod;
716 struct prod_token_parm_item *symbol_table_entry;
717 struct prod_token_parm_item* tok;
718 tree type;
720 tok = $1;
721 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
722 search_prod.category = token_category;
723 symbol_table_entry = lookup_tree_name (&search_prod);
724 if (!symbol_table_entry)
726 fprintf (stderr, "%s:%i:%i: Variable referred to but not defined\n",
727 tok->tp.tok.location.file,
728 tok->tp.tok.location.line, tok->tp.tok.charno);
729 print_token (stderr, 0, tok);
730 errorcount++;
731 YYERROR;
734 prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
735 NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
736 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
737 if (!NUMERIC_TYPE (prod))
738 YYERROR;
739 OP1 (prod) = $1;
741 prod->tp.pro.code = tree_code_get_expression (EXP_REFERENCE, type,
742 symbol_table_entry->tp.pro.code, NULL, NULL);
743 $$ = prod;
747 init_opt:
748 /* Nil. */ {
749 $$ = 0;
751 |init {
752 /* Nothing to do. */
755 init:
756 ASSIGN init_element {
760 init_element:
761 INTEGER {
762 $$ = make_integer_constant ($1);
768 /* Print a token VALUE to file FILE. Ignore TYPE which is the token
769 type. */
771 void
772 print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
774 struct prod_token_parm_item *tok;
775 unsigned int ix;
777 tok = value;
778 fprintf (file, "%d \"", tok->tp.tok.location.line);
779 for (ix = 0; ix < tok->tp.tok.length; ix++)
780 fprintf (file, "%c", tok->tp.tok.chars[ix]);
781 fprintf (file, "\"");
784 /* Output a message ERROR_MESSAGE from the parser. */
785 void
786 yyerror (const char *error_message)
788 struct prod_token_parm_item *tok;
790 tok = yylval;
791 if (tok)
793 fprintf (stderr, "%s:%i:%i: %s\n", tok->tp.tok.location.file,
794 tok->tp.tok.location.line, tok->tp.tok.charno, error_message);
795 print_token (stderr, 0, tok);
797 else
798 fprintf (stderr, "%s\n", error_message);
800 errorcount++;
804 /* Reverse the order of a token list, linked by parse_next, old first
805 token is OLD_FIRST. */
807 static struct prod_token_parm_item*
808 reverse_prod_list (struct prod_token_parm_item *old_first)
810 struct prod_token_parm_item *current;
811 struct prod_token_parm_item *next;
812 struct prod_token_parm_item *prev = NULL;
814 current = old_first;
815 prev = NULL;
817 while (current)
819 if (current->category != production_category)
820 abort ();
821 next = current->tp.pro.next;
822 current->tp.pro.next = prev;
823 prev = current;
824 current = next;
826 return prev;
829 /* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
831 static void
832 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
834 if (type == VOID)
836 fprintf (stderr, "%s:%i:%i: Type must not be void in this context\n",
837 name->tp.tok.location.file,
838 name->tp.tok.location.line, name->tp.tok.charno);
839 print_token (stderr, 0, name);
840 errorcount++;
844 /* Check TYPE1 and TYPE2 which are integral types. Return the lowest
845 common type (min is signed int). */
847 static int
848 get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2)
850 if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
851 return UNSIGNED_INT;
852 if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
853 return UNSIGNED_INT;
855 return SIGNED_INT;
858 /* Check type (TYPE_NUM) and expression (EXP) match. Return the 1 if
859 OK else 0. Must be exact match - same name unless it is an
860 integral type. */
862 static int
863 check_type_match (int type_num, struct prod_token_parm_item *exp)
865 switch (type_num)
867 case SIGNED_INT:
868 case UNSIGNED_INT:
869 case SIGNED_CHAR:
870 case UNSIGNED_CHAR:
871 switch (NUMERIC_TYPE (exp))
873 case SIGNED_INT:
874 case UNSIGNED_INT:
875 case SIGNED_CHAR:
876 case UNSIGNED_CHAR:
877 return 1;
879 case VOID:
880 abort ();
882 default:
883 abort ();
885 break;
887 case VOID:
888 abort ();
890 default:
891 abort ();
896 /* Make a production for an integer constant VALUE. */
898 static struct prod_token_parm_item *
899 make_integer_constant (struct prod_token_parm_item* value)
901 struct prod_token_parm_item* tok;
902 struct prod_token_parm_item *prod;
903 tok = value;
904 prod = make_production (PROD_INTEGER_CONSTANT, tok);
905 if ((tok->tp.tok.chars[0] == (unsigned char)'-')|| (tok->tp.tok.chars[0] == (unsigned char)'+'))
906 NUMERIC_TYPE (prod) = SIGNED_INT;
907 else
908 NUMERIC_TYPE (prod) = UNSIGNED_INT;
909 prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars, tok->tp.tok.length);
910 return prod;
914 /* Build a PROD_PLUS_EXPRESSION. This is uses for PLUS, MINUS, ASSIGN
915 and EQUALS expressions. */
917 static struct prod_token_parm_item *
918 make_plus_expression (struct prod_token_parm_item* tok,
919 struct prod_token_parm_item* op1,
920 struct prod_token_parm_item* op2,
921 int type_code, int prod_code)
923 struct prod_token_parm_item *prod;
924 tree type;
926 ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
927 ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
929 prod = make_production (PROD_PLUS_EXPRESSION, tok);
931 NUMERIC_TYPE (prod) = type_code;
932 type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
933 if (!type)
934 abort ();
935 OP1 (prod) = op1;
936 OP2 (prod) = op2;
938 prod->tp.pro.code = tree_code_get_expression
939 (prod_code, type, op1->tp.pro.code,
940 op2->tp.pro.code, NULL);
942 return prod;
946 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
948 static void
949 set_storage (struct prod_token_parm_item *prod)
951 struct prod_token_parm_item* stg_class;
952 stg_class = STORAGE_CLASS_TOKEN (prod);
953 switch (stg_class->type)
955 case STATIC:
956 STORAGE_CLASS (prod) = STATIC_STORAGE;
957 break;
959 case AUTOMATIC:
960 STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
961 break;
963 case EXTERNAL_DEFINITION:
964 STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
965 break;
967 case EXTERNAL_REFERENCE:
968 STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
969 break;
971 default:
972 abort ();
976 /* Set parse trace. */
978 void
979 treelang_debug (void)
981 if (option_parser_trace)
982 yydebug = 1;