1 %
{ /* -*- c -*- emacs mode c */
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
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
41 There are no conflicts in this grammar. Please keep it that way.
47 #include "coretypes.h"
49 #include "diagnostic.h"
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
62 static inline
int my_yylex
(void);
63 /* Call lex, but ensure time is charged to TV_LEX. */
64 static inline
int my_yylex
()
67 timevar_push
(TV_LEX
);
72 #define yylex my_yylex
74 extern
int option_parser_trace
;
76 /* Local prototypes. */
78 static void yyerror (const char *error_message
);
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. */
104 %token RIGHT_SQUARE_BRACKET
105 %token LEFT_SQUARE_BRACKET
106 %token RIGHT_PARENTHESIS
107 %token LEFT_PARENTHESIS
131 %token EXTERNAL_DEFINITION
132 %token EXTERNAL_REFERENCE
134 /* Tokens not passed to parser. */
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
166 | declarations declaration
{
175 |function_prototype
{
184 storage typename NAME init_opt SEMICOLON
{
185 struct prod_token_parm_item
* tok
;
186 struct prod_token_parm_item
*prod
;
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
))
198 STORAGE_CLASS_TOKEN
(prod
) = $1;
203 if
(! ((struct prod_token_parm_item
*)VAR_INIT
(prod
))->tp.pro.code
)
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
);
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
,
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
)
236 struct prod_token_parm_item
* tok
;
237 struct prod_token_parm_item
*prod
;
238 struct prod_token_parm_item
*prod2
;
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
))
249 prod2
= make_production
(PROD_PARAMETER
, tok
);
250 VARIABLE
(prod2
) = prod
;
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
;
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;
274 switch
(STORAGE_CLASS
(prod
))
277 case EXTERNAL_DEFINITION_STORAGE
:
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
);
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
);
296 this_parm
= this_parm
->tp.pro.next
)
298 if
(this_parm
->category
!= production_category
)
300 this_parm_var
= VARIABLE
(this_parm
);
303 if
(this_parm_var
->category
!= production_category
)
305 this_parms
= my_malloc
(sizeof
(struct prod_token_parm_item
));
306 if
(!this_parm_var
->tp.pro.main_token
)
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
)));
314 last_parms
->tp.par.next
= this_parms
;
315 last_parms
= this_parms
;
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
);
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
;
340 SYMBOL_TABLE_NAME
((&search_prod
)) = tok
;
341 search_prod.category
= token_category
;
342 current_function
= proto
= lookup_tree_name
(&search_prod
);
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
);
352 if
(!proto
->tp.pro.code
)
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
);
361 this_parm
= this_parm
->tp.pro.next
)
363 if
(! (struct prod_token_parm_item
*)VARIABLE
(this_parm
))
365 if
(! (( (struct prod_token_parm_item
*)VARIABLE
(this_parm
))->tp.pro.code
))
369 variable_defs_opt statements_opt RIGHT_BRACE
{
370 struct prod_token_parm_item
* tok
;
372 tree_code_create_function_wrapup
(tok
->tp.tok.location
);
373 current_function
= NULL
;
399 |variable_defs variable_def
{
406 struct prod_token_parm_item
* tok
;
407 struct prod_token_parm_item
*prod
;
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
));
415 struct prod_token_parm_item
* tok
;
416 struct prod_token_parm_item
*prod
;
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
));
424 struct prod_token_parm_item
* tok
;
425 struct prod_token_parm_item
*prod
;
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
));
433 struct prod_token_parm_item
* tok
;
434 struct prod_token_parm_item
*prod
;
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
));
442 struct prod_token_parm_item
* tok
;
443 struct prod_token_parm_item
*prod
;
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
));
457 |parameters COMMA parameter
{
458 struct prod_token_parm_item
*prod1
;
460 prod1
->tp.pro.next
= $1; /* Insert in reverse order. */
469 |statements statement
{
475 expression SEMICOLON
{
476 struct prod_token_parm_item
*exp
;
478 tree_code_output_expression_statement
(exp
->tp.pro.code
,
479 exp
->tp.pro.main_token
->tp.tok.location
);
490 IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS
{
491 struct prod_token_parm_item
* tok
;
492 struct prod_token_parm_item
*exp
;
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. */
502 struct prod_token_parm_item
* tok
;
504 tree_code_if_else
(tok
->tp.tok.location
);
506 LEFT_BRACE statements_opt RIGHT_BRACE
{
507 struct prod_token_parm_item
* tok
;
509 tree_code_if_end
(tok
->tp.tok.location
);
515 tl_RETURN expression_opt
{
516 struct prod_token_parm_item
*type_prod
;
517 struct prod_token_parm_item
* ret_tok
;
519 type_prod
= EXPRESSION_TYPE
(current_function
);
520 if
(NUMERIC_TYPE
(type_prod
) == VOID
)
522 tree_code_generate_return
(type_prod
->tp.pro.code
, NULL
);
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
);
530 tree_code_generate_return
(type_prod
->tp.pro.code
, 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
);
543 struct prod_token_parm_item
*exp
;
545 /* Check same type. */
546 if
(check_type_match
(NUMERIC_TYPE
(type_prod
), $2))
548 if
(!type_prod
->tp.pro.code
)
550 if
(!exp
->tp.pro.code
)
552 /* Generate the code. */
553 tree_code_generate_return
(type_prod
->tp.pro.code
, exp
->tp.pro.code
);
564 struct prod_token_parm_item
*exp
;
566 if
(!exp
->tp.pro.code
)
575 $$
= make_integer_constant
($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
);
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
);
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
);
614 $$
= make_plus_expression
615 (tok
, op1
, op2
, type_code
, EXP_ASSIGN
);
617 |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
;
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
);
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
);
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
)
659 for
(exp_count
= 0, exp
= PARAMETERS
(prod
); exp
; exp
= exp
->tp.pro.next
)
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
);
671 parms
= tree_code_init_parameters
();
672 for
(exp_proto
= PARAMETERS
(proto
), exp
= PARAMETERS
(prod
);
674 exp
= exp
->tp.pro.next
, exp_proto
= exp_proto
->tp.pro.next
)
680 if
(!exp
->tp.pro.code
)
682 var
= VARIABLE
(exp_proto
);
685 if
(!var
->tp.pro.code
)
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
);
696 expressions_with_commas:
698 struct prod_token_parm_item
*exp
;
700 ensure_not_void
(NUMERIC_TYPE
(exp
), exp
->tp.pro.main_token
);
703 |expressions_with_commas COMMA expression
{
704 struct prod_token_parm_item
*exp
;
706 ensure_not_void
(NUMERIC_TYPE
(exp
), exp
->tp.pro.main_token
);
707 exp
->tp.pro.next
= $1; /* Reverse order. */
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
;
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
);
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
))
741 prod
->tp.pro.code
= tree_code_get_expression
(EXP_REFERENCE
, type
,
742 symbol_table_entry
->tp.pro.code
, NULL
, NULL
);
756 ASSIGN init_element
{
762 $$
= make_integer_constant
($1);
768 /* Print a token VALUE to file FILE. Ignore TYPE which is the token
772 print_token
(FILE * file
, unsigned int type ATTRIBUTE_UNUSED
, YYSTYPE value
)
774 struct prod_token_parm_item
*tok
;
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. */
786 yyerror (const char *error_message
)
788 struct prod_token_parm_item
*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
);
798 fprintf
(stderr
, "%s\n", error_message
);
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
;
819 if
(current
->category
!= production_category
)
821 next
= current
->tp.pro.next
;
822 current
->tp.pro.next
= prev
;
829 /* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
832 ensure_not_void
(unsigned int type
, struct prod_token_parm_item
* name
)
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
);
844 /* Check TYPE1 and TYPE2 which are integral types. Return the lowest
845 common type (min is signed int). */
848 get_common_type
(struct prod_token_parm_item
*type1
, struct prod_token_parm_item
*type2
)
850 if
(NUMERIC_TYPE
(type1
) == UNSIGNED_INT
)
852 if
(NUMERIC_TYPE
(type2
) == UNSIGNED_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
863 check_type_match
(int type_num
, struct prod_token_parm_item
*exp
)
871 switch
(NUMERIC_TYPE
(exp
))
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
;
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
;
908 NUMERIC_TYPE
(prod
) = UNSIGNED_INT
;
909 prod
->tp.pro.code
= tree_code_get_integer_value
(tok
->tp.tok.chars
, tok
->tp.tok.length
);
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
;
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
));
938 prod
->tp.pro.code
= tree_code_get_expression
939 (prod_code
, type
, op1
->tp.pro.code
,
940 op2
->tp.pro.code
, NULL
);
946 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
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
)
956 STORAGE_CLASS
(prod
) = STATIC_STORAGE
;
960 STORAGE_CLASS
(prod
) = AUTOMATIC_STORAGE
;
963 case EXTERNAL_DEFINITION
:
964 STORAGE_CLASS
(prod
) = EXTERNAL_DEFINITION_STORAGE
;
967 case EXTERNAL_REFERENCE
:
968 STORAGE_CLASS
(prod
) = EXTERNAL_REFERENCE_STORAGE
;
976 /* Set parse trace. */
979 treelang_debug
(void)
981 if
(option_parser_trace
)