2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / treelang / parse.y
blobf0f721d554536eae3f11cafc188836e7b2153d45
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
65 my_yylex (void)
67 int res;
68 timevar_push (TV_LEX);
69 res = yylex ();
70 timevar_pop (TV_LEX);
71 return res;
73 #define yylex my_yylex
75 extern int option_parser_trace;
77 /* Local prototypes. */
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);
93 /* File global variables. */
95 static struct prod_token_parm_item *current_function=NULL;
99 /* Not %raw - seems to have bugs. */
100 %token_table
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
117 /* Literals. */
118 %token INTEGER
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
135 /* Tokens not passed to parser. */
136 %token WHITESPACE
137 %token COMMENT
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
153 file:
154 /* Nil. */ {
155 /* Nothing to do. */
157 |declarations {
158 /* Nothing to do. */
163 declarations:
164 declaration {
165 /* Nothing to do. */
167 | declarations declaration {
168 /* Nothing to do. */
172 declaration:
173 variable_def {
174 /* Nothing to do. */
176 |function_prototype {
177 /* Nothing to do. */
179 |function {
180 /* Nothing to do. */
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))
197 YYERROR;
199 STORAGE_CLASS_TOKEN (prod) = $1;
200 set_storage (prod);
202 if (VAR_INIT (prod))
204 if (! ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code)
205 abort ();
206 if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
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;
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 ();
228 storage:
229 STATIC
230 |AUTOMATIC
231 |EXTERNAL_DEFINITION
232 |EXTERNAL_REFERENCE
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))
248 YYERROR;
250 prod2 = make_production (PROD_PARAMETER, tok);
251 VARIABLE (prod2) = prod;
252 $$ = prod2;
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))
277 case STATIC_STORAGE:
278 case EXTERNAL_DEFINITION_STORAGE:
279 break;
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;
290 default:
291 abort ();
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)
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)
315 last_parms->tp.par.next = this_parms;
316 last_parms = this_parms;
318 else
320 first_parms = this_parms;
321 last_parms = this_parms;
323 this_parms->tp.par.where_to_put_var_tree =
324 & (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
326 FIRST_PARMS (prod) = first_parms;
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);
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)
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;
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));
359 /* Check all the parameters have code. */
360 for (this_parm = PARAMETERS (proto);
361 this_parm;
362 this_parm = this_parm->tp.pro.next)
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 ();
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;
378 variable_defs_opt:
379 /* Nil. */ {
380 $$ = 0;
382 |variable_defs {
383 $$ = $1;
387 statements_opt:
388 /* Nil. */ {
389 $$ = 0;
391 |statements {
392 $$ = $1;
396 variable_defs:
397 variable_def {
398 /* Nothing to do. */
400 |variable_defs variable_def {
401 /* Nothing to do. */
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;
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;
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;
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;
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;
453 parameters:
454 parameter {
455 /* Nothing to do. */
456 $$ = $1;
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;
466 statements:
467 statement {
468 /* Nothing to do. */
470 |statements statement {
471 /* Nothing to do. */
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);
482 |return SEMICOLON {
483 /* Nothing to do. */
485 |if_statement {
486 /* Nothing to do. */
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);
499 LEFT_BRACE statements_opt RIGHT_BRACE {
500 /* Just let the statements flow. */
502 ELSE {
503 struct prod_token_parm_item* tok;
504 tok = $1;
505 tree_code_if_else (tok->tp.tok.location);
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);
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
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);
533 else
534 if ($2 == NULL)
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++;
542 else
544 struct prod_token_parm_item *exp;
545 exp = $2;
546 /* Check same type. */
547 if (check_type_match (NUMERIC_TYPE (type_prod), $2))
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);
560 expression_opt:
561 /* Nil. */ {
562 $$ = 0;
564 |expression {
565 struct prod_token_parm_item *exp;
566 exp = $1;
567 if (!exp->tp.pro.code)
568 abort ();
570 $$ = $1;
574 expression:
575 INTEGER {
576 $$ = make_integer_constant ($1);
578 |variable_ref {
579 $$ = $1;
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);
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);
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);
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);
618 |function_invocation {
619 $$ = $1;
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;
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)
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;
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++;
660 for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
661 exp_count++;
663 if (exp_count != exp_proto_count)
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;
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)
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);
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;
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;
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;
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;
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)
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;
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;
742 prod->tp.pro.code = tree_code_get_expression (EXP_REFERENCE, type,
743 symbol_table_entry->tp.pro.code, NULL, NULL);
744 $$ = prod;
748 init_opt:
749 /* Nil. */ {
750 $$ = 0;
752 |init {
753 /* Nothing to do. */
756 init:
757 ASSIGN init_element {
761 init_element:
762 INTEGER {
763 $$ = make_integer_constant ($1);
769 /* Print a token VALUE to file FILE. Ignore TYPE which is the token
770 type. */
772 void
773 print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
775 struct prod_token_parm_item *tok;
776 unsigned int ix;
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, "\"");
785 /* Output a message ERROR_MESSAGE from the parser. */
786 void
787 yyerror (const char *error_message)
789 struct prod_token_parm_item *tok;
791 tok = yylval;
792 if (tok)
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);
798 else
799 fprintf (stderr, "%s\n", error_message);
801 errorcount++;
805 /* Reverse the order of a token list, linked by parse_next, old first
806 token is OLD_FIRST. */
808 static struct prod_token_parm_item*
809 reverse_prod_list (struct prod_token_parm_item *old_first)
811 struct prod_token_parm_item *current;
812 struct prod_token_parm_item *next;
813 struct prod_token_parm_item *prev = NULL;
815 current = old_first;
816 prev = NULL;
818 while (current)
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;
827 return prev;
830 /* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
832 static void
833 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
835 if (type == VOID)
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++;
845 /* Check TYPE1 and TYPE2 which are integral types. Return the lowest
846 common type (min is signed int). */
848 static int
849 get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2)
851 if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
852 return UNSIGNED_INT;
853 if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
854 return UNSIGNED_INT;
856 return SIGNED_INT;
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. */
863 static int
864 check_type_match (int type_num, struct prod_token_parm_item *exp)
866 switch (type_num)
868 case SIGNED_INT:
869 case UNSIGNED_INT:
870 case SIGNED_CHAR:
871 case UNSIGNED_CHAR:
872 switch (NUMERIC_TYPE (exp))
874 case SIGNED_INT:
875 case UNSIGNED_INT:
876 case SIGNED_CHAR:
877 case UNSIGNED_CHAR:
878 return 1;
880 case VOID:
881 abort ();
883 default:
884 abort ();
886 break;
888 case VOID:
889 abort ();
891 default:
892 abort ();
897 /* Make a production for an integer constant VALUE. */
899 static struct prod_token_parm_item *
900 make_integer_constant (struct prod_token_parm_item* value)
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;
915 /* Build a PROD_PLUS_EXPRESSION. This is uses for PLUS, MINUS, ASSIGN
916 and EQUALS expressions. */
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)
924 struct prod_token_parm_item *prod;
925 tree type;
927 ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
928 ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
930 prod = make_production (PROD_PLUS_EXPRESSION, tok);
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;
939 prod->tp.pro.code = tree_code_get_expression
940 (prod_code, type, op1->tp.pro.code,
941 op2->tp.pro.code, NULL);
943 return prod;
947 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
949 static void
950 set_storage (struct prod_token_parm_item *prod)
952 struct prod_token_parm_item* stg_class;
953 stg_class = STORAGE_CLASS_TOKEN (prod);
954 switch (stg_class->type)
956 case STATIC:
957 STORAGE_CLASS (prod) = STATIC_STORAGE;
958 break;
960 case AUTOMATIC:
961 STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
962 break;
964 case EXTERNAL_DEFINITION:
965 STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
966 break;
968 case EXTERNAL_REFERENCE:
969 STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
970 break;
972 default:
973 abort ();
977 /* Set parse trace. */
979 void
980 treelang_debug (void)
982 if (option_parser_trace)
983 yydebug = 1;