1 %
{ /* -*- c -*- emacs mode c */
4 TREELANG Compiler parser.
6 ---------------------------------------------------------------------
8 Copyright (C) 1999, 2000, 2001, 2002 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.
56 #include "diagnostic.h"
62 #define YYPRINT(file, type, value) print_token (file, type, value)
63 #define YYERROR_VERBOSE YES
66 extern
int option_parser_trace
;
68 /* Local prototypes. */
70 static void yyerror (const char *error_message
);
73 void print_token
(FILE * file
, unsigned int type ATTRIBUTE_UNUSED
, YYSTYPE value
);
74 static struct production
*reverse_prod_list
(struct production
*old_first
);
75 static void ensure_not_void
(unsigned int type
, struct token
* name
);
76 static int check_type_match
(int type_num
, struct production
*exp
);
77 static int get_common_type
(struct production
*type1
, struct production
*type2
);
78 static struct production
*make_integer_constant
(struct token
* value
);
79 static void set_storage
(struct production
*prod
);
81 /* File global variables. */
83 static struct production
*current_function
=NULL
;
87 /* Not %raw - seems to have bugs. */
93 %token RIGHT_SQUARE_BRACKET
94 %token LEFT_SQUARE_BRACKET
95 %token RIGHT_PARENTHESIS
96 %token LEFT_PARENTHESIS
120 %token EXTERNAL_DEFINITION
121 %token EXTERNAL_REFERENCE
123 /* Tokens not passed to parser. */
127 /* Pseudo tokens - productions. */
128 %token PROD_VARIABLE_NAME
129 %token PROD_TYPE_NAME
130 %token PROD_FUNCTION_NAME
131 %token PROD_INTEGER_CONSTANT
132 %token PROD_PLUS_EXPRESSION
133 %token PROD_MINUS_EXPRESSION
134 %token PROD_ASSIGN_EXPRESSION
135 %token PROD_VARIABLE_REFERENCE_EXPRESSION
136 %token PROD_PARAMETER
137 %token PROD_FUNCTION_INVOCATION
155 | declarations declaration
{
164 |function_prototype
{
173 storage typename NAME init_opt SEMICOLON
{
175 struct production
*prod
;
177 prod
= make_production
(PROD_VARIABLE_NAME
, tok
);
178 SYMBOL_TABLE_NAME
(prod
) = tok
;
179 EXPRESSION_TYPE
(prod
) = $2;
180 VAR_INIT
(prod
) = $4;
181 NUMERIC_TYPE
(prod
) = NUMERIC_TYPE
(( (struct production
*)EXPRESSION_TYPE
(prod
)));
182 ensure_not_void
(NUMERIC_TYPE
(prod
), tok
);
183 if
(insert_tree_name
(prod
))
187 STORAGE_CLASS_TOKEN
(prod
) = $1;
192 if
(! ((struct production
*)VAR_INIT
(prod
))->code
)
194 if
(STORAGE_CLASS
(prod
) == EXTERNAL_REFERENCE_STORAGE
)
196 fprintf
(stderr
, "%s:%i:%i: External reference variables may not have initial value\n", in_fname
,
197 tok
->lineno
, tok
->charno
);
198 print_token
(stderr
, 0, tok
);
203 prod
->code
= tree_code_create_variable
204 (STORAGE_CLASS
(prod
),
205 ((struct token
*)SYMBOL_TABLE_NAME
(prod
))->chars
,
206 ((struct token
*)SYMBOL_TABLE_NAME
(prod
))->length
,
208 VAR_INIT
(prod
)?
((struct production
*)VAR_INIT
(prod
))->code
:NULL
,
226 struct production
*prod
;
227 struct production
*prod2
;
229 prod
= make_production
(PROD_VARIABLE_NAME
, tok
);
230 SYMBOL_TABLE_NAME
(prod
) = $2;
231 EXPRESSION_TYPE
(prod
) = $1;
232 NUMERIC_TYPE
(prod
) = NUMERIC_TYPE
(( (struct production
*)EXPRESSION_TYPE
(prod
)));
233 ensure_not_void
(NUMERIC_TYPE
(prod
), tok
);
234 if
(insert_tree_name
(prod
))
238 prod2
= make_production
(PROD_PARAMETER
, tok
);
239 VARIABLE
(prod2
) = prod
;
245 storage typename NAME LEFT_PARENTHESIS parameters RIGHT_PARENTHESIS SEMICOLON
{
247 struct production
*prod
;
248 struct production
*type
;
249 struct tree_parameter_list
* first_parms
;
250 struct tree_parameter_list
* last_parms
;
251 struct tree_parameter_list
* this_parms
;
252 struct production
*this_parm
;
253 struct production
*this_parm_var
;
255 prod
= make_production
(PROD_FUNCTION_NAME
, $3);
256 SYMBOL_TABLE_NAME
(prod
) = $3;
257 EXPRESSION_TYPE
(prod
) = $2;
258 NUMERIC_TYPE
(prod
) = NUMERIC_TYPE
(( (struct production
*)EXPRESSION_TYPE
(prod
)));
259 PARAMETERS
(prod
) = reverse_prod_list
($5);
260 insert_tree_name
(prod
);
261 STORAGE_CLASS_TOKEN
(prod
) = $1;
263 switch
(STORAGE_CLASS
(prod
))
266 case EXTERNAL_DEFINITION_STORAGE
:
269 case AUTOMATIC_STORAGE
:
270 fprintf
(stderr
, "%s:%i:%i: A function cannot be automatic\n", in_fname
,
271 tok
->lineno
, tok
->charno
);
272 print_token
(stderr
, 0, tok
);
280 type
= EXPRESSION_TYPE
(prod
);
281 /* Create a parameter list in a non-front end specific format. */
282 for
(first_parms
= NULL
, last_parms
= NULL
, this_parm
= PARAMETERS
(prod
);
284 this_parm
= this_parm
->next
)
286 if
(this_parm
->category
!= production_category
)
288 this_parm_var
= VARIABLE
(this_parm
);
291 if
(this_parm_var
->category
!= production_category
)
293 this_parms
= my_malloc
(sizeof
(struct tree_parameter_list
));
294 if
(!this_parm_var
->main_token
)
296 this_parms
->variable_name
= this_parm_var
->main_token
->chars
;
297 this_parms
->type
= NUMERIC_TYPE
(( (struct production
*)EXPRESSION_TYPE
(this_parm_var
)));
300 last_parms
->next
= this_parms
;
301 last_parms
= this_parms
;
305 first_parms
= this_parms
;
306 last_parms
= this_parms
;
308 this_parms
->where_to_put_var_tree
= & (( (struct production
*)VARIABLE
(this_parm
))->code
);
310 FIRST_PARMS
(prod
) = first_parms
;
312 prod
->code
= tree_code_create_function_prototype
313 (tok
->chars
, STORAGE_CLASS
(prod
), NUMERIC_TYPE
(type
),
314 first_parms
, in_fname
, tok
->lineno
);
321 struct production
*proto
;
322 struct production search_prod
;
324 struct production
*this_parm
;
326 SYMBOL_TABLE_NAME
((&search_prod
)) = tok
;
327 current_function
= proto
= lookup_tree_name
(&search_prod
);
330 fprintf
(stderr
, "%s:%i:%i: Function prototype not found\n", in_fname
,
331 tok
->lineno
, tok
->charno
);
332 print_token
(stderr
, 0, tok
);
338 tree_code_create_function_initial
339 (proto
->code
, in_fname
, tok
->lineno
,
340 FIRST_PARMS
(current_function
));
342 /* Check all the parameters have code. */
343 for
(this_parm
= PARAMETERS
(proto
);
345 this_parm
= this_parm
->next
)
347 if
(! (struct production
*)VARIABLE
(this_parm
))
349 if
(! (( (struct production
*)VARIABLE
(this_parm
))->code
))
353 variable_defs_opt statements_opt RIGHT_BRACE
{
356 tree_code_create_function_wrapup
(in_fname
, tok
->lineno
);
357 current_function
= NULL
;
383 |variable_defs variable_def
{
391 struct production
*prod
;
393 prod
= make_production
(PROD_TYPE_NAME
, tok
);
394 NUMERIC_TYPE
(prod
) = SIGNED_INT
;
395 prod
->code
= tree_code_get_type
(NUMERIC_TYPE
(prod
));
400 struct production
*prod
;
402 prod
= make_production
(PROD_TYPE_NAME
, tok
);
403 NUMERIC_TYPE
(prod
) = UNSIGNED_INT
;
404 prod
->code
= tree_code_get_type
(NUMERIC_TYPE
(prod
));
409 struct production
*prod
;
411 prod
= make_production
(PROD_TYPE_NAME
, tok
);
412 NUMERIC_TYPE
(prod
) = SIGNED_CHAR
;
413 prod
->code
= tree_code_get_type
(NUMERIC_TYPE
(prod
));
418 struct production
*prod
;
420 prod
= make_production
(PROD_TYPE_NAME
, tok
);
421 NUMERIC_TYPE
(prod
) = UNSIGNED_CHAR
;
422 prod
->code
= tree_code_get_type
(NUMERIC_TYPE
(prod
));
427 struct production
*prod
;
429 prod
= make_production
(PROD_TYPE_NAME
, tok
);
430 NUMERIC_TYPE
(prod
) = VOID_TYPE
;
431 prod
->code
= tree_code_get_type
(NUMERIC_TYPE
(prod
));
441 |parameters COMMA parameter
{
442 struct production
*prod1
;
444 prod1
->next
= $1; /* Insert in reverse order. */
453 |statements statement
{
459 expression SEMICOLON
{
460 struct production
*exp
;
462 tree_code_output_expression_statement
(exp
->code
, in_fname
, exp
->main_token
->lineno
);
473 IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS
{
475 struct production
*exp
;
478 ensure_not_void
(NUMERIC_TYPE
(exp
), exp
->main_token
);
479 tree_code_if_start
(exp
->code
, in_fname
, tok
->lineno
);
481 LEFT_BRACE statements_opt RIGHT_BRACE
{
482 /* Just let the statements flow. */
487 tree_code_if_else
(in_fname
, tok
->lineno
);
489 LEFT_BRACE statements_opt RIGHT_BRACE
{
492 tree_code_if_end
(in_fname
, tok
->lineno
);
498 RETURN expression_opt
{
499 struct production
*type_prod
;
500 struct token
* ret_tok
;
502 type_prod
= EXPRESSION_TYPE
(current_function
);
503 if
(NUMERIC_TYPE
(type_prod
) == VOID
)
505 tree_code_generate_return
(type_prod
->code
, NULL
);
508 fprintf
(stderr
, "%s:%i:%i: Redundant expression in return\n", in_fname
,
509 ret_tok
->lineno
, ret_tok
->charno
);
510 print_token
(stderr
, 0, ret_tok
);
512 tree_code_generate_return
(type_prod
->code
, NULL
);
517 fprintf
(stderr
, "%s:%i:%i: Expression missing in return\n", in_fname
,
518 ret_tok
->lineno
, ret_tok
->charno
);
519 print_token
(stderr
, 0, ret_tok
);
524 struct production
*exp
;
526 /* Check same type. */
527 if
(check_type_match
(NUMERIC_TYPE
(type_prod
), $2))
529 if
(!type_prod
->code
)
533 /* Generate the code. */
534 tree_code_generate_return
(type_prod
->code
, exp
->code
);
545 struct production
*exp
;
556 $$
= make_integer_constant
($1);
561 |expression PLUS expression
{
563 struct production
*prod
;
564 struct production
*op1
;
565 struct production
*op2
;
571 ensure_not_void
(NUMERIC_TYPE
(op1
), op1
->main_token
);
572 ensure_not_void
(NUMERIC_TYPE
(op2
), op2
->main_token
);
573 prod
= make_production
(PROD_PLUS_EXPRESSION
, tok
);
574 NUMERIC_TYPE
(prod
) = get_common_type
(op1
, op2
);
575 if
(!NUMERIC_TYPE
(prod
))
579 type
= get_type_for_numeric_type
(NUMERIC_TYPE
(prod
));
585 prod
->code
= tree_code_get_expression
586 (EXP_PLUS
, type
, op1
->code
, op2
->code
, NULL
);
590 |expression MINUS expression %prec PLUS
{
592 struct production
*prod
;
593 struct production
*op1
;
594 struct production
*op2
;
599 ensure_not_void
(NUMERIC_TYPE
(op1
), op1
->main_token
);
600 ensure_not_void
(NUMERIC_TYPE
(op2
), op2
->main_token
);
602 prod
= make_production
(PROD_PLUS_EXPRESSION
, tok
);
603 NUMERIC_TYPE
(prod
) = get_common_type
(op1
, op2
);
604 if
(!NUMERIC_TYPE
(prod
))
608 type
= get_type_for_numeric_type
(NUMERIC_TYPE
(prod
));
614 prod
->code
= tree_code_get_expression
(EXP_MINUS
,
615 type
, op1
->code
, op2
->code
, NULL
);
619 |expression EQUALS expression
{
621 struct production
*prod
;
622 struct production
*op1
;
623 struct production
*op2
;
628 ensure_not_void
(NUMERIC_TYPE
(op1
), op1
->main_token
);
629 ensure_not_void
(NUMERIC_TYPE
(op2
), op2
->main_token
);
631 prod
= make_production
(PROD_PLUS_EXPRESSION
, tok
);
632 NUMERIC_TYPE
(prod
) = SIGNED_INT
;
633 if
(!NUMERIC_TYPE
(prod
))
637 type
= get_type_for_numeric_type
(NUMERIC_TYPE
(prod
));
643 prod
->code
= tree_code_get_expression
(EXP_EQUALS
,
644 type
, op1
->code
, op2
->code
, NULL
);
648 |variable_ref ASSIGN expression
{
650 struct production
*prod
;
651 struct production
*op1
;
652 struct production
*op2
;
658 ensure_not_void
(NUMERIC_TYPE
(op2
), op2
->main_token
);
659 prod
= make_production
(PROD_ASSIGN_EXPRESSION
, tok
);
660 NUMERIC_TYPE
(prod
) = NUMERIC_TYPE
(op1
);
661 if
(!NUMERIC_TYPE
(prod
))
665 type
= get_type_for_numeric_type
(NUMERIC_TYPE
(prod
));
670 prod
->code
= tree_code_get_expression
(EXP_ASSIGN
,
671 type
, op1
->code
, op2
->code
, NULL
);
675 |function_invocation
{
681 NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS
{
682 struct production
*prod
;
684 struct production search_prod
;
685 struct production
*proto
;
686 struct production
*exp
;
687 struct production
*exp_proto
;
688 struct production
*var
;
695 prod
= make_production
(PROD_FUNCTION_INVOCATION
, tok
);
696 SYMBOL_TABLE_NAME
(prod
) = tok
;
697 PARAMETERS
(prod
) = reverse_prod_list
($3);
698 SYMBOL_TABLE_NAME
((&search_prod
)) = tok
;
699 proto
= lookup_tree_name
(&search_prod
);
702 fprintf
(stderr
, "%s:%i:%i: Function prototype not found\n", in_fname
,
703 tok
->lineno
, tok
->charno
);
704 print_token
(stderr
, 0, tok
);
708 EXPRESSION_TYPE
(prod
) = EXPRESSION_TYPE
(proto
);
709 NUMERIC_TYPE
(prod
) = NUMERIC_TYPE
(proto
);
710 /* Count the expressions and ensure they match the prototype. */
711 for
(exp_proto_count
= 0, exp_proto
= PARAMETERS
(proto
);
712 exp_proto
; exp_proto
= exp_proto
->next
)
715 for
(exp_count
= 0, exp
= PARAMETERS
(prod
); exp
; exp
= exp
->next
)
718 if
(exp_count
!= exp_proto_count
)
720 fprintf
(stderr
, "%s:%i:%i: expression count mismatch with prototype\n", in_fname
,
721 tok
->lineno
, tok
->charno
);
722 print_token
(stderr
, 0, tok
);
726 parms
= tree_code_init_parameters
();
727 for
(exp_proto
= PARAMETERS
(proto
), exp
= PARAMETERS
(prod
);
729 exp
= exp
->next
, exp_proto
= exp_proto
->next
)
737 var
= VARIABLE
(exp_proto
);
742 parms
= tree_code_add_parameter
(parms
, var
->code
, exp
->code
);
744 type
= get_type_for_numeric_type
(NUMERIC_TYPE
(prod
));
745 prod
->code
= tree_code_get_expression
746 (EXP_FUNCTION_INVOCATION
, type
, proto
->code
, parms
, NULL
);
751 expressions_with_commas:
753 struct production
*exp
;
755 ensure_not_void
(NUMERIC_TYPE
(exp
), exp
->main_token
);
758 |expressions_with_commas COMMA expression
{
759 struct production
*exp
;
761 ensure_not_void
(NUMERIC_TYPE
(exp
), exp
->main_token
);
762 exp
->next
= $1; /* Reverse order. */
769 struct production search_prod
;
770 struct production
*prod
;
771 struct production
*symbol_table_entry
;
776 SYMBOL_TABLE_NAME
((&search_prod
)) = tok
;
777 symbol_table_entry
= lookup_tree_name
(&search_prod
);
778 if
(!symbol_table_entry
)
780 fprintf
(stderr
, "%s:%i:%i: Variable referred to but not defined\n", in_fname
,
781 tok
->lineno
, tok
->charno
);
782 print_token
(stderr
, 0, tok
);
787 prod
= make_production
(PROD_VARIABLE_REFERENCE_EXPRESSION
, tok
);
788 NUMERIC_TYPE
(prod
) = NUMERIC_TYPE
(symbol_table_entry
);
789 type
= get_type_for_numeric_type
(NUMERIC_TYPE
(prod
));
790 if
(!NUMERIC_TYPE
(prod
))
794 prod
->code
= tree_code_get_expression
(EXP_REFERENCE
, type
,
795 symbol_table_entry
->code
, NULL
, NULL
);
809 ASSIGN init_element
{
815 $$
= make_integer_constant
($1);
821 /* Print a token VALUE to file FILE. Ignore TYPE which is the token
825 print_token
(FILE * file
, unsigned int type ATTRIBUTE_UNUSED
, YYSTYPE value
)
831 fprintf
(file
, "%d \"", tok
->lineno
);
832 for
(ix
= 0; ix
< tok
->length
; ix
++)
833 fprintf
(file
, "%c", tok
->chars
[ix
]);
834 fprintf
(file
, "\"");
837 /* Output a message ERROR_MESSAGE from the parser. */
839 yyerror (const char *error_message
)
846 fprintf
(stderr
, "%s:%i:%i: %s\n", in_fname
, tok
->lineno
, tok
->charno
, error_message
);
847 print_token
(stderr
, 0, tok
);
850 fprintf
(stderr
, "%s\n", error_message
);
856 /* Reverse the order of a token list, linked by parse_next, old first
857 token is OLD_FIRST. */
859 static struct production
*
860 reverse_prod_list
(struct production
*old_first
)
862 struct production
*current
;
863 struct production
*next
;
864 struct production
*prev
= NULL
;
871 if
(current
->category
!= production_category
)
873 next
= current
->next
;
874 current
->next
= prev
;
881 /* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
884 ensure_not_void
(unsigned int type
, struct token
* name
)
888 fprintf
(stderr
, "%s:%i:%i: Type must not be void in this context\n", in_fname
,
889 name
->lineno
, name
->charno
);
890 print_token
(stderr
, 0, name
);
895 /* Check TYPE1 and TYPE2 which are integral types. Return the lowest
896 common type (min is signed int). */
899 get_common_type
(struct production
*type1
, struct production
*type2
)
901 if
(NUMERIC_TYPE
(type1
) == UNSIGNED_INT
)
903 if
(NUMERIC_TYPE
(type2
) == UNSIGNED_INT
)
909 /* Check type (TYPE_NUM) and expression (EXP) match. Return the 1 if
910 OK else 0. Must be exact match - same name unless it is an
914 check_type_match
(int type_num
, struct production
*exp
)
922 switch
(NUMERIC_TYPE
(exp
))
947 /* Make a production for an integer constant VALUE. */
949 static struct production
*
950 make_integer_constant
(struct token
* value
)
953 struct production
*prod
;
955 prod
= make_production
(PROD_INTEGER_CONSTANT
, tok
);
956 if
((tok
->chars
[0] == (unsigned char)'-')||
(tok
->chars
[0] == (unsigned char)'+'))
957 NUMERIC_TYPE
(prod
) = SIGNED_INT
;
959 NUMERIC_TYPE
(prod
) = UNSIGNED_INT
;
960 prod
->code
= tree_code_get_integer_value
(tok
->chars
, tok
->length
);
964 /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
967 set_storage
(struct production
*prod
)
969 struct token
* stg_class
;
970 stg_class
= STORAGE_CLASS_TOKEN
(prod
);
971 switch
(stg_class
->type
)
974 STORAGE_CLASS
(prod
) = STATIC_STORAGE
;
978 STORAGE_CLASS
(prod
) = AUTOMATIC_STORAGE
;
981 case EXTERNAL_DEFINITION
:
982 STORAGE_CLASS
(prod
) = EXTERNAL_DEFINITION_STORAGE
;
985 case EXTERNAL_REFERENCE
:
986 STORAGE_CLASS
(prod
) = EXTERNAL_REFERENCE_STORAGE
;
994 /* Set parse trace. */
997 treelang_debug
(void)
999 if
(option_parser_trace
)