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. */
68 timevar_push
(TV_LEX
);
73 #define yylex my_yylex
75 extern
int option_parser_trace
;
77 /* Local prototypes. */
79 static void yyerror (const char *error_message
);
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. */
105 %token RIGHT_SQUARE_BRACKET
106 %token LEFT_SQUARE_BRACKET
107 %token RIGHT_PARENTHESIS
108 %token LEFT_PARENTHESIS
132 %token EXTERNAL_DEFINITION
133 %token EXTERNAL_REFERENCE
135 /* Tokens not passed to parser. */
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
167 | declarations declaration
{
176 |function_prototype
{
185 storage typename NAME init_opt SEMICOLON
{
186 struct prod_token_parm_item
* tok
;
187 struct prod_token_parm_item
*prod
;
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
))
199 STORAGE_CLASS_TOKEN
(prod
) = $1;
204 if
(! ((struct prod_token_parm_item
*)VAR_INIT
(prod
))->tp.pro.code
)
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
);
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
,
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
)
237 struct prod_token_parm_item
* tok
;
238 struct prod_token_parm_item
*prod
;
239 struct prod_token_parm_item
*prod2
;
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
))
250 prod2
= make_production
(PROD_PARAMETER
, tok
);
251 VARIABLE
(prod2
) = prod
;
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
;
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;
275 switch
(STORAGE_CLASS
(prod
))
278 case EXTERNAL_DEFINITION_STORAGE
:
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
);
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
);
297 this_parm
= this_parm
->tp.pro.next
)
299 if
(this_parm
->category
!= production_category
)
301 this_parm_var
= VARIABLE
(this_parm
);
304 if
(this_parm_var
->category
!= production_category
)
306 this_parms
= my_malloc
(sizeof
(struct prod_token_parm_item
));
307 if
(!this_parm_var
->tp.pro.main_token
)
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
)));
315 last_parms
->tp.par.next
= this_parms
;
316 last_parms
= this_parms
;
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
);
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
;
341 SYMBOL_TABLE_NAME
((&search_prod
)) = tok
;
342 search_prod.category
= token_category
;
343 current_function
= proto
= lookup_tree_name
(&search_prod
);
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
);
353 if
(!proto
->tp.pro.code
)
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
);
362 this_parm
= this_parm
->tp.pro.next
)
364 if
(! (struct prod_token_parm_item
*)VARIABLE
(this_parm
))
366 if
(! (( (struct prod_token_parm_item
*)VARIABLE
(this_parm
))->tp.pro.code
))
370 variable_defs_opt statements_opt RIGHT_BRACE
{
371 struct prod_token_parm_item
* tok
;
373 tree_code_create_function_wrapup
(tok
->tp.tok.location
);
374 current_function
= NULL
;
400 |variable_defs variable_def
{
407 struct prod_token_parm_item
* tok
;
408 struct prod_token_parm_item
*prod
;
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
));
416 struct prod_token_parm_item
* tok
;
417 struct prod_token_parm_item
*prod
;
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
));
425 struct prod_token_parm_item
* tok
;
426 struct prod_token_parm_item
*prod
;
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
));
434 struct prod_token_parm_item
* tok
;
435 struct prod_token_parm_item
*prod
;
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
));
443 struct prod_token_parm_item
* tok
;
444 struct prod_token_parm_item
*prod
;
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
));
458 |parameters COMMA parameter
{
459 struct prod_token_parm_item
*prod1
;
461 prod1
->tp.pro.next
= $1; /* Insert in reverse order. */
470 |statements statement
{
476 expression SEMICOLON
{
477 struct prod_token_parm_item
*exp
;
479 tree_code_output_expression_statement
(exp
->tp.pro.code
,
480 exp
->tp.pro.main_token
->tp.tok.location
);
491 IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS
{
492 struct prod_token_parm_item
* tok
;
493 struct prod_token_parm_item
*exp
;
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. */
503 struct prod_token_parm_item
* tok
;
505 tree_code_if_else
(tok
->tp.tok.location
);
507 LEFT_BRACE statements_opt RIGHT_BRACE
{
508 struct prod_token_parm_item
* tok
;
510 tree_code_if_end
(tok
->tp.tok.location
);
516 tl_RETURN expression_opt
{
517 struct prod_token_parm_item
*type_prod
;
518 struct prod_token_parm_item
* ret_tok
;
520 type_prod
= EXPRESSION_TYPE
(current_function
);
521 if
(NUMERIC_TYPE
(type_prod
) == VOID
)
523 tree_code_generate_return
(type_prod
->tp.pro.code
, NULL
);
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
);
531 tree_code_generate_return
(type_prod
->tp.pro.code
, 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
);
544 struct prod_token_parm_item
*exp
;
546 /* Check same type. */
547 if
(check_type_match
(NUMERIC_TYPE
(type_prod
), $2))
549 if
(!type_prod
->tp.pro.code
)
551 if
(!exp
->tp.pro.code
)
553 /* Generate the code. */
554 tree_code_generate_return
(type_prod
->tp.pro.code
, exp
->tp.pro.code
);
565 struct prod_token_parm_item
*exp
;
567 if
(!exp
->tp.pro.code
)
576 $$
= make_integer_constant
($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
);
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
);
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
);
615 $$
= make_plus_expression
616 (tok
, op1
, op2
, type_code
, EXP_ASSIGN
);
618 |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
;
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
);
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
);
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
)
660 for
(exp_count
= 0, exp
= PARAMETERS
(prod
); exp
; exp
= exp
->tp.pro.next
)
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
);
672 parms
= tree_code_init_parameters
();
673 for
(exp_proto
= PARAMETERS
(proto
), exp
= PARAMETERS
(prod
);
675 exp
= exp
->tp.pro.next
, exp_proto
= exp_proto
->tp.pro.next
)
681 if
(!exp
->tp.pro.code
)
683 var
= VARIABLE
(exp_proto
);
686 if
(!var
->tp.pro.code
)
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
);
697 expressions_with_commas:
699 struct prod_token_parm_item
*exp
;
701 ensure_not_void
(NUMERIC_TYPE
(exp
), exp
->tp.pro.main_token
);
704 |expressions_with_commas COMMA expression
{
705 struct prod_token_parm_item
*exp
;
707 ensure_not_void
(NUMERIC_TYPE
(exp
), exp
->tp.pro.main_token
);
708 exp
->tp.pro.next
= $1; /* Reverse order. */
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
;
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
);
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
))
742 prod
->tp.pro.code
= tree_code_get_expression
(EXP_REFERENCE
, type
,
743 symbol_table_entry
->tp.pro.code
, NULL
, NULL
);
757 ASSIGN init_element
{
763 $$
= make_integer_constant
($1);
769 /* Print a token VALUE to file FILE. Ignore TYPE which is the token
773 print_token
(FILE * file
, unsigned int type ATTRIBUTE_UNUSED
, YYSTYPE value
)
775 struct prod_token_parm_item
*tok
;
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. */
787 yyerror (const char *error_message
)
789 struct prod_token_parm_item
*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
);
799 fprintf
(stderr
, "%s\n", error_message
);
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
;
820 if
(current
->category
!= production_category
)
822 next
= current
->tp.pro.next
;
823 current
->tp.pro.next
= prev
;
830 /* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
833 ensure_not_void
(unsigned int type
, struct prod_token_parm_item
* name
)
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
);
845 /* Check TYPE1 and TYPE2 which are integral types. Return the lowest
846 common type (min is signed int). */
849 get_common_type
(struct prod_token_parm_item
*type1
, struct prod_token_parm_item
*type2
)
851 if
(NUMERIC_TYPE
(type1
) == UNSIGNED_INT
)
853 if
(NUMERIC_TYPE
(type2
) == UNSIGNED_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
864 check_type_match
(int type_num
, struct prod_token_parm_item
*exp
)
872 switch
(NUMERIC_TYPE
(exp
))
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
;
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
;
909 NUMERIC_TYPE
(prod
) = UNSIGNED_INT
;
910 prod
->tp.pro.code
= tree_code_get_integer_value
(tok
->tp.tok.chars
, tok
->tp.tok.length
);
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
;
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
));
939 prod
->tp.pro.code
= tree_code_get_expression
940 (prod_code
, type
, op1
->tp.pro.code
,
941 op2
->tp.pro.code
, NULL
);
947 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
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
)
957 STORAGE_CLASS
(prod
) = STATIC_STORAGE
;
961 STORAGE_CLASS
(prod
) = AUTOMATIC_STORAGE
;
964 case EXTERNAL_DEFINITION
:
965 STORAGE_CLASS
(prod
) = EXTERNAL_DEFINITION_STORAGE
;
968 case EXTERNAL_REFERENCE
:
969 STORAGE_CLASS
(prod
) = EXTERNAL_REFERENCE_STORAGE
;
977 /* Set parse trace. */
980 treelang_debug
(void)
982 if
(option_parser_trace
)