1 /* Parser grammar for quick source code scan of Java(TM) language programs.
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3 Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 /* This file parses Java source code. Action can be further completed
27 to achieve a desired behavior. This file isn't part of the Java
28 language gcc front end.
30 The grammar conforms to the Java grammar described in "The Java(TM)
31 Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
32 1996, ISBN 0-201-63451-1"
34 Some rules have been modified to support JDK1.1 inner classes
35 definitions and other extensions. */
46 extern char *input_filename;
47 extern FILE *finput, *out;
49 /* Obstack for the lexer. */
50 struct obstack temporary_obstack;
52 /* The current parser context. */
53 static struct parser_ctxt *ctxp;
55 /* Error and warning counts, current line number, because they're used
58 int java_warning_count;
61 /* Tweak default rules when necessary. */
63 #define USE_ABSORBER absorber = 0
65 /* Keep track of the current class name and package name. */
66 static const char *current_class;
67 static const char *package_name;
69 /* Keep track of whether things have be listed before. */
70 static int previous_output;
72 /* Record modifier uses */
73 static int modifier_value;
75 /* Keep track of number of bracket pairs after a variable declarator
77 static int bracket_count;
79 /* Record a method declaration */
80 struct method_declarator {
81 const char *method_name;
84 #define NEW_METHOD_DECLARATOR(D,N,A) \
87 (struct method_declarator *)xmalloc (sizeof (struct method_declarator)); \
88 (D)->method_name = (N); \
92 /* Two actions for this grammar */
93 static void report_class_declaration PROTO ((const char *));
94 static void report_main_declaration PROTO ((struct method_declarator *));
102 struct method_declarator *declarator;
103 int value; /* For modifiers */
108 /* Things defined here have to match the order of what's in the
109 binop_lookup table. */
111 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
112 %token LS_TK SRS_TK ZRS_TK
113 %token AND_TK XOR_TK OR_TK
114 %token BOOL_AND_TK BOOL_OR_TK
115 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
117 /* This maps to the same binop_lookup entry than the token above */
119 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
121 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
122 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
125 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
127 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
128 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
129 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
130 %token PAD_TK ABSTRACT_TK MODIFIER_TK
132 /* Keep those two in order, too */
133 %token DECR_TK INCR_TK
135 /* From now one, things can be in any order */
137 %token DEFAULT_TK IF_TK THROW_TK
138 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
139 %token THROWS_TK BREAK_TK IMPORT_TK
140 %token ELSE_TK INSTANCEOF_TK RETURN_TK
141 %token VOID_TK CATCH_TK INTERFACE_TK
142 %token CASE_TK EXTENDS_TK FINALLY_TK
143 %token SUPER_TK WHILE_TK CLASS_TK
144 %token SWITCH_TK CONST_TK TRY_TK
145 %token FOR_TK NEW_TK CONTINUE_TK
146 %token GOTO_TK PACKAGE_TK THIS_TK
148 %token BYTE_TK SHORT_TK INT_TK LONG_TK
149 %token CHAR_TK INTEGRAL_TK
151 %token FLOAT_TK DOUBLE_TK FP_TK
155 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
157 %token ASSIGN_ANY_TK ASSIGN_TK
158 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
160 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
161 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
163 %type <node> ID_TK identifier name simple_name qualified_name type
164 primitive_type reference_type array_type formal_parameter_list
165 formal_parameter class_or_interface_type class_type interface_type
166 %type <declarator> method_declarator
167 %type <value> MODIFIER_TK
170 /* 19.2 Production from 2.3: The Syntactic Grammar */
175 /* 19.3 Productions from 3: Lexical structure */
185 /* 19.4 Productions from 4: Types, Values and Variables */
194 /* use preset global here. FIXME */
195 $$ = xstrdup ("int");
199 /* use preset global here. FIXME */
200 $$ = xstrdup ("double");
204 /* use preset global here. FIXME */
205 $$ = xstrdup ("boolean");
210 class_or_interface_type
214 class_or_interface_type:
219 class_or_interface_type /* Default rule */
223 class_or_interface_type
227 primitive_type OSB_TK CSB_TK
230 char *n = xmalloc (strlen ($1)+2);
235 | array_type OSB_TK CSB_TK
237 char *n = xmalloc (strlen ($1)+2);
244 /* 19.5 Productions from 6: Names */
246 simple_name /* Default rule */
247 | qualified_name /* Default rule */
251 identifier /* Default rule */
255 name DOT_TK identifier
257 char *n = xmalloc (strlen ($1)+strlen ($3)+2);
258 sprintf (n, "%s.%s", $1, $3);
267 /* 19.6: Production from 7: Packages */
269 | package_declaration
270 | import_declarations
272 | package_declaration import_declarations
273 | package_declaration type_declarations
274 | import_declarations type_declarations
275 | package_declaration import_declarations type_declarations
280 | import_declarations import_declaration
285 | type_declarations type_declaration
289 PACKAGE_TK name SC_TK
290 { package_name = $2; }
294 single_type_import_declaration
295 | type_import_on_demand_declaration
298 single_type_import_declaration:
302 type_import_on_demand_declaration:
303 IMPORT_TK name DOT_TK MULT_TK SC_TK
308 | interface_declaration
312 /* 19.7 Shortened from the original:
313 modifiers: modifier | modifiers modifier
314 modifier: any of public... */
324 | modifiers MODIFIER_TK
334 /* 19.8.1 Production from $8.1: Class Declaration */
336 modifiers CLASS_TK identifier super interfaces
338 report_class_declaration($3);
342 | CLASS_TK identifier super interfaces
343 { report_class_declaration($2); }
348 | EXTENDS_TK class_type
352 | IMPLEMENTS_TK interface_type_list
358 | interface_type_list C_TK interface_type
364 | OCB_TK class_body_declarations CCB_TK
367 class_body_declarations:
368 class_body_declaration
369 | class_body_declarations class_body_declaration
372 class_body_declaration:
373 class_member_declaration
375 | constructor_declaration
376 | block /* Added, JDK1.1, instance initializer */
379 class_member_declaration:
382 | class_declaration /* Added, JDK1.1 inner classes */
383 | interface_declaration /* Added, JDK1.1 inner classes */
386 /* 19.8.2 Productions from 8.3: Field Declarations */
388 type variable_declarators SC_TK
390 | modifiers type variable_declarators SC_TK
391 { modifier_value = 0; }
394 variable_declarators:
395 /* Should we use build_decl_list () instead ? FIXME */
396 variable_declarator /* Default rule */
397 | variable_declarators C_TK variable_declarator
401 variable_declarator_id
402 | variable_declarator_id ASSIGN_TK variable_initializer
405 variable_declarator_id:
407 { bracket_count = 0; USE_ABSORBER; }
408 | variable_declarator_id OSB_TK CSB_TK
412 variable_initializer:
417 /* 19.8.3 Productions from 8.4: Method Declarations */
419 method_header method_body
423 type method_declarator throws
425 | VOID_TK method_declarator throws
426 | modifiers type method_declarator throws
427 { modifier_value = 0; }
428 | modifiers VOID_TK method_declarator throws
430 report_main_declaration ($3);
436 identifier OP_TK CP_TK
438 struct method_declarator *d;
439 NEW_METHOD_DECLARATOR (d, $1, NULL);
442 | identifier OP_TK formal_parameter_list CP_TK
444 struct method_declarator *d;
445 NEW_METHOD_DECLARATOR (d, $1, $3);
448 | method_declarator OSB_TK CSB_TK
451 formal_parameter_list:
453 | formal_parameter_list C_TK formal_parameter
455 char *n = xmalloc (strlen ($1)+strlen($3)+2);
456 sprintf (n, "%s,%s", $1, $3);
462 type variable_declarator_id
468 char *n = xmalloc (bracket_count + 1 + strlen ($$));
469 for (i = 0; i < bracket_count; ++i)
471 strcpy (n + bracket_count, $$);
477 | modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
482 char *n = xmalloc (bracket_count + 1 + strlen ($$));
483 for (i = 0; i < bracket_count; ++i)
485 strcpy (n + bracket_count, $$);
494 | THROWS_TK class_type_list
500 | class_type_list C_TK class_type
510 /* 19.8.4 Productions from 8.5: Static Initializers */
513 | static block SC_TK /* Shouldn't be here. FIXME */
516 static: /* Test lval.sub_token here */
521 /* 19.8.5 Productions from 8.6: Constructor Declarations */
522 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
523 - If a forbidded modifier is found, the the error is either the use of
524 a forbidded modifier for a constructor OR bogus attempt to declare a
525 method without having specified the return type. FIXME */
526 constructor_declaration:
527 constructor_declarator throws constructor_body
528 | modifiers constructor_declarator throws constructor_body
529 { modifier_value = 0; }
530 /* extra SC_TK, FIXME */
531 | constructor_declarator throws constructor_body SC_TK
532 /* extra SC_TK, FIXME */
533 | modifiers constructor_declarator throws constructor_body SC_TK
534 { modifier_value = 0; }
535 /* I'm not happy with the SC_TK addition. It isn't in the grammer and should
536 probably be matched by and empty statement. But it doesn't work. FIXME */
539 constructor_declarator:
540 simple_name OP_TK CP_TK
542 | simple_name OP_TK formal_parameter_list CP_TK
548 | OCB_TK explicit_constructor_invocation CCB_TK
549 | OCB_TK block_statements CCB_TK
550 | OCB_TK explicit_constructor_invocation block_statements CCB_TK
553 /* Error recovery for that rule moved down expression_statement: rule. */
554 explicit_constructor_invocation:
555 this_or_super OP_TK CP_TK SC_TK
556 | this_or_super OP_TK argument_list CP_TK SC_TK
557 /* Added, JDK1.1 inner classes. Modified because the rule
558 'primary' couldn't work. */
559 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
561 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
565 this_or_super: /* Added, simplifies error diagnostics */
570 /* 19.9 Productions from 9: Interfaces */
571 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
572 interface_declaration:
573 INTERFACE_TK identifier interface_body
574 { report_class_declaration ($2); modifier_value = 0; }
575 | modifiers INTERFACE_TK identifier interface_body
576 { report_class_declaration ($3); modifier_value = 0; }
577 | INTERFACE_TK identifier extends_interfaces interface_body
578 { report_class_declaration ($2); modifier_value = 0; }
579 | modifiers INTERFACE_TK identifier extends_interfaces interface_body
580 { report_class_declaration ($3); modifier_value = 0; }
584 EXTENDS_TK interface_type
585 | extends_interfaces C_TK interface_type
590 | OCB_TK interface_member_declarations CCB_TK
593 interface_member_declarations:
594 interface_member_declaration
595 | interface_member_declarations interface_member_declaration
598 interface_member_declaration:
600 | abstract_method_declaration
601 | class_declaration /* Added, JDK1.1 inner classes */
602 | interface_declaration /* Added, JDK1.1 inner classes */
605 constant_declaration:
609 abstract_method_declaration:
613 /* 19.10 Productions from 10: Arrays */
616 | OCB_TK variable_initializers CCB_TK
618 | OCB_TK variable_initializers C_TK CCB_TK
621 variable_initializers:
623 | variable_initializers C_TK variable_initializer
626 /* 19.11 Production from 14: Blocks and Statements */
629 | OCB_TK block_statements CCB_TK
634 | block_statements block_statement
638 local_variable_declaration_statement
640 | class_declaration /* Added, JDK1.1 inner classes */
643 local_variable_declaration_statement:
644 local_variable_declaration SC_TK /* Can't catch missing ';' here */
647 local_variable_declaration:
648 type variable_declarators
650 | modifiers type variable_declarators /* Added, JDK1.1 final locals */
651 { modifier_value = 0; }
655 statement_without_trailing_substatement
658 | if_then_else_statement
664 statement_without_trailing_substatement
665 | labeled_statement_nsi
666 | if_then_else_statement_nsi
667 | while_statement_nsi
671 statement_without_trailing_substatement:
674 | expression_statement
680 | synchronized_statement
698 labeled_statement_nsi:
699 label_decl statement_nsi
702 /* We concentrate here a bunch of error handling rules that we couldn't write
703 earlier, because expression_statement catches a missing ';'. */
704 expression_statement:
705 statement_expression SC_TK
708 statement_expression:
710 | pre_increment_expression
711 | pre_decrement_expression
712 | post_increment_expression
713 | post_decrement_expression
715 | class_instance_creation_expression
719 IF_TK OP_TK expression CP_TK statement
722 if_then_else_statement:
723 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
726 if_then_else_statement_nsi:
727 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
731 SWITCH_TK OP_TK expression CP_TK switch_block
736 | OCB_TK switch_labels CCB_TK
737 | OCB_TK switch_block_statement_groups CCB_TK
738 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
741 switch_block_statement_groups:
742 switch_block_statement_group
743 | switch_block_statement_groups switch_block_statement_group
746 switch_block_statement_group:
747 switch_labels block_statements
753 | switch_labels switch_label
757 CASE_TK constant_expression REL_CL_TK
758 | DEFAULT_TK REL_CL_TK
762 WHILE_TK OP_TK expression CP_TK
766 while_expression statement
770 while_expression statement_nsi
778 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
782 for_begin SC_TK expression SC_TK for_update CP_TK statement
783 | for_begin SC_TK SC_TK for_update CP_TK statement
787 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
788 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
798 for_init: /* Can be empty */
799 | statement_expression_list
800 | local_variable_declaration
803 for_update: /* Can be empty */
804 | statement_expression_list
807 statement_expression_list:
809 | statement_expression_list C_TK statement_expression
814 | BREAK_TK identifier SC_TK
819 | CONTINUE_TK identifier SC_TK
824 | RETURN_TK expression SC_TK
828 THROW_TK expression SC_TK
831 synchronized_statement:
832 synchronized OP_TK expression CP_TK block
833 | synchronized OP_TK expression CP_TK error
836 synchronized: /* Test lval.sub_token here */
843 | TRY_TK block finally
844 | TRY_TK block catches finally
849 | catches catch_clause
853 CATCH_TK OP_TK formal_parameter CP_TK block
860 /* 19.12 Production from 15: Expressions */
863 | array_creation_expression
866 primary_no_new_array:
869 | OP_TK expression CP_TK
870 | class_instance_creation_expression
874 /* type DOT_TK CLASS_TK doens't work. So we split the rule
875 'type' into its components. Missing is something for array,
876 which will complete the reference_type part. FIXME */
877 | name DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
879 | primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
881 | VOID_TK DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
882 /* Added, JDK1.1 inner classes. Documentation is wrong
883 refering to a 'ClassName' (class_name) rule that doesn't
884 exist. Used name instead. */
885 | name DOT_TK THIS_TK
889 class_instance_creation_expression:
890 NEW_TK class_type OP_TK argument_list CP_TK
891 | NEW_TK class_type OP_TK CP_TK
892 /* Added, JDK1.1 inner classes but modified to use
893 'class_type' instead of 'TypeName' (type_name) mentionned
894 in the documentation but doesn't exist. */
895 | NEW_TK class_type OP_TK argument_list CP_TK class_body
896 | NEW_TK class_type OP_TK CP_TK class_body
897 /* Added, JDK1.1 inner classes, modified to use name or
898 primary instead of primary solely which couldn't work in
900 | something_dot_new identifier OP_TK CP_TK
901 | something_dot_new identifier OP_TK CP_TK class_body
902 | something_dot_new identifier OP_TK argument_list CP_TK
903 | something_dot_new identifier OP_TK argument_list CP_TK class_body
906 something_dot_new: /* Added, not part of the specs. */
909 | primary DOT_TK NEW_TK
914 | argument_list C_TK expression
915 | argument_list C_TK error
918 array_creation_expression:
919 NEW_TK primitive_type dim_exprs
920 | NEW_TK class_or_interface_type dim_exprs
921 | NEW_TK primitive_type dim_exprs dims
922 | NEW_TK class_or_interface_type dim_exprs dims
923 /* Added, JDK1.1 anonymous array. Initial documentation rule
925 | NEW_TK class_or_interface_type dims array_initializer
926 | NEW_TK primitive_type dims array_initializer
935 OSB_TK expression CSB_TK
944 primary DOT_TK identifier
945 | SUPER_TK DOT_TK identifier
951 | name OP_TK argument_list CP_TK
953 | primary DOT_TK identifier OP_TK CP_TK
954 | primary DOT_TK identifier OP_TK argument_list CP_TK
955 | SUPER_TK DOT_TK identifier OP_TK CP_TK
956 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
960 name OSB_TK expression CSB_TK
962 | primary_no_new_array OSB_TK expression CSB_TK
969 | post_increment_expression
970 | post_decrement_expression
973 post_increment_expression:
974 postfix_expression INCR_TK
977 post_decrement_expression:
978 postfix_expression DECR_TK
982 pre_increment_expression
983 | pre_decrement_expression
984 | PLUS_TK unary_expression
985 | MINUS_TK unary_expression
986 | unary_expression_not_plus_minus
989 pre_increment_expression:
990 INCR_TK unary_expression
993 pre_decrement_expression:
994 DECR_TK unary_expression
997 unary_expression_not_plus_minus:
999 | NOT_TK unary_expression
1000 | NEG_TK unary_expression
1004 cast_expression: /* Error handling here is potentially weak */
1005 OP_TK primitive_type dims CP_TK unary_expression
1006 | OP_TK primitive_type CP_TK unary_expression
1007 | OP_TK expression CP_TK unary_expression_not_plus_minus
1008 | OP_TK name dims CP_TK unary_expression_not_plus_minus
1011 multiplicative_expression:
1013 | multiplicative_expression MULT_TK unary_expression
1014 | multiplicative_expression DIV_TK unary_expression
1015 | multiplicative_expression REM_TK unary_expression
1018 additive_expression:
1019 multiplicative_expression
1020 | additive_expression PLUS_TK multiplicative_expression
1021 | additive_expression MINUS_TK multiplicative_expression
1026 | shift_expression LS_TK additive_expression
1027 | shift_expression SRS_TK additive_expression
1028 | shift_expression ZRS_TK additive_expression
1031 relational_expression:
1033 | relational_expression LT_TK shift_expression
1034 | relational_expression GT_TK shift_expression
1035 | relational_expression LTE_TK shift_expression
1036 | relational_expression GTE_TK shift_expression
1037 | relational_expression INSTANCEOF_TK reference_type
1040 equality_expression:
1041 relational_expression
1042 | equality_expression EQ_TK relational_expression
1043 | equality_expression NEQ_TK relational_expression
1048 | and_expression AND_TK equality_expression
1051 exclusive_or_expression:
1053 | exclusive_or_expression XOR_TK and_expression
1056 inclusive_or_expression:
1057 exclusive_or_expression
1058 | inclusive_or_expression OR_TK exclusive_or_expression
1061 conditional_and_expression:
1062 inclusive_or_expression
1063 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
1066 conditional_or_expression:
1067 conditional_and_expression
1068 | conditional_or_expression BOOL_OR_TK conditional_and_expression
1071 conditional_expression: /* Error handling here is weak */
1072 conditional_or_expression
1073 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
1076 assignment_expression:
1077 conditional_expression
1082 left_hand_side assignment_operator assignment_expression
1092 assignment_operator:
1098 assignment_expression
1101 constant_expression:
1109 /* Create a new parser context */
1112 java_push_parser_context ()
1114 struct parser_ctxt *new =
1115 (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
1117 bzero ((PTR) new, sizeof (struct parser_ctxt));
1122 /* Actions defined here */
1125 report_class_declaration (name)
1128 extern int flag_dump_class, flag_list_filename;
1130 if (flag_dump_class)
1132 if (!previous_output)
1134 if (flag_list_filename)
1135 fprintf (out, "%s: ", input_filename);
1136 previous_output = 1;
1140 fprintf (out, "%s.%s ", package_name, name);
1142 fprintf (out, "%s ", name);
1145 current_class = name;
1149 report_main_declaration (declarator)
1150 struct method_declarator *declarator;
1152 extern int flag_find_main;
1155 && modifier_value == 2
1156 && !strcmp (declarator->method_name, "main")
1158 && declarator->args [0] == '['
1159 && (! strcmp (declarator->args+1, "String")
1160 || ! strcmp (declarator->args + 1, "java.lang.String"))
1163 if (!previous_output)
1166 fprintf (out, "%s.%s ", package_name, current_class);
1168 fprintf (out, current_class);
1169 previous_output = 1;
1174 /* Reset global status used by the report functions. */
1176 void reset_report ()
1178 previous_output = 0;
1179 current_class = package_name = NULL;
1184 const char *msg ATTRIBUTE_UNUSED;
1194 ret = xmalloc (strlen (s) + 1);