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