1 /* Parser grammar for quick source code scan of Java(TM) language programs.
2 Copyright (C) 1998 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. */
44 /* Definitions for PROTO and VPROTO macros */
45 #include "gansidecl.h"
48 extern char *input_filename;
49 extern FILE *finput, *out;
51 /* Obstack for the lexer. */
52 struct obstack temporary_obstack;
54 /* The current parser context. */
55 static struct parser_ctxt *ctxp;
57 /* Error and warning counts, current line number, because they're used
60 int java_warning_count;
63 /* Tweak default rules when necessary. */
65 #define USE_ABSORBER absorber = 0
67 /* Keep track of the current class name and package name. */
68 static char *current_class;
69 static char *package_name;
71 /* Keep track of whether things have be listed before. */
72 static int previous_output;
74 /* Record modifier uses */
75 static int modifier_value;
77 /* Record a method declaration */
78 struct method_declarator {
82 #define NEW_METHOD_DECLARATOR(D,N,A) \
85 (struct method_declarator *)xmalloc (sizeof (struct method_declarator)); \
86 (D)->method_name = (N); \
90 /* Two actions for this grammar */
91 static void report_class_declaration PROTO ((char *));
92 static void report_main_declaration PROTO ((struct method_declarator *));
94 /* Other extern functions */
95 char *xmalloc PROTO ((unsigned));
96 char *xstrdup PROTO ((char *));
104 struct method_declarator *declarator;
105 int value; /* For modifiers */
110 /* Things defined here have to match the order of what's in the
111 binop_lookup table. */
113 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
114 %token LS_TK SRS_TK ZRS_TK
115 %token AND_TK XOR_TK OR_TK
116 %token BOOL_AND_TK BOOL_OR_TK
117 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
119 /* This maps to the same binop_lookup entry than the token above */
121 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
123 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
124 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
127 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
129 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
130 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
131 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
132 %token PAD_TK ABSTRACT_TK MODIFIER_TK
134 /* Keep those two in order, too */
135 %token DECR_TK INCR_TK
137 /* From now one, things can be in any order */
139 %token DEFAULT_TK IF_TK THROW_TK
140 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
141 %token THROWS_TK BREAK_TK IMPORT_TK
142 %token ELSE_TK INSTANCEOF_TK RETURN_TK
143 %token VOID_TK CATCH_TK INTERFACE_TK
144 %token CASE_TK EXTENDS_TK FINALLY_TK
145 %token SUPER_TK WHILE_TK CLASS_TK
146 %token SWITCH_TK CONST_TK TRY_TK
147 %token FOR_TK NEW_TK CONTINUE_TK
148 %token GOTO_TK PACKAGE_TK THIS_TK
150 %token BYTE_TK SHORT_TK INT_TK LONG_TK
151 %token CHAR_TK INTEGRAL_TK
153 %token FLOAT_TK DOUBLE_TK FP_TK
157 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
159 %token ASSIGN_ANY_TK ASSIGN_TK
160 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
162 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
163 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
165 %type <node> ID_TK identifier name simple_name qualified_name type
166 primitive_type reference_type array_type formal_parameter_list
167 formal_parameter class_or_interface_type class_type interface_type
168 %type <declarator> method_declarator
169 %type <value> MODIFIER_TK
172 /* 19.2 Production from 2.3: The Syntactic Grammar */
177 /* 19.3 Productions from 3: Lexical structure */
187 /* 19.4 Productions from 4: Types, Values and Variables */
196 /* use preset global here. FIXME */
197 $$ = xstrdup ("int");
201 /* use preset global here. FIXME */
202 $$ = xstrdup ("double");
206 /* use preset global here. FIXME */
207 $$ = xstrdup ("boolean");
212 class_or_interface_type
216 class_or_interface_type:
221 class_or_interface_type /* Default rule */
225 class_or_interface_type
229 primitive_type OSB_TK CSB_TK
232 char *n = xmalloc (strlen ($1)+2);
237 | array_type OSB_TK CSB_TK
239 char *n = xmalloc (strlen ($1)+2);
246 /* 19.5 Productions from 6: Names */
248 simple_name /* Default rule */
249 | qualified_name /* Default rule */
253 identifier /* Default rule */
257 name DOT_TK identifier
259 char *n = xmalloc (strlen ($1)+strlen ($3)+2);
260 sprintf (n, "%s.s", $1, $3);
269 /* 19.6: Production from 7: Packages */
271 | package_declaration
272 | import_declarations
274 | package_declaration import_declarations
275 | package_declaration type_declarations
276 | import_declarations type_declarations
277 | package_declaration import_declarations type_declarations
282 | import_declarations import_declaration
287 | type_declarations type_declaration
291 PACKAGE_TK name SC_TK
292 { package_name = $2; }
296 single_type_import_declaration
297 | type_import_on_demand_declaration
300 single_type_import_declaration:
304 type_import_on_demand_declaration:
305 IMPORT_TK name DOT_TK MULT_TK SC_TK
310 | interface_declaration
314 /* 19.7 Shortened from the original:
315 modifiers: modifier | modifiers modifier
316 modifier: any of public... */
326 | modifiers MODIFIER_TK
336 /* 19.8.1 Production from $8.1: Class Declaration */
338 modifiers CLASS_TK identifier super interfaces
340 report_class_declaration($3);
344 | CLASS_TK identifier super interfaces
345 { report_class_declaration($2); }
350 | EXTENDS_TK class_type
354 | IMPLEMENTS_TK interface_type_list
360 | interface_type_list C_TK interface_type
366 | OCB_TK class_body_declarations CCB_TK
369 class_body_declarations:
370 class_body_declaration
371 | class_body_declarations class_body_declaration
374 class_body_declaration:
375 class_member_declaration
377 | constructor_declaration
378 | block /* Added, JDK1.1, instance initializer */
381 class_member_declaration:
384 | class_declaration /* Added, JDK1.1 inner classes */
385 | interface_declaration /* Added, JDK1.1 inner classes */
388 /* 19.8.2 Productions from 8.3: Field Declarations */
390 type variable_declarators SC_TK
392 | modifiers type variable_declarators SC_TK
393 { modifier_value = 0; }
396 variable_declarators:
397 /* Should we use build_decl_list () instead ? FIXME */
398 variable_declarator /* Default rule */
399 | variable_declarators C_TK variable_declarator
403 variable_declarator_id
404 | variable_declarator_id ASSIGN_TK variable_initializer
407 variable_declarator_id:
410 | variable_declarator_id OSB_TK CSB_TK
413 variable_initializer:
418 /* 19.8.3 Productions from 8.4: Method Declarations */
420 method_header method_body
424 type method_declarator throws
426 | VOID_TK method_declarator throws
427 | modifiers type method_declarator throws
428 { modifier_value = 0; }
429 | modifiers VOID_TK method_declarator throws
431 report_main_declaration ($3);
437 identifier OP_TK CP_TK
439 struct method_declarator *d;
440 NEW_METHOD_DECLARATOR (d, $1, NULL);
443 | identifier OP_TK formal_parameter_list CP_TK
445 struct method_declarator *d;
446 NEW_METHOD_DECLARATOR (d, $1, $3);
449 | method_declarator OSB_TK CSB_TK
452 formal_parameter_list:
454 | formal_parameter_list C_TK formal_parameter
456 char *n = xmalloc (strlen ($1)+strlen($3)+2);
457 sprintf (n, "%s,%s", $1, $3);
463 type variable_declarator_id
468 | modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
473 | THROWS_TK class_type_list
479 | class_type_list C_TK class_type
489 /* 19.8.4 Productions from 8.5: Static Initializers */
492 | static block SC_TK /* Shouldn't be here. FIXME */
495 static: /* Test lval.sub_token here */
500 /* 19.8.5 Productions from 8.6: Constructor Declarations */
501 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
502 - If a forbidded modifier is found, the the error is either the use of
503 a forbidded modifier for a constructor OR bogus attempt to declare a
504 method without having specified the return type. FIXME */
505 constructor_declaration:
506 constructor_declarator throws constructor_body
507 | modifiers constructor_declarator throws constructor_body
508 { modifier_value = 0; }
509 /* extra SC_TK, FIXME */
510 | constructor_declarator throws constructor_body SC_TK
511 /* extra SC_TK, FIXME */
512 | modifiers constructor_declarator throws constructor_body SC_TK
513 { modifier_value = 0; }
514 /* I'm not happy with the SC_TK addition. It isn't in the grammer and should
515 probably be matched by and empty statement. But it doesn't work. FIXME */
518 constructor_declarator:
519 simple_name OP_TK CP_TK
521 | simple_name OP_TK formal_parameter_list CP_TK
527 | OCB_TK explicit_constructor_invocation CCB_TK
528 | OCB_TK block_statements CCB_TK
529 | OCB_TK explicit_constructor_invocation block_statements CCB_TK
532 /* Error recovery for that rule moved down expression_statement: rule. */
533 explicit_constructor_invocation:
534 this_or_super OP_TK CP_TK SC_TK
535 | this_or_super OP_TK argument_list CP_TK SC_TK
536 /* Added, JDK1.1 inner classes. Modified because the rule
537 'primary' couldn't work. */
538 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
540 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
544 this_or_super: /* Added, simplifies error diagnostics */
549 /* 19.9 Productions from 9: Interfaces */
550 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
551 interface_declaration:
552 INTERFACE_TK identifier interface_body
553 | modifiers INTERFACE_TK identifier interface_body
554 { modifier_value = 0; }
555 | INTERFACE_TK identifier extends_interfaces interface_body
556 | modifiers INTERFACE_TK identifier extends_interfaces interface_body
557 { modifier_value = 0; }
561 EXTENDS_TK interface_type
562 | extends_interfaces C_TK interface_type
567 | OCB_TK interface_member_declarations CCB_TK
570 interface_member_declarations:
571 interface_member_declaration
572 | interface_member_declarations interface_member_declaration
575 interface_member_declaration:
577 | abstract_method_declaration
578 | class_declaration /* Added, JDK1.1 inner classes */
579 | interface_declaration /* Added, JDK1.1 inner classes */
582 constant_declaration:
586 abstract_method_declaration:
590 /* 19.10 Productions from 10: Arrays */
593 | OCB_TK variable_initializers CCB_TK
595 | OCB_TK variable_initializers C_TK CCB_TK
598 variable_initializers:
600 | variable_initializers C_TK variable_initializer
603 /* 19.11 Production from 14: Blocks and Statements */
606 | OCB_TK block_statements CCB_TK
611 | block_statements block_statement
615 local_variable_declaration_statement
617 | class_declaration /* Added, JDK1.1 inner classes */
620 local_variable_declaration_statement:
621 local_variable_declaration SC_TK /* Can't catch missing ';' here */
624 local_variable_declaration:
625 type variable_declarators
627 | modifiers type variable_declarators /* Added, JDK1.1 final locals */
628 { modifier_value = 0; }
632 statement_without_trailing_substatement
635 | if_then_else_statement
641 statement_without_trailing_substatement
642 | labeled_statement_nsi
643 | if_then_else_statement_nsi
644 | while_statement_nsi
648 statement_without_trailing_substatement:
651 | expression_statement
657 | synchronized_statement
675 labeled_statement_nsi:
676 label_decl statement_nsi
679 /* We concentrate here a bunch of error handling rules that we couldn't write
680 earlier, because expression_statement catches a missing ';'. */
681 expression_statement:
682 statement_expression SC_TK
685 statement_expression:
687 | pre_increment_expression
688 | pre_decrement_expression
689 | post_increment_expression
690 | post_decrement_expression
692 | class_instance_creation_expression
696 IF_TK OP_TK expression CP_TK statement
699 if_then_else_statement:
700 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
703 if_then_else_statement_nsi:
704 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
708 SWITCH_TK OP_TK expression CP_TK switch_block
713 | OCB_TK switch_labels CCB_TK
714 | OCB_TK switch_block_statement_groups CCB_TK
715 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
718 switch_block_statement_groups:
719 switch_block_statement_group
720 | switch_block_statement_groups switch_block_statement_group
723 switch_block_statement_group:
724 switch_labels block_statements
730 | switch_labels switch_label
734 CASE_TK constant_expression REL_CL_TK
735 | DEFAULT_TK REL_CL_TK
739 WHILE_TK OP_TK expression CP_TK
743 while_expression statement
747 while_expression statement_nsi
755 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
759 for_begin SC_TK expression SC_TK for_update CP_TK statement
760 | for_begin SC_TK SC_TK for_update CP_TK statement
764 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
765 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
775 for_init: /* Can be empty */
776 | statement_expression_list
777 | local_variable_declaration
780 for_update: /* Can be empty */
781 | statement_expression_list
784 statement_expression_list:
786 | statement_expression_list C_TK statement_expression
791 | BREAK_TK identifier SC_TK
796 | CONTINUE_TK identifier SC_TK
801 | RETURN_TK expression SC_TK
805 THROW_TK expression SC_TK
808 synchronized_statement:
809 synchronized OP_TK expression CP_TK block
810 | synchronized OP_TK expression CP_TK error
813 synchronized: /* Test lval.sub_token here */
820 | TRY_TK block finally
821 | TRY_TK block catches finally
826 | catches catch_clause
830 CATCH_TK OP_TK formal_parameter CP_TK block
837 /* 19.12 Production from 15: Expressions */
840 | array_creation_expression
843 primary_no_new_array:
846 | OP_TK expression CP_TK
847 | class_instance_creation_expression
851 /* type DOT_TK CLASS_TK doens't work. So we split the rule
852 'type' into its components. Missing is something for array,
853 which will complete the reference_type part. FIXME */
854 | name DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
856 | primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
858 | VOID_TK DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
859 /* Added, JDK1.1 inner classes. Documentation is wrong
860 refering to a 'ClassName' (class_name) rule that doesn't
861 exist. Used name instead. */
862 | name DOT_TK THIS_TK
866 class_instance_creation_expression:
867 NEW_TK class_type OP_TK argument_list CP_TK
868 | NEW_TK class_type OP_TK CP_TK
869 /* Added, JDK1.1 inner classes but modified to use
870 'class_type' instead of 'TypeName' (type_name) mentionned
871 in the documentation but doesn't exist. */
872 | NEW_TK class_type OP_TK argument_list CP_TK class_body
873 | NEW_TK class_type OP_TK CP_TK class_body
874 /* Added, JDK1.1 inner classes, modified to use name or
875 primary instead of primary solely which couldn't work in
877 | something_dot_new identifier OP_TK CP_TK
878 | something_dot_new identifier OP_TK CP_TK class_body
879 | something_dot_new identifier OP_TK argument_list CP_TK
880 | something_dot_new identifier OP_TK argument_list CP_TK class_body
883 something_dot_new: /* Added, not part of the specs. */
886 | primary DOT_TK NEW_TK
891 | argument_list C_TK expression
892 | argument_list C_TK error
895 array_creation_expression:
896 NEW_TK primitive_type dim_exprs
897 | NEW_TK class_or_interface_type dim_exprs
898 | NEW_TK primitive_type dim_exprs dims
899 | NEW_TK class_or_interface_type dim_exprs dims
900 /* Added, JDK1.1 anonymous array. Initial documentation rule
902 | NEW_TK class_or_interface_type dims array_initializer
903 | NEW_TK primitive_type dims array_initializer
912 OSB_TK expression CSB_TK
921 primary DOT_TK identifier
922 | SUPER_TK DOT_TK identifier
928 | name OP_TK argument_list CP_TK
930 | primary DOT_TK identifier OP_TK CP_TK
931 | primary DOT_TK identifier OP_TK argument_list CP_TK
932 | SUPER_TK DOT_TK identifier OP_TK CP_TK
933 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
937 name OSB_TK expression CSB_TK
939 | primary_no_new_array OSB_TK expression CSB_TK
946 | post_increment_expression
947 | post_decrement_expression
950 post_increment_expression:
951 postfix_expression INCR_TK
954 post_decrement_expression:
955 postfix_expression DECR_TK
959 pre_increment_expression
960 | pre_decrement_expression
961 | PLUS_TK unary_expression
962 | MINUS_TK unary_expression
963 | unary_expression_not_plus_minus
966 pre_increment_expression:
967 INCR_TK unary_expression
970 pre_decrement_expression:
971 DECR_TK unary_expression
974 unary_expression_not_plus_minus:
976 | NOT_TK unary_expression
977 | NEG_TK unary_expression
981 cast_expression: /* Error handling here is potentially weak */
982 OP_TK primitive_type dims CP_TK unary_expression
983 | OP_TK primitive_type CP_TK unary_expression
984 | OP_TK expression CP_TK unary_expression_not_plus_minus
985 | OP_TK name dims CP_TK unary_expression_not_plus_minus
988 multiplicative_expression:
990 | multiplicative_expression MULT_TK unary_expression
991 | multiplicative_expression DIV_TK unary_expression
992 | multiplicative_expression REM_TK unary_expression
996 multiplicative_expression
997 | additive_expression PLUS_TK multiplicative_expression
998 | additive_expression MINUS_TK multiplicative_expression
1003 | shift_expression LS_TK additive_expression
1004 | shift_expression SRS_TK additive_expression
1005 | shift_expression ZRS_TK additive_expression
1008 relational_expression:
1010 | relational_expression LT_TK shift_expression
1011 | relational_expression GT_TK shift_expression
1012 | relational_expression LTE_TK shift_expression
1013 | relational_expression GTE_TK shift_expression
1014 | relational_expression INSTANCEOF_TK reference_type
1017 equality_expression:
1018 relational_expression
1019 | equality_expression EQ_TK relational_expression
1020 | equality_expression NEQ_TK relational_expression
1025 | and_expression AND_TK equality_expression
1028 exclusive_or_expression:
1030 | exclusive_or_expression XOR_TK and_expression
1033 inclusive_or_expression:
1034 exclusive_or_expression
1035 | inclusive_or_expression OR_TK exclusive_or_expression
1038 conditional_and_expression:
1039 inclusive_or_expression
1040 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
1043 conditional_or_expression:
1044 conditional_and_expression
1045 | conditional_or_expression BOOL_OR_TK conditional_and_expression
1048 conditional_expression: /* Error handling here is weak */
1049 conditional_or_expression
1050 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
1053 assignment_expression:
1054 conditional_expression
1059 left_hand_side assignment_operator assignment_expression
1069 assignment_operator:
1075 assignment_expression
1078 constant_expression:
1086 /* Create a new parser context */
1089 java_push_parser_context ()
1091 struct parser_ctxt *new =
1092 (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
1094 bzero (new, sizeof (struct parser_ctxt));
1099 /* Actions defined here */
1102 report_class_declaration (name)
1105 extern int flag_dump_class, flag_list_filename;
1107 if (flag_dump_class)
1109 if (!previous_output)
1111 if (flag_list_filename)
1112 fprintf (out, "%s: ", input_filename);
1113 previous_output = 1;
1117 fprintf (out, "%s.%s ", package_name, name);
1119 fprintf (out, "%s ", name);
1122 current_class = name;
1126 report_main_declaration (declarator)
1127 struct method_declarator *declarator;
1129 extern int flag_find_main;
1132 && modifier_value == 2
1133 && !strcmp (declarator->method_name, "main")
1135 && declarator->args [0] == '['
1136 && !strcmp( declarator->args+1, "String")
1139 if (!previous_output)
1142 fprintf (out, "%s.%s ", package_name, current_class);
1144 fprintf (out, current_class);
1145 previous_output = 1;
1150 /* Reset global status used by the report functions. */
1152 void reset_report ()
1154 previous_output = 0;
1155 current_class = package_name = NULL;