1 /* Parser grammar for quick source code scan of Java(TM) language programs.
2 Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
5 This file is part of GCC.
7 GCC 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 GCC 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 GCC; 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. */
42 #include "coretypes.h"
48 extern
FILE *finput
, *out
;
50 /* Current position in real source file. */
52 location_t input_location
;
54 /* Obstack for the lexer. */
55 struct obstack temporary_obstack
;
57 /* The current parser context. */
58 static struct parser_ctxt
*ctxp
;
60 /* Error and warning counts, because they're used elsewhere */
62 int java_warning_count
;
64 /* Tweak default rules when necessary. */
66 #define USE_ABSORBER absorber = 0
68 /* Keep track of the current package name. */
69 static const 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 (almost) cyclomatic complexity. */
78 static int complexity
;
80 /* Keeps track of number of bracket pairs after a variable declarator
82 static int bracket_count
;
84 /* Numbers anonymous classes */
85 static int anonymous_count
;
87 /* This is used to record the current class context. */
91 struct class_context
*next
;
94 /* The global class context. */
95 static struct class_context
*current_class_context
;
97 /* A special constant used to represent an anonymous context. */
98 static const char *anonymous_context
= "ANONYMOUS";
100 /* Count of method depth. */
101 static int method_depth
;
103 /* Record a method declaration */
104 struct method_declarator
{
105 const char *method_name
;
108 #define NEW_METHOD_DECLARATOR(D,N,A) \
110 (D
) = xmalloc
(sizeof
(struct method_declarator
)); \
111 (D
)->method_name
= (N
); \
115 /* Two actions for this grammar */
116 static int make_class_name_recursive
(struct obstack
*stack
,
117 struct class_context
*ctx
);
118 static char *get_class_name
(void);
119 static void report_class_declaration
(const char *);
120 static void report_main_declaration
(struct method_declarator
*);
121 static void push_class_context
(const char *);
122 static void pop_class_context
(void);
132 struct method_declarator
*declarator
;
133 int value
; /* For modifiers */
137 extern
int flag_assert
;
144 /* Things defined here have to match the order of what's in the
145 binop_lookup table. */
147 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
148 %token LS_TK SRS_TK ZRS_TK
149 %token AND_TK XOR_TK OR_TK
150 %token BOOL_AND_TK BOOL_OR_TK
151 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
153 /* This maps to the same binop_lookup entry than the token above */
155 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
157 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
158 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
161 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
163 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
164 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
165 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
166 %token PAD_TK ABSTRACT_TK MODIFIER_TK
169 /* Keep those two in order, too */
170 %token DECR_TK INCR_TK
172 /* From now one, things can be in any order */
174 %token DEFAULT_TK IF_TK THROW_TK
175 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
176 %token THROWS_TK BREAK_TK IMPORT_TK
177 %token ELSE_TK INSTANCEOF_TK RETURN_TK
178 %token VOID_TK CATCH_TK INTERFACE_TK
179 %token CASE_TK EXTENDS_TK FINALLY_TK
180 %token SUPER_TK WHILE_TK CLASS_TK
181 %token SWITCH_TK CONST_TK TRY_TK
182 %token FOR_TK NEW_TK CONTINUE_TK
183 %token GOTO_TK PACKAGE_TK THIS_TK
186 %token BYTE_TK SHORT_TK INT_TK LONG_TK
187 %token CHAR_TK INTEGRAL_TK
189 %token FLOAT_TK DOUBLE_TK FP_TK
193 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
195 %token ASSIGN_ANY_TK ASSIGN_TK
196 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
198 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
199 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
201 %type
<node
> ID_TK identifier name simple_name qualified_name type
202 primitive_type reference_type array_type formal_parameter_list
203 formal_parameter class_or_interface_type class_type interface_type
204 %type
<declarator
> method_declarator
205 %type
<value
> MODIFIER_TK
208 /* 19.2 Production from 2.3: The Syntactic Grammar */
213 /* 19.3 Productions from 3: Lexical structure */
223 /* 19.4 Productions from 4: Types, Values and Variables */
232 /* use preset global here. FIXME */
233 $$
= xstrdup
("int");
237 /* use preset global here. FIXME */
238 $$
= xstrdup
("double");
242 /* use preset global here. FIXME */
243 $$
= xstrdup
("boolean");
248 class_or_interface_type
252 class_or_interface_type:
257 class_or_interface_type
/* Default rule */
261 class_or_interface_type
267 while
(bracket_count
-- > 0)
268 $$
= concat
("[", $1, NULL
);
272 while
(bracket_count
-- > 0)
273 $$
= concat
("[", $1, NULL
);
277 /* 19.5 Productions from 6: Names */
279 simple_name
/* Default rule */
280 | qualified_name
/* Default rule */
284 identifier
/* Default rule */
288 name DOT_TK identifier
290 $$
= concat
($1, ".", $3, NULL
);
298 /* 19.6: Production from 7: Packages */
300 | package_declaration
301 | import_declarations
303 | package_declaration import_declarations
304 | package_declaration type_declarations
305 | import_declarations type_declarations
306 | package_declaration import_declarations type_declarations
311 | import_declarations import_declaration
316 | type_declarations type_declaration
320 PACKAGE_TK name SC_TK
321 { package_name
= $2; }
325 single_type_import_declaration
326 | type_import_on_demand_declaration
329 single_type_import_declaration:
333 type_import_on_demand_declaration:
334 IMPORT_TK name DOT_TK MULT_TK SC_TK
339 | interface_declaration
343 /* 19.7 Shortened from the original:
344 modifiers: modifier | modifiers modifier
345 modifier: any of public... */
355 | modifiers MODIFIER_TK
365 /* 19.8.1 Production from $8.1: Class Declaration */
367 modifiers CLASS_TK identifier super interfaces
369 report_class_declaration
($3);
373 | CLASS_TK identifier super interfaces
374 { report_class_declaration
($2); }
379 | EXTENDS_TK class_type
383 | IMPLEMENTS_TK interface_type_list
389 | interface_type_list C_TK interface_type
395 { pop_class_context
(); }
396 | OCB_TK class_body_declarations CCB_TK
397 { pop_class_context
(); }
400 class_body_declarations:
401 class_body_declaration
402 | class_body_declarations class_body_declaration
405 class_body_declaration:
406 class_member_declaration
408 | constructor_declaration
409 | block
/* Added, JDK1.1, instance initializer */
412 class_member_declaration:
415 | class_declaration
/* Added, JDK1.1 inner classes */
416 | interface_declaration
/* Added, JDK1.1 inner classes */
420 /* 19.8.2 Productions from 8.3: Field Declarations */
422 type variable_declarators SC_TK
424 | modifiers type variable_declarators SC_TK
425 { modifier_value
= 0; }
428 variable_declarators:
429 /* Should we use build_decl_list () instead ? FIXME */
430 variable_declarator
/* Default rule */
431 | variable_declarators C_TK variable_declarator
435 variable_declarator_id
436 | variable_declarator_id ASSIGN_TK variable_initializer
439 variable_declarator_id:
441 { bracket_count
= 0; USE_ABSORBER
; }
442 | variable_declarator_id OSB_TK CSB_TK
446 variable_initializer:
451 /* 19.8.3 Productions from 8.4: Method Declarations */
460 type method_declarator throws
462 | VOID_TK method_declarator throws
463 | modifiers type method_declarator throws
464 { modifier_value
= 0; }
465 | modifiers VOID_TK method_declarator throws
467 report_main_declaration
($3);
473 identifier OP_TK CP_TK
475 struct method_declarator
*d
;
476 NEW_METHOD_DECLARATOR
(d
, $1, NULL
);
479 | identifier OP_TK formal_parameter_list CP_TK
481 struct method_declarator
*d
;
482 NEW_METHOD_DECLARATOR
(d
, $1, $3);
485 | method_declarator OSB_TK CSB_TK
488 formal_parameter_list:
490 | formal_parameter_list C_TK formal_parameter
492 $$
= concat
($1, ",", $3, NULL
);
497 type variable_declarator_id
503 char *n
= xmalloc
(bracket_count
+ 1 + strlen
($$
));
504 for
(i
= 0; i
< bracket_count
; ++i
)
506 strcpy
(n
+ bracket_count
, $$
);
512 | modifiers type variable_declarator_id
/* Added, JDK1.1 final locals */
517 char *n
= xmalloc
(bracket_count
+ 1 + strlen
($$
));
518 for
(i
= 0; i
< bracket_count
; ++i
)
520 strcpy
(n
+ bracket_count
, $$
);
529 | THROWS_TK class_type_list
535 | class_type_list C_TK class_type
544 /* 19.8.4 Productions from 8.5: Static Initializers */
549 static: /* Test lval.sub_token here */
554 /* 19.8.5 Productions from 8.6: Constructor Declarations */
555 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
556 - If a forbidded modifier is found, the the error is either the use of
557 a forbidded modifier for a constructor OR bogus attempt to declare a
558 method without having specified the return type. FIXME */
559 constructor_declaration:
560 constructor_declarator throws constructor_body
561 | modifiers constructor_declarator throws constructor_body
562 { modifier_value
= 0; }
563 /* extra SC_TK, FIXME */
564 | constructor_declarator throws constructor_body SC_TK
565 /* extra SC_TK, FIXME */
566 | modifiers constructor_declarator throws constructor_body SC_TK
567 { modifier_value
= 0; }
568 /* I'm not happy with the SC_TK addition. It isn't in the grammer and should
569 probably be matched by and empty statement. But it doesn't work. FIXME */
572 constructor_declarator:
573 simple_name OP_TK CP_TK
575 | simple_name OP_TK formal_parameter_list CP_TK
581 | OCB_TK explicit_constructor_invocation CCB_TK
582 | OCB_TK block_statements CCB_TK
583 | OCB_TK explicit_constructor_invocation block_statements CCB_TK
586 /* Error recovery for that rule moved down expression_statement: rule. */
587 explicit_constructor_invocation:
588 this_or_super OP_TK CP_TK SC_TK
589 | this_or_super OP_TK argument_list CP_TK SC_TK
590 /* Added, JDK1.1 inner classes. Modified because the rule
591 'primary' couldn't work. */
592 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
594 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
598 this_or_super: /* Added, simplifies error diagnostics */
603 /* 19.9 Productions from 9: Interfaces */
604 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
605 interface_declaration:
606 INTERFACE_TK identifier
607 { report_class_declaration
($2); modifier_value
= 0; }
609 | modifiers INTERFACE_TK identifier
610 { report_class_declaration
($3); modifier_value
= 0; }
612 | INTERFACE_TK identifier extends_interfaces
613 { report_class_declaration
($2); modifier_value
= 0; }
615 | modifiers INTERFACE_TK identifier extends_interfaces
616 { report_class_declaration
($3); modifier_value
= 0; }
621 EXTENDS_TK interface_type
622 | extends_interfaces C_TK interface_type
627 { pop_class_context
(); }
628 | OCB_TK interface_member_declarations CCB_TK
629 { pop_class_context
(); }
632 interface_member_declarations:
633 interface_member_declaration
634 | interface_member_declarations interface_member_declaration
637 interface_member_declaration:
639 | abstract_method_declaration
640 | class_declaration
/* Added, JDK1.1 inner classes */
641 | interface_declaration
/* Added, JDK1.1 inner classes */
644 constant_declaration:
648 abstract_method_declaration:
652 /* 19.10 Productions from 10: Arrays */
655 | OCB_TK variable_initializers CCB_TK
657 | OCB_TK variable_initializers C_TK CCB_TK
660 variable_initializers:
662 | variable_initializers C_TK variable_initializer
665 /* 19.11 Production from 14: Blocks and Statements */
668 | OCB_TK block_statements CCB_TK
673 | block_statements block_statement
677 local_variable_declaration_statement
679 | class_declaration
/* Added, JDK1.1 inner classes */
682 local_variable_declaration_statement:
683 local_variable_declaration SC_TK
/* Can't catch missing ';' here */
686 local_variable_declaration:
687 type variable_declarators
689 | modifiers type variable_declarators
/* Added, JDK1.1 final locals */
690 { modifier_value
= 0; }
694 statement_without_trailing_substatement
697 | if_then_else_statement
703 statement_without_trailing_substatement
704 | labeled_statement_nsi
705 | if_then_else_statement_nsi
706 | while_statement_nsi
710 statement_without_trailing_substatement:
713 | expression_statement
719 | synchronized_statement
738 labeled_statement_nsi:
739 label_decl statement_nsi
742 /* We concentrate here a bunch of error handling rules that we couldn't write
743 earlier, because expression_statement catches a missing ';'. */
744 expression_statement:
745 statement_expression SC_TK
748 statement_expression:
750 | pre_increment_expression
751 | pre_decrement_expression
752 | post_increment_expression
753 | post_decrement_expression
755 | class_instance_creation_expression
759 IF_TK OP_TK expression CP_TK statement
{ ++complexity
; }
762 if_then_else_statement:
763 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
767 if_then_else_statement_nsi:
768 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
773 SWITCH_TK OP_TK expression CP_TK switch_block
778 | OCB_TK switch_labels CCB_TK
779 | OCB_TK switch_block_statement_groups CCB_TK
780 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
783 switch_block_statement_groups:
784 switch_block_statement_group
785 | switch_block_statement_groups switch_block_statement_group
788 switch_block_statement_group:
789 switch_labels block_statements
{ ++complexity
; }
795 | switch_labels switch_label
799 CASE_TK constant_expression REL_CL_TK
800 | DEFAULT_TK REL_CL_TK
804 WHILE_TK OP_TK expression CP_TK
{ ++complexity
; }
808 while_expression statement
812 while_expression statement_nsi
820 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
825 for_begin SC_TK expression SC_TK for_update CP_TK statement
826 | for_begin SC_TK SC_TK for_update CP_TK statement
830 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
831 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
839 for_header for_init
{ ++complexity
; }
841 for_init: /* Can be empty */
842 | statement_expression_list
843 | local_variable_declaration
846 for_update: /* Can be empty */
847 | statement_expression_list
850 statement_expression_list:
852 | statement_expression_list C_TK statement_expression
857 | BREAK_TK identifier SC_TK
860 /* `continue' with a label is considered for complexity but ordinary
864 | CONTINUE_TK identifier SC_TK
{ ++complexity
; }
869 | RETURN_TK expression SC_TK
873 THROW_TK expression SC_TK
{ ++complexity
; }
877 ASSERT_TK expression REL_CL_TK expression SC_TK
878 | ASSERT_TK expression SC_TK
880 {yyerror ("Missing term"); RECOVER
;}
881 | ASSERT_TK expression
error
882 {yyerror ("';' expected"); RECOVER
;}
884 synchronized_statement:
885 synchronized OP_TK expression CP_TK block
886 | synchronized OP_TK expression CP_TK
error
889 synchronized: /* Test lval.sub_token here */
896 | TRY_TK block finally
897 | TRY_TK block catches finally
902 | catches catch_clause
906 CATCH_TK OP_TK formal_parameter CP_TK block
{ ++complexity
; }
910 FINALLY_TK block
{ ++complexity
; }
913 /* 19.12 Production from 15: Expressions */
916 | array_creation_expression
919 primary_no_new_array:
922 | OP_TK expression CP_TK
923 | class_instance_creation_expression
928 /* Added, JDK1.1 inner classes. Documentation is wrong
929 refering to a 'ClassName' (class_name) rule that doesn't
930 exist. Used name instead. */
931 | name DOT_TK THIS_TK
938 | array_type DOT_TK CLASS_TK
940 | primitive_type DOT_TK CLASS_TK
942 | VOID_TK DOT_TK CLASS_TK
946 class_instance_creation_expression:
947 NEW_TK class_type OP_TK argument_list CP_TK
948 | NEW_TK class_type OP_TK CP_TK
949 | anonymous_class_creation
950 | something_dot_new identifier OP_TK CP_TK
951 | something_dot_new identifier OP_TK CP_TK class_body
952 | something_dot_new identifier OP_TK argument_list CP_TK
953 | something_dot_new identifier OP_TK argument_list CP_TK class_body
956 anonymous_class_creation:
957 NEW_TK class_type OP_TK CP_TK
958 { report_class_declaration
(anonymous_context
); }
960 | NEW_TK class_type OP_TK argument_list CP_TK
961 { report_class_declaration
(anonymous_context
); }
965 something_dot_new: /* Added, not part of the specs. */
968 | primary DOT_TK NEW_TK
973 | argument_list C_TK expression
974 | argument_list C_TK
error
977 array_creation_expression:
978 NEW_TK primitive_type dim_exprs
979 | NEW_TK class_or_interface_type dim_exprs
980 | NEW_TK primitive_type dim_exprs dims
981 | NEW_TK class_or_interface_type dim_exprs dims
982 /* Added, JDK1.1 anonymous array. Initial documentation rule
984 | NEW_TK class_or_interface_type dims array_initializer
985 | NEW_TK primitive_type dims array_initializer
994 OSB_TK expression CSB_TK
999 { bracket_count
= 1; }
1000 | dims OSB_TK CSB_TK
1001 { bracket_count
++; }
1005 primary DOT_TK identifier
1006 | SUPER_TK DOT_TK identifier
1009 /* We include method invocation in the complexity measure on the
1010 theory that most method calls are virtual and therefore involve a
1014 { USE_ABSORBER
; ++complexity
; }
1015 | name OP_TK argument_list CP_TK
1016 { USE_ABSORBER
; ++complexity
; }
1017 | primary DOT_TK identifier OP_TK CP_TK
{ ++complexity
; }
1018 | primary DOT_TK identifier OP_TK argument_list CP_TK
{ ++complexity
; }
1019 | SUPER_TK DOT_TK identifier OP_TK CP_TK
{ ++complexity
; }
1020 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
{ ++complexity
; }
1024 name OSB_TK expression CSB_TK
1026 | primary_no_new_array OSB_TK expression CSB_TK
1033 | post_increment_expression
1034 | post_decrement_expression
1037 post_increment_expression:
1038 postfix_expression INCR_TK
1041 post_decrement_expression:
1042 postfix_expression DECR_TK
1046 pre_increment_expression
1047 | pre_decrement_expression
1048 | PLUS_TK unary_expression
1049 | MINUS_TK unary_expression
1050 | unary_expression_not_plus_minus
1053 pre_increment_expression:
1054 INCR_TK unary_expression
1057 pre_decrement_expression:
1058 DECR_TK unary_expression
1061 unary_expression_not_plus_minus:
1063 | NOT_TK unary_expression
1064 | NEG_TK unary_expression
1068 cast_expression: /* Error handling here is potentially weak */
1069 OP_TK primitive_type dims CP_TK unary_expression
1070 | OP_TK primitive_type CP_TK unary_expression
1071 | OP_TK expression CP_TK unary_expression_not_plus_minus
1072 | OP_TK name dims CP_TK unary_expression_not_plus_minus
1075 multiplicative_expression:
1077 | multiplicative_expression MULT_TK unary_expression
1078 | multiplicative_expression DIV_TK unary_expression
1079 | multiplicative_expression REM_TK unary_expression
1082 additive_expression:
1083 multiplicative_expression
1084 | additive_expression PLUS_TK multiplicative_expression
1085 | additive_expression MINUS_TK multiplicative_expression
1090 | shift_expression LS_TK additive_expression
1091 | shift_expression SRS_TK additive_expression
1092 | shift_expression ZRS_TK additive_expression
1095 relational_expression:
1097 | relational_expression LT_TK shift_expression
1098 | relational_expression GT_TK shift_expression
1099 | relational_expression LTE_TK shift_expression
1100 | relational_expression GTE_TK shift_expression
1101 | relational_expression INSTANCEOF_TK reference_type
1104 equality_expression:
1105 relational_expression
1106 | equality_expression EQ_TK relational_expression
1107 | equality_expression NEQ_TK relational_expression
1112 | and_expression AND_TK equality_expression
1115 exclusive_or_expression:
1117 | exclusive_or_expression XOR_TK and_expression
1120 inclusive_or_expression:
1121 exclusive_or_expression
1122 | inclusive_or_expression OR_TK exclusive_or_expression
1125 conditional_and_expression:
1126 inclusive_or_expression
1127 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
1131 conditional_or_expression:
1132 conditional_and_expression
1133 | conditional_or_expression BOOL_OR_TK conditional_and_expression
1137 conditional_expression: /* Error handling here is weak */
1138 conditional_or_expression
1139 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
1143 assignment_expression:
1144 conditional_expression
1149 left_hand_side assignment_operator assignment_expression
1159 assignment_operator:
1165 assignment_expression
1168 constant_expression:
1174 /* Create a new parser context */
1177 java_push_parser_context
(void)
1179 struct parser_ctxt
*new
= xcalloc
(1, sizeof
(struct parser_ctxt
));
1186 push_class_context
(const char *name
)
1188 struct class_context
*ctx
;
1190 ctx
= xmalloc
(sizeof
(struct class_context
));
1191 ctx
->name
= (char *) name
;
1192 ctx
->next
= current_class_context
;
1193 current_class_context
= ctx
;
1197 pop_class_context
(void)
1199 struct class_context
*ctx
;
1201 if
(current_class_context
== NULL
)
1204 ctx
= current_class_context
->next
;
1205 if
(current_class_context
->name
!= anonymous_context
)
1206 free
(current_class_context
->name
);
1207 free
(current_class_context
);
1209 current_class_context
= ctx
;
1210 if
(current_class_context
== NULL
)
1211 anonymous_count
= 0;
1214 /* Recursively construct the class name. This is just a helper
1215 function for get_class_name(). */
1217 make_class_name_recursive
(struct obstack
*stack
, struct class_context
*ctx
)
1222 make_class_name_recursive
(stack
, ctx
->next
);
1224 /* Replace an anonymous context with the appropriate counter value. */
1225 if
(ctx
->name
== anonymous_context
)
1229 sprintf
(buf
, "%d", anonymous_count
);
1230 ctx
->name
= xstrdup
(buf
);
1233 obstack_grow
(stack
, ctx
->name
, strlen
(ctx
->name
));
1234 obstack_1grow
(stack
, '$');
1236 return ISDIGIT
(ctx
->name
[0]);
1239 /* Return a newly allocated string holding the name of the class. */
1241 get_class_name
(void)
1245 struct obstack name_stack
;
1247 obstack_init
(&name_stack
);
1249 /* Duplicate the logic of parse.y:maybe_make_nested_class_name(). */
1250 last_was_digit
= make_class_name_recursive
(&name_stack
,
1251 current_class_context
->next
);
1253 if
(! last_was_digit
1255 && current_class_context
->name
!= anonymous_context
)
1259 sprintf
(buf
, "%d", anonymous_count
);
1260 obstack_grow
(&name_stack
, buf
, strlen
(buf
));
1261 obstack_1grow
(&name_stack
, '$');
1264 if
(current_class_context
->name
== anonymous_context
)
1268 sprintf
(buf
, "%d", anonymous_count
);
1269 current_class_context
->name
= xstrdup
(buf
);
1270 obstack_grow0
(&name_stack
, buf
, strlen
(buf
));
1273 obstack_grow0
(&name_stack
, current_class_context
->name
,
1274 strlen
(current_class_context
->name
));
1276 result
= xstrdup
(obstack_finish
(&name_stack
));
1277 obstack_free
(&name_stack
, NULL
);
1282 /* Actions defined here */
1285 report_class_declaration
(const char * name
)
1287 extern
int flag_dump_class
, flag_list_filename
;
1289 push_class_context
(name
);
1290 if
(flag_dump_class
)
1292 char *name
= get_class_name
();
1294 if
(!previous_output
)
1296 if
(flag_list_filename
)
1297 fprintf
(out
, "%s: ", input_filename
);
1298 previous_output
= 1;
1302 fprintf
(out
, "%s.%s ", package_name
, name
);
1304 fprintf
(out
, "%s ", name
);
1311 report_main_declaration
(struct method_declarator
*declarator
)
1313 extern
int flag_find_main
;
1316 && modifier_value
== 2
1317 && !strcmp
(declarator
->method_name
, "main")
1319 && declarator
->args
[0] == '['
1320 && (! strcmp
(declarator
->args
+1, "String")
1321 ||
! strcmp
(declarator
->args
+ 1, "java.lang.String"))
1322 && current_class_context
)
1324 if
(!previous_output
)
1326 char *name
= get_class_name
();
1328 fprintf
(out
, "%s.%s ", package_name
, name
);
1330 fprintf
(out
, "%s", name
);
1332 previous_output
= 1;
1340 extern
int flag_complexity
;
1341 if
(flag_complexity
)
1342 fprintf
(out
, "%s %d\n", input_filename
, complexity
);
1345 /* Reset global status used by the report functions. */
1347 void reset_report
(void)
1349 previous_output
= 0;
1350 package_name
= NULL
;
1351 current_class_context
= NULL
;
1356 yyerror (const char *msg ATTRIBUTE_UNUSED
)
1358 fprintf
(stderr
, "%s: %d: %s\n", input_filename
, input_line
, msg
);