2004-12-22 Daniel Berlin <dberlin@dberlin.org>
[official-gcc.git] / gcc / treelang / parse.y
blobb1330c70ccfbe0787b7f767040c8f5440b54119d
1 /* -*- c -*- emacs mode c */
2 /* TREELANG Compiler parser.
4 ---------------------------------------------------------------------
6 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
7 Free Software Foundation, Inc.
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.
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.
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.
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!
28 ---------------------------------------------------------------------
30 Written by Tim Josling 1999-2001, based in part on other parts of
31 the GCC compiler. */
33 /* Grammar Conflicts
34 *****************
35 There are no conflicts in this grammar. Please keep it that way. */
37 %{
38 #include "config.h"
39 #include "system.h"
40 #include "coretypes.h"
41 #include "tm.h"
42 #include "errors.h"
43 #include "timevar.h"
45 #include "treelang.h"
46 #include "treetree.h"
48 #define YYDEBUG 1
49 #define YYPRINT(file, type, value) print_token (file, type, value)
50 #define YYERROR_VERBOSE YES
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);
57 /* Call lex, but ensure time is charged to TV_LEX. */
58 static inline int
59 my_yylex (void)
61 int res;
62 timevar_push (TV_LEX);
63 res = yylex ();
64 timevar_pop (TV_LEX);
65 return res;
67 #define yylex my_yylex
69 extern int option_parser_trace;
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);
90 /* File global variables. */
91 static struct prod_token_parm_item *current_function = NULL;
94 /* Not %raw - seems to have bugs. */
95 %token_table
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
112 /* Literals. */
113 %token INTEGER
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
130 /* Tokens not passed to parser. */
131 %token WHITESPACE
132 %token COMMENT
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
148 file:
149 /* Nil. */ {
150 /* Nothing to do. */
152 |declarations {
153 /* Nothing to do. */
158 declarations:
159 declaration {
160 /* Nothing to do. */
162 | declarations declaration {
163 /* Nothing to do. */
167 declaration:
168 variable_def {
169 /* Nothing to do. */
171 |function_prototype {
172 /* Nothing to do. */
174 |function {
175 /* Nothing to do. */
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))
193 YYERROR;
195 STORAGE_CLASS_TOKEN (prod) = $1;
196 set_storage (prod);
198 if (VAR_INIT (prod))
200 gcc_assert (((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code);
201 if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
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;
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);
223 storage:
224 STATIC
225 |AUTOMATIC
226 |EXTERNAL_DEFINITION
227 |EXTERNAL_REFERENCE
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))
244 YYERROR;
246 prod2 = make_production (PROD_PARAMETER, tok);
247 VARIABLE (prod2) = prod;
248 $$ = prod2;
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))
274 case STATIC_STORAGE:
275 case EXTERNAL_DEFINITION_STORAGE:
276 break;
278 case AUTOMATIC_STORAGE:
279 error ("%HFunction %q.*s cannot be automatic.",
280 &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
281 YYERROR;
282 break;
284 default:
285 gcc_unreachable ();
287 type = EXPRESSION_TYPE (prod);
288 /* Create a parameter list in a non-front end specific format. */
289 for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
290 this_parm;
291 this_parm = this_parm->tp.pro.next)
293 gcc_assert (this_parm->category == production_category);
294 this_parm_var = VARIABLE (this_parm);
296 gcc_assert (this_parm_var);
297 gcc_assert (this_parm_var->category == production_category);
298 gcc_assert (this_parm_var->tp.pro.main_token);
300 this_parms = my_malloc (sizeof (struct prod_token_parm_item));
302 this_parms->tp.par.variable_name =
303 this_parm_var->tp.pro.main_token->tp.tok.chars;
304 this_parms->category = parameter_category;
305 this_parms->type = NUMERIC_TYPE
306 (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
307 if (last_parms)
309 last_parms->tp.par.next = this_parms;
310 last_parms = this_parms;
312 else
314 first_parms = this_parms;
315 last_parms = this_parms;
317 this_parms->tp.par.where_to_put_var_tree =
318 & (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
320 FIRST_PARMS (prod) = first_parms;
322 prod->tp.pro.code =
323 tree_code_create_function_prototype (tok->tp.tok.chars,
324 STORAGE_CLASS (prod),
325 NUMERIC_TYPE (type),
326 first_parms, tok->tp.tok.location);
330 function:
331 NAME LEFT_BRACE {
332 struct prod_token_parm_item *proto;
333 struct prod_token_parm_item search_prod;
334 struct prod_token_parm_item* tok;
335 struct prod_token_parm_item *this_parm;
336 tok = $1;
337 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
338 search_prod.category = token_category;
339 current_function = proto = lookup_tree_name (&search_prod);
340 if (!proto)
342 error ("%HNo prototype found for %q.*s", &tok->tp.tok.location,
343 tok->tp.tok.length, tok->tp.tok.chars);
344 YYERROR;
347 gcc_assert (proto->tp.pro.code);
349 tree_code_create_function_initial (proto->tp.pro.code, tok->tp.tok.location,
350 FIRST_PARMS (current_function));
352 #ifdef ENABLE_CHECKING
353 /* Check all the parameters have code. */
354 for (this_parm = PARAMETERS (proto);
355 this_parm;
356 this_parm = this_parm->tp.pro.next)
358 gcc_assert ((struct prod_token_parm_item*)VARIABLE (this_parm));
359 gcc_assert (((struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
361 #endif
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;
371 variable_defs_opt:
372 /* Nil. */ {
373 $$ = 0;
375 |variable_defs {
376 $$ = $1;
380 statements_opt:
381 /* Nil. */ {
382 $$ = 0;
384 |statements {
385 $$ = $1;
389 variable_defs:
390 variable_def {
391 /* Nothing to do. */
393 |variable_defs variable_def {
394 /* Nothing to do. */
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;
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;
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;
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;
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;
446 parameters_opt:
447 /* Nothing to do. */ {
448 $$ = 0;
450 | parameters {
451 $$ = $1;
454 parameters:
455 parameter {
456 /* Nothing to do. */
457 $$ = $1;
459 |parameters COMMA parameter {
460 struct prod_token_parm_item *prod1;
461 prod1 = $3;
462 prod1->tp.pro.next = $1; /* Insert in reverse order. */
463 $$ = prod1;
467 statements:
468 statement {
469 /* Nothing to do. */
471 |statements statement {
472 /* Nothing to do. */
476 statement:
477 expression SEMICOLON {
478 struct prod_token_parm_item *exp;
479 exp = $1;
480 tree_code_output_expression_statement (exp->tp.pro.code,
481 exp->tp.pro.main_token->tp.tok.location);
483 |return SEMICOLON {
484 /* Nothing to do. */
486 |if_statement {
487 /* Nothing to do. */
491 if_statement:
492 IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
493 struct prod_token_parm_item* tok;
494 struct prod_token_parm_item *exp;
495 tok = $1;
496 exp = $3;
497 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
498 tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
500 LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
501 /* Just let the statements flow. */
503 ELSE {
504 struct prod_token_parm_item* tok;
505 tok = $1;
506 tree_code_if_else (tok->tp.tok.location);
508 LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
509 struct prod_token_parm_item* tok;
510 tok = $1;
511 tree_code_if_end (tok->tp.tok.location);
516 return:
517 tl_RETURN expression_opt {
518 struct prod_token_parm_item *type_prod;
519 struct prod_token_parm_item *ret_tok = $1;
520 struct prod_token_parm_item *exp = $2;
522 type_prod = EXPRESSION_TYPE (current_function);
523 if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
524 if (exp == NULL)
525 tree_code_generate_return (type_prod->tp.pro.code, NULL);
526 else
528 warning ("%HRedundant expression in return.",
529 &ret_tok->tp.tok.location, ret_tok->tp.tok.length,
530 ret_tok->tp.tok.chars);
531 tree_code_generate_return (type_prod->tp.pro.code, NULL);
533 else
534 if (exp == NULL)
535 error ("%HExpression missing in return.", &ret_tok->tp.tok.location);
536 else
538 /* Check same type. */
539 if (check_type_match (NUMERIC_TYPE (type_prod), exp))
541 gcc_assert (type_prod->tp.pro.code);
542 gcc_assert (exp->tp.pro.code);
544 /* Generate the code. */
545 tree_code_generate_return (type_prod->tp.pro.code,
546 exp->tp.pro.code);
552 expression_opt:
553 /* Nil. */ {
554 $$ = 0;
556 |expression {
557 struct prod_token_parm_item *exp;
558 exp = $1;
559 gcc_assert (exp->tp.pro.code);
561 $$ = $1;
565 expression:
566 INTEGER {
567 $$ = make_integer_constant ($1);
569 |variable_ref {
570 $$ = $1;
572 |expression tl_PLUS expression {
573 struct prod_token_parm_item *tok = $2;
574 struct prod_token_parm_item *op1 = $1;
575 struct prod_token_parm_item *op2 = $3;
576 int type_code = get_common_type (op1, op2);
577 if (!type_code)
578 YYERROR;
579 $$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
581 |expression tl_MINUS expression %prec tl_PLUS {
582 struct prod_token_parm_item *tok = $2;
583 struct prod_token_parm_item *op1 = $1;
584 struct prod_token_parm_item *op2 = $3;
585 int type_code = get_common_type (op1, op2);
586 if (!type_code)
587 YYERROR;
588 $$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
590 |expression EQUALS expression {
591 struct prod_token_parm_item *tok = $2;
592 struct prod_token_parm_item *op1 = $1;
593 struct prod_token_parm_item *op2 = $3;
594 $$ = make_plus_expression
595 (tok, op1, op2, SIGNED_INT, EXP_EQUALS);
597 |variable_ref ASSIGN expression {
598 struct prod_token_parm_item *tok = $2;
599 struct prod_token_parm_item *op1 = $1;
600 struct prod_token_parm_item *op2 = $3;
601 int type_code = NUMERIC_TYPE (op1);
602 if (!type_code)
603 YYERROR;
604 $$ = make_plus_expression
605 (tok, op1, op2, type_code, EXP_ASSIGN);
607 |function_invocation {
608 $$ = $1;
612 function_invocation:
613 NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
614 struct prod_token_parm_item *prod;
615 struct prod_token_parm_item* tok;
616 struct prod_token_parm_item search_prod;
617 struct prod_token_parm_item *proto;
618 struct prod_token_parm_item *exp;
619 struct prod_token_parm_item *exp_proto;
620 struct prod_token_parm_item *var;
621 int exp_proto_count;
622 int exp_count;
623 tree parms;
624 tree type;
626 tok = $1;
627 prod = make_production (PROD_FUNCTION_INVOCATION, tok);
628 SYMBOL_TABLE_NAME (prod) = tok;
629 PARAMETERS (prod) = reverse_prod_list ($3);
630 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
631 search_prod.category = token_category;
632 proto = lookup_tree_name (&search_prod);
633 if (!proto)
635 error ("%HFunction prototype not found for %q.*%s.",
636 &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
637 YYERROR;
639 EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
640 NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
641 /* Count the expressions and ensure they match the prototype. */
642 for (exp_proto_count = 0, exp_proto = PARAMETERS (proto);
643 exp_proto; exp_proto = exp_proto->tp.pro.next)
644 exp_proto_count++;
646 for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
647 exp_count++;
649 if (exp_count != exp_proto_count)
651 error ("%HExpression count mismatch %q.*s with prototype.",
652 &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
653 YYERROR;
655 parms = tree_code_init_parameters ();
656 for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
657 exp_proto;
658 exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
660 gcc_assert (exp);
661 gcc_assert (exp_proto);
662 gcc_assert (exp->tp.pro.code);
664 var = VARIABLE (exp_proto);
666 gcc_assert (var);
667 gcc_assert (var->tp.pro.code);
669 parms = tree_code_add_parameter (parms, var->tp.pro.code,
670 exp->tp.pro.code);
672 type = tree_code_get_type (NUMERIC_TYPE (prod));
673 prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
674 proto->tp.pro.code, parms,
675 NULL);
676 $$ = prod;
680 expressions_with_commas:
681 expression {
682 struct prod_token_parm_item *exp;
683 exp = $1;
684 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
685 $$ = $1;
687 |expressions_with_commas COMMA expression {
688 struct prod_token_parm_item *exp;
689 exp = $3;
690 ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
691 exp->tp.pro.next = $1; /* Reverse order. */
692 $$ = exp;
696 variable_ref:
697 NAME {
698 struct prod_token_parm_item search_prod;
699 struct prod_token_parm_item *prod;
700 struct prod_token_parm_item *symbol_table_entry;
701 struct prod_token_parm_item* tok;
702 tree type;
704 tok = $1;
705 SYMBOL_TABLE_NAME ((&search_prod)) = tok;
706 search_prod.category = token_category;
707 symbol_table_entry = lookup_tree_name (&search_prod);
708 if (!symbol_table_entry)
710 error ("%HVariable %q.*s not defined.",
711 &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
712 YYERROR;
715 prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
716 NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
717 type = tree_code_get_type (NUMERIC_TYPE (prod));
718 if (!NUMERIC_TYPE (prod))
719 YYERROR;
720 OP1 (prod) = $1;
722 prod->tp.pro.code =
723 tree_code_get_expression (EXP_REFERENCE, type,
724 symbol_table_entry->tp.pro.code, NULL, NULL);
725 $$ = prod;
729 init_opt:
730 /* Nil. */ {
731 $$ = 0;
733 |init {
734 /* Nothing to do. */
737 init:
738 ASSIGN init_element {
739 $$ = $2;
743 init_element:
744 INTEGER {
745 $$ = make_integer_constant ($1);
751 /* Print a token VALUE to file FILE. Ignore TYPE which is the token
752 type. */
754 void
755 print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
757 struct prod_token_parm_item *tok;
758 unsigned int ix;
760 tok = value;
761 fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
762 for (ix = 0; ix < tok->tp.tok.length; ix++)
763 fprintf (file, "%c", tok->tp.tok.chars[ix]);
765 fprintf (file, "\"");
768 /* Output a message ERROR_MESSAGE from the parser. */
769 static void
770 yyerror (const char *error_message)
772 struct prod_token_parm_item *tok;
774 tok = yylval;
775 if (tok)
776 error ("%H%s", &tok->tp.tok.location, error_message);
777 else
778 error ("%s", error_message);
781 /* Reverse the order of a token list, linked by parse_next, old first
782 token is OLD_FIRST. */
784 static struct prod_token_parm_item*
785 reverse_prod_list (struct prod_token_parm_item *old_first)
787 struct prod_token_parm_item *current;
788 struct prod_token_parm_item *next;
789 struct prod_token_parm_item *prev = NULL;
791 current = old_first;
792 prev = NULL;
794 while (current)
796 gcc_assert (current->category == production_category);
798 next = current->tp.pro.next;
799 current->tp.pro.next = prev;
800 prev = current;
801 current = next;
803 return prev;
806 /* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
808 static void
809 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
811 if (type == VOID_TYPE)
812 error ("%HType must not be void in this context.",
813 &name->tp.tok.location);
816 /* Check TYPE1 and TYPE2 which are integral types. Return the lowest
817 common type (min is signed int). */
819 static int
820 get_common_type (struct prod_token_parm_item *type1,
821 struct prod_token_parm_item *type2)
823 if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
824 return UNSIGNED_INT;
825 if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
826 return UNSIGNED_INT;
828 return SIGNED_INT;
831 /* Check type (TYPE_NUM) and expression (EXP) match. Return the 1 if
832 OK else 0. Must be exact match - same name unless it is an
833 integral type. */
835 static int
836 check_type_match (int type_num, struct prod_token_parm_item *exp)
838 switch (type_num)
840 case SIGNED_INT:
841 case UNSIGNED_INT:
842 case SIGNED_CHAR:
843 case UNSIGNED_CHAR:
844 switch (NUMERIC_TYPE (exp))
846 case SIGNED_INT:
847 case UNSIGNED_INT:
848 case SIGNED_CHAR:
849 case UNSIGNED_CHAR:
850 return 1;
852 case VOID_TYPE:
853 default:
854 gcc_unreachable ();
856 break;
858 case VOID_TYPE:
859 default:
860 gcc_unreachable ();
865 /* Make a production for an integer constant VALUE. */
867 static struct prod_token_parm_item *
868 make_integer_constant (struct prod_token_parm_item* value)
870 struct prod_token_parm_item* tok;
871 struct prod_token_parm_item *prod;
872 tok = value;
873 prod = make_production (PROD_INTEGER_CONSTANT, tok);
874 if ((tok->tp.tok.chars[0] == (unsigned char)'-')
875 || (tok->tp.tok.chars[0] == (unsigned char)'+'))
876 NUMERIC_TYPE (prod) = SIGNED_INT;
877 else
878 NUMERIC_TYPE (prod) = UNSIGNED_INT;
879 prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
880 tok->tp.tok.length);
881 return prod;
885 /* Build a PROD_PLUS_EXPRESSION. This is uses for PLUS, MINUS, ASSIGN
886 and EQUALS expressions. */
888 static struct prod_token_parm_item *
889 make_plus_expression (struct prod_token_parm_item* tok,
890 struct prod_token_parm_item* op1,
891 struct prod_token_parm_item* op2,
892 int type_code, int prod_code)
894 struct prod_token_parm_item *prod;
895 tree type;
897 ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
898 ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
900 prod = make_production (PROD_PLUS_EXPRESSION, tok);
902 NUMERIC_TYPE (prod) = type_code;
903 type = tree_code_get_type (type_code);
905 gcc_assert (type);
907 OP1 (prod) = op1;
908 OP2 (prod) = op2;
910 prod->tp.pro.code = tree_code_get_expression (prod_code, type,
911 op1->tp.pro.code,
912 op2->tp.pro.code, NULL);
914 return prod;
918 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
920 static void
921 set_storage (struct prod_token_parm_item *prod)
923 struct prod_token_parm_item* stg_class;
924 stg_class = STORAGE_CLASS_TOKEN (prod);
925 switch (stg_class->type)
927 case STATIC:
928 STORAGE_CLASS (prod) = STATIC_STORAGE;
929 break;
931 case AUTOMATIC:
932 STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
933 break;
935 case EXTERNAL_DEFINITION:
936 STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
937 break;
939 case EXTERNAL_REFERENCE:
940 STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
941 break;
943 default:
944 gcc_unreachable ();
948 /* Set parse trace. */
950 void
951 treelang_debug (void)
953 if (option_parser_trace)
954 yydebug = 1;
957 #ifdef __XGETTEXT__
958 /* Depending on the version of Bison used to compile this grammar,
959 it may issue generic diagnostics spelled "syntax error" or
960 "parse error". To prevent this from changing the translation
961 template randomly, we list all the variants of this particular
962 diagnostic here. Translators: there is no fine distinction
963 between diagnostics with "syntax error" in them, and diagnostics
964 with "parse error" in them. It's okay to give them both the same
965 translation. */
966 const char d1[] = N_("syntax error");
967 const char d2[] = N_("parse error");
968 const char d3[] = N_("syntax error; also virtual memory exhausted");
969 const char d4[] = N_("parse error; also virtual memory exhausted");
970 const char d5[] = N_("syntax error: cannot back up");
971 const char d6[] = N_("parse error: cannot back up");
972 #endif