FSF GCC merge 02/23/03
[official-gcc.git] / gcc / java / parse-scan.y
blob981ed477b2eeef61a1eaa37472d143b24608a079
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)
10 any later version.
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. */
38 #define JC1_LITE
40 #include "config.h"
41 #include "system.h"
42 #include "coretypes.h"
43 #include "tm.h"
45 #include "obstack.h"
46 #include "toplev.h"
48 #define obstack_chunk_alloc xmalloc
49 #define obstack_chunk_free free
51 extern char *input_filename;
52 extern FILE *finput, *out;
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, current line number, because they're used
61 elsewhere */
62 int java_error_count;
63 int java_warning_count;
64 int lineno;
66 /* Tweak default rules when necessary. */
67 static int absorber;
68 #define USE_ABSORBER absorber = 0
70 /* Keep track of the current package name. */
71 static const char *package_name;
73 /* Keep track of whether things have be listed before. */
74 static int previous_output;
76 /* Record modifier uses */
77 static int modifier_value;
79 /* Record (almost) cyclomatic complexity. */
80 static int complexity;
82 /* Keeps track of number of bracket pairs after a variable declarator
83 id. */
84 static int bracket_count;
86 /* Numbers anonymous classes */
87 static int anonymous_count;
89 /* This is used to record the current class context. */
90 struct class_context
92 char *name;
93 struct class_context *next;
96 /* The global class context. */
97 static struct class_context *current_class_context;
99 /* A special constant used to represent an anonymous context. */
100 static const char *anonymous_context = "ANONYMOUS";
102 /* Count of method depth. */
103 static int method_depth;
105 /* Record a method declaration */
106 struct method_declarator {
107 const char *method_name;
108 const char *args;
110 #define NEW_METHOD_DECLARATOR(D,N,A) \
112 (D) = xmalloc (sizeof (struct method_declarator)); \
113 (D)->method_name = (N); \
114 (D)->args = (A); \
117 /* Two actions for this grammar */
118 static int make_class_name_recursive (struct obstack *stack,
119 struct class_context *ctx);
120 static char *get_class_name (void);
121 static void report_class_declaration (const char *);
122 static void report_main_declaration (struct method_declarator *);
123 static void push_class_context (const char *);
124 static void pop_class_context (void);
126 void report (void);
128 #include "lex.h"
129 #include "parse.h"
132 %union {
133 char *node;
134 struct method_declarator *declarator;
135 int value; /* For modifiers */
139 extern int flag_assert;
141 #include "lex.c"
144 %pure_parser
146 /* Things defined here have to match the order of what's in the
147 binop_lookup table. */
149 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
150 %token LS_TK SRS_TK ZRS_TK
151 %token AND_TK XOR_TK OR_TK
152 %token BOOL_AND_TK BOOL_OR_TK
153 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
155 /* This maps to the same binop_lookup entry than the token above */
157 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
158 %token REM_ASSIGN_TK
159 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
160 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
163 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
165 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
166 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
167 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
168 %token PAD_TK ABSTRACT_TK MODIFIER_TK
169 %token STRICT_TK
171 /* Keep those two in order, too */
172 %token DECR_TK INCR_TK
174 /* From now one, things can be in any order */
176 %token DEFAULT_TK IF_TK THROW_TK
177 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
178 %token THROWS_TK BREAK_TK IMPORT_TK
179 %token ELSE_TK INSTANCEOF_TK RETURN_TK
180 %token VOID_TK CATCH_TK INTERFACE_TK
181 %token CASE_TK EXTENDS_TK FINALLY_TK
182 %token SUPER_TK WHILE_TK CLASS_TK
183 %token SWITCH_TK CONST_TK TRY_TK
184 %token FOR_TK NEW_TK CONTINUE_TK
185 %token GOTO_TK PACKAGE_TK THIS_TK
186 %token ASSERT_TK
188 %token BYTE_TK SHORT_TK INT_TK LONG_TK
189 %token CHAR_TK INTEGRAL_TK
191 %token FLOAT_TK DOUBLE_TK FP_TK
193 %token ID_TK
195 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
197 %token ASSIGN_ANY_TK ASSIGN_TK
198 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
200 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
201 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
203 %type <node> ID_TK identifier name simple_name qualified_name type
204 primitive_type reference_type array_type formal_parameter_list
205 formal_parameter class_or_interface_type class_type interface_type
206 %type <declarator> method_declarator
207 %type <value> MODIFIER_TK
210 /* 19.2 Production from 2.3: The Syntactic Grammar */
211 goal:
212 compilation_unit
215 /* 19.3 Productions from 3: Lexical structure */
216 literal:
217 INT_LIT_TK
218 | FP_LIT_TK
219 | BOOL_LIT_TK
220 | CHAR_LIT_TK
221 | STRING_LIT_TK
222 | NULL_TK
225 /* 19.4 Productions from 4: Types, Values and Variables */
226 type:
227 primitive_type
228 | reference_type
231 primitive_type:
232 INTEGRAL_TK
234 /* use preset global here. FIXME */
235 $$ = xstrdup ("int");
237 | FP_TK
239 /* use preset global here. FIXME */
240 $$ = xstrdup ("double");
242 | BOOLEAN_TK
244 /* use preset global here. FIXME */
245 $$ = xstrdup ("boolean");
249 reference_type:
250 class_or_interface_type
251 | array_type
254 class_or_interface_type:
255 name
258 class_type:
259 class_or_interface_type /* Default rule */
262 interface_type:
263 class_or_interface_type
266 array_type:
267 primitive_type dims
269 while (bracket_count-- > 0)
270 $$ = concat ("[", $1, NULL);
272 | name dims
274 while (bracket_count-- > 0)
275 $$ = concat ("[", $1, NULL);
279 /* 19.5 Productions from 6: Names */
280 name:
281 simple_name /* Default rule */
282 | qualified_name /* Default rule */
285 simple_name:
286 identifier /* Default rule */
289 qualified_name:
290 name DOT_TK identifier
292 $$ = concat ($1, ".", $3, NULL);
296 identifier:
297 ID_TK
300 /* 19.6: Production from 7: Packages */
301 compilation_unit:
302 | package_declaration
303 | import_declarations
304 | type_declarations
305 | package_declaration import_declarations
306 | package_declaration type_declarations
307 | import_declarations type_declarations
308 | package_declaration import_declarations type_declarations
311 import_declarations:
312 import_declaration
313 | import_declarations import_declaration
316 type_declarations:
317 type_declaration
318 | type_declarations type_declaration
321 package_declaration:
322 PACKAGE_TK name SC_TK
323 { package_name = $2; }
326 import_declaration:
327 single_type_import_declaration
328 | type_import_on_demand_declaration
331 single_type_import_declaration:
332 IMPORT_TK name SC_TK
335 type_import_on_demand_declaration:
336 IMPORT_TK name DOT_TK MULT_TK SC_TK
339 type_declaration:
340 class_declaration
341 | interface_declaration
342 | empty_statement
345 /* 19.7 Shortened from the original:
346 modifiers: modifier | modifiers modifier
347 modifier: any of public... */
348 modifiers:
349 MODIFIER_TK
351 if ($1 == PUBLIC_TK)
352 modifier_value++;
353 if ($1 == STATIC_TK)
354 modifier_value++;
355 USE_ABSORBER;
357 | modifiers MODIFIER_TK
359 if ($2 == PUBLIC_TK)
360 modifier_value++;
361 if ($2 == STATIC_TK)
362 modifier_value++;
363 USE_ABSORBER;
367 /* 19.8.1 Production from $8.1: Class Declaration */
368 class_declaration:
369 modifiers CLASS_TK identifier super interfaces
371 report_class_declaration($3);
372 modifier_value = 0;
374 class_body
375 | CLASS_TK identifier super interfaces
376 { report_class_declaration($2); }
377 class_body
380 super:
381 | EXTENDS_TK class_type
384 interfaces:
385 | IMPLEMENTS_TK interface_type_list
388 interface_type_list:
389 interface_type
390 { USE_ABSORBER; }
391 | interface_type_list C_TK interface_type
392 { USE_ABSORBER; }
395 class_body:
396 OCB_TK CCB_TK
397 { pop_class_context (); }
398 | OCB_TK class_body_declarations CCB_TK
399 { pop_class_context (); }
402 class_body_declarations:
403 class_body_declaration
404 | class_body_declarations class_body_declaration
407 class_body_declaration:
408 class_member_declaration
409 | static_initializer
410 | constructor_declaration
411 | block /* Added, JDK1.1, instance initializer */
414 class_member_declaration:
415 field_declaration
416 | method_declaration
417 | class_declaration /* Added, JDK1.1 inner classes */
418 | interface_declaration /* Added, JDK1.1 inner classes */
419 | empty_statement
422 /* 19.8.2 Productions from 8.3: Field Declarations */
423 field_declaration:
424 type variable_declarators SC_TK
425 { USE_ABSORBER; }
426 | modifiers type variable_declarators SC_TK
427 { modifier_value = 0; }
430 variable_declarators:
431 /* Should we use build_decl_list () instead ? FIXME */
432 variable_declarator /* Default rule */
433 | variable_declarators C_TK variable_declarator
436 variable_declarator:
437 variable_declarator_id
438 | variable_declarator_id ASSIGN_TK variable_initializer
441 variable_declarator_id:
442 identifier
443 { bracket_count = 0; USE_ABSORBER; }
444 | variable_declarator_id OSB_TK CSB_TK
445 { ++bracket_count; }
448 variable_initializer:
449 expression
450 | array_initializer
453 /* 19.8.3 Productions from 8.4: Method Declarations */
454 method_declaration:
455 method_header
456 { ++method_depth; }
457 method_body
458 { --method_depth; }
461 method_header:
462 type method_declarator throws
463 { USE_ABSORBER; }
464 | VOID_TK method_declarator throws
465 | modifiers type method_declarator throws
466 { modifier_value = 0; }
467 | modifiers VOID_TK method_declarator throws
469 report_main_declaration ($3);
470 modifier_value = 0;
474 method_declarator:
475 identifier OP_TK CP_TK
477 struct method_declarator *d;
478 NEW_METHOD_DECLARATOR (d, $1, NULL);
479 $$ = d;
481 | identifier OP_TK formal_parameter_list CP_TK
483 struct method_declarator *d;
484 NEW_METHOD_DECLARATOR (d, $1, $3);
485 $$ = d;
487 | method_declarator OSB_TK CSB_TK
490 formal_parameter_list:
491 formal_parameter
492 | formal_parameter_list C_TK formal_parameter
494 $$ = concat ($1, ",", $3, NULL);
498 formal_parameter:
499 type variable_declarator_id
501 USE_ABSORBER;
502 if (bracket_count)
504 int i;
505 char *n = xmalloc (bracket_count + 1 + strlen ($$));
506 for (i = 0; i < bracket_count; ++i)
507 n[i] = '[';
508 strcpy (n + bracket_count, $$);
509 $$ = n;
511 else
512 $$ = $1;
514 | modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
516 if (bracket_count)
518 int i;
519 char *n = xmalloc (bracket_count + 1 + strlen ($$));
520 for (i = 0; i < bracket_count; ++i)
521 n[i] = '[';
522 strcpy (n + bracket_count, $$);
523 $$ = n;
525 else
526 $$ = $2;
530 throws:
531 | THROWS_TK class_type_list
534 class_type_list:
535 class_type
536 { USE_ABSORBER; }
537 | class_type_list C_TK class_type
538 { USE_ABSORBER; }
541 method_body:
542 block
543 | SC_TK
546 /* 19.8.4 Productions from 8.5: Static Initializers */
547 static_initializer:
548 static block
551 static: /* Test lval.sub_token here */
552 MODIFIER_TK
553 { USE_ABSORBER; }
556 /* 19.8.5 Productions from 8.6: Constructor Declarations */
557 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
558 - If a forbidded modifier is found, the the error is either the use of
559 a forbidded modifier for a constructor OR bogus attempt to declare a
560 method without having specified the return type. FIXME */
561 constructor_declaration:
562 constructor_declarator throws constructor_body
563 | modifiers constructor_declarator throws constructor_body
564 { modifier_value = 0; }
565 /* extra SC_TK, FIXME */
566 | constructor_declarator throws constructor_body SC_TK
567 /* extra SC_TK, FIXME */
568 | modifiers constructor_declarator throws constructor_body SC_TK
569 { modifier_value = 0; }
570 /* I'm not happy with the SC_TK addition. It isn't in the grammer and should
571 probably be matched by and empty statement. But it doesn't work. FIXME */
574 constructor_declarator:
575 simple_name OP_TK CP_TK
576 { USE_ABSORBER; }
577 | simple_name OP_TK formal_parameter_list CP_TK
578 { USE_ABSORBER; }
581 constructor_body:
582 OCB_TK CCB_TK
583 | OCB_TK explicit_constructor_invocation CCB_TK
584 | OCB_TK block_statements CCB_TK
585 | OCB_TK explicit_constructor_invocation block_statements CCB_TK
588 /* Error recovery for that rule moved down expression_statement: rule. */
589 explicit_constructor_invocation:
590 this_or_super OP_TK CP_TK SC_TK
591 | this_or_super OP_TK argument_list CP_TK SC_TK
592 /* Added, JDK1.1 inner classes. Modified because the rule
593 'primary' couldn't work. */
594 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
595 { USE_ABSORBER; }
596 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
597 { USE_ABSORBER; }
600 this_or_super: /* Added, simplifies error diagnostics */
601 THIS_TK
602 | SUPER_TK
605 /* 19.9 Productions from 9: Interfaces */
606 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
607 interface_declaration:
608 INTERFACE_TK identifier
609 { report_class_declaration ($2); modifier_value = 0; }
610 interface_body
611 | modifiers INTERFACE_TK identifier
612 { report_class_declaration ($3); modifier_value = 0; }
613 interface_body
614 | INTERFACE_TK identifier extends_interfaces
615 { report_class_declaration ($2); modifier_value = 0; }
616 interface_body
617 | modifiers INTERFACE_TK identifier extends_interfaces
618 { report_class_declaration ($3); modifier_value = 0; }
619 interface_body
622 extends_interfaces:
623 EXTENDS_TK interface_type
624 | extends_interfaces C_TK interface_type
627 interface_body:
628 OCB_TK CCB_TK
629 { pop_class_context (); }
630 | OCB_TK interface_member_declarations CCB_TK
631 { pop_class_context (); }
634 interface_member_declarations:
635 interface_member_declaration
636 | interface_member_declarations interface_member_declaration
639 interface_member_declaration:
640 constant_declaration
641 | abstract_method_declaration
642 | class_declaration /* Added, JDK1.1 inner classes */
643 | interface_declaration /* Added, JDK1.1 inner classes */
646 constant_declaration:
647 field_declaration
650 abstract_method_declaration:
651 method_header SC_TK
654 /* 19.10 Productions from 10: Arrays */
655 array_initializer:
656 OCB_TK CCB_TK
657 | OCB_TK variable_initializers CCB_TK
658 | OCB_TK C_TK CCB_TK
659 | OCB_TK variable_initializers C_TK CCB_TK
662 variable_initializers:
663 variable_initializer
664 | variable_initializers C_TK variable_initializer
667 /* 19.11 Production from 14: Blocks and Statements */
668 block:
669 OCB_TK CCB_TK
670 | OCB_TK block_statements CCB_TK
673 block_statements:
674 block_statement
675 | block_statements block_statement
678 block_statement:
679 local_variable_declaration_statement
680 | statement
681 | class_declaration /* Added, JDK1.1 inner classes */
684 local_variable_declaration_statement:
685 local_variable_declaration SC_TK /* Can't catch missing ';' here */
688 local_variable_declaration:
689 type variable_declarators
690 { USE_ABSORBER; }
691 | modifiers type variable_declarators /* Added, JDK1.1 final locals */
692 { modifier_value = 0; }
695 statement:
696 statement_without_trailing_substatement
697 | labeled_statement
698 | if_then_statement
699 | if_then_else_statement
700 | while_statement
701 | for_statement
704 statement_nsi:
705 statement_without_trailing_substatement
706 | labeled_statement_nsi
707 | if_then_else_statement_nsi
708 | while_statement_nsi
709 | for_statement_nsi
712 statement_without_trailing_substatement:
713 block
714 | empty_statement
715 | expression_statement
716 | switch_statement
717 | do_statement
718 | break_statement
719 | continue_statement
720 | return_statement
721 | synchronized_statement
722 | throw_statement
723 | try_statement
724 | assert_statement
727 empty_statement:
728 SC_TK
731 label_decl:
732 identifier REL_CL_TK
733 { USE_ABSORBER; }
736 labeled_statement:
737 label_decl statement
740 labeled_statement_nsi:
741 label_decl statement_nsi
744 /* We concentrate here a bunch of error handling rules that we couldn't write
745 earlier, because expression_statement catches a missing ';'. */
746 expression_statement:
747 statement_expression SC_TK
750 statement_expression:
751 assignment
752 | pre_increment_expression
753 | pre_decrement_expression
754 | post_increment_expression
755 | post_decrement_expression
756 | method_invocation
757 | class_instance_creation_expression
760 if_then_statement:
761 IF_TK OP_TK expression CP_TK statement { ++complexity; }
764 if_then_else_statement:
765 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
766 { ++complexity; }
769 if_then_else_statement_nsi:
770 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
771 { ++complexity; }
774 switch_statement:
775 SWITCH_TK OP_TK expression CP_TK switch_block
778 switch_block:
779 OCB_TK CCB_TK
780 | OCB_TK switch_labels CCB_TK
781 | OCB_TK switch_block_statement_groups CCB_TK
782 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
785 switch_block_statement_groups:
786 switch_block_statement_group
787 | switch_block_statement_groups switch_block_statement_group
790 switch_block_statement_group:
791 switch_labels block_statements { ++complexity; }
795 switch_labels:
796 switch_label
797 | switch_labels switch_label
800 switch_label:
801 CASE_TK constant_expression REL_CL_TK
802 | DEFAULT_TK REL_CL_TK
805 while_expression:
806 WHILE_TK OP_TK expression CP_TK { ++complexity; }
809 while_statement:
810 while_expression statement
813 while_statement_nsi:
814 while_expression statement_nsi
817 do_statement_begin:
818 DO_TK
821 do_statement:
822 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
823 { ++complexity; }
826 for_statement:
827 for_begin SC_TK expression SC_TK for_update CP_TK statement
828 | for_begin SC_TK SC_TK for_update CP_TK statement
831 for_statement_nsi:
832 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
833 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
836 for_header:
837 FOR_TK OP_TK
840 for_begin:
841 for_header for_init { ++complexity; }
843 for_init: /* Can be empty */
844 | statement_expression_list
845 | local_variable_declaration
848 for_update: /* Can be empty */
849 | statement_expression_list
852 statement_expression_list:
853 statement_expression
854 | statement_expression_list C_TK statement_expression
857 break_statement:
858 BREAK_TK SC_TK
859 | BREAK_TK identifier SC_TK
862 /* `continue' with a label is considered for complexity but ordinary
863 continue is not. */
864 continue_statement:
865 CONTINUE_TK SC_TK
866 | CONTINUE_TK identifier SC_TK { ++complexity; }
869 return_statement:
870 RETURN_TK SC_TK
871 | RETURN_TK expression SC_TK
874 throw_statement:
875 THROW_TK expression SC_TK { ++complexity; }
878 assert_statement:
879 ASSERT_TK expression REL_CL_TK expression SC_TK
880 | ASSERT_TK expression SC_TK
881 | ASSERT_TK error
882 {yyerror ("Missing term"); RECOVER;}
883 | ASSERT_TK expression error
884 {yyerror ("';' expected"); RECOVER;}
886 synchronized_statement:
887 synchronized OP_TK expression CP_TK block
888 | synchronized OP_TK expression CP_TK error
891 synchronized: /* Test lval.sub_token here */
892 MODIFIER_TK
893 { USE_ABSORBER; }
896 try_statement:
897 TRY_TK block catches
898 | TRY_TK block finally
899 | TRY_TK block catches finally
902 catches:
903 catch_clause
904 | catches catch_clause
907 catch_clause:
908 CATCH_TK OP_TK formal_parameter CP_TK block { ++complexity; }
911 finally:
912 FINALLY_TK block { ++complexity; }
915 /* 19.12 Production from 15: Expressions */
916 primary:
917 primary_no_new_array
918 | array_creation_expression
921 primary_no_new_array:
922 literal
923 | THIS_TK
924 | OP_TK expression CP_TK
925 | class_instance_creation_expression
926 | field_access
927 | method_invocation
928 | array_access
929 | type_literals
930 /* Added, JDK1.1 inner classes. Documentation is wrong
931 refering to a 'ClassName' (class_name) rule that doesn't
932 exist. Used name instead. */
933 | name DOT_TK THIS_TK
934 { USE_ABSORBER; }
937 type_literals:
938 name DOT_TK CLASS_TK
939 { USE_ABSORBER; }
940 | array_type DOT_TK CLASS_TK
941 { USE_ABSORBER; }
942 | primitive_type DOT_TK CLASS_TK
943 { USE_ABSORBER; }
944 | VOID_TK DOT_TK CLASS_TK
945 { USE_ABSORBER; }
948 class_instance_creation_expression:
949 NEW_TK class_type OP_TK argument_list CP_TK
950 | NEW_TK class_type OP_TK CP_TK
951 | anonymous_class_creation
952 | something_dot_new identifier OP_TK CP_TK
953 | something_dot_new identifier OP_TK CP_TK class_body
954 | something_dot_new identifier OP_TK argument_list CP_TK
955 | something_dot_new identifier OP_TK argument_list CP_TK class_body
958 anonymous_class_creation:
959 NEW_TK class_type OP_TK CP_TK
960 { report_class_declaration (anonymous_context); }
961 class_body
962 | NEW_TK class_type OP_TK argument_list CP_TK
963 { report_class_declaration (anonymous_context); }
964 class_body
967 something_dot_new: /* Added, not part of the specs. */
968 name DOT_TK NEW_TK
969 { USE_ABSORBER; }
970 | primary DOT_TK NEW_TK
973 argument_list:
974 expression
975 | argument_list C_TK expression
976 | argument_list C_TK error
979 array_creation_expression:
980 NEW_TK primitive_type dim_exprs
981 | NEW_TK class_or_interface_type dim_exprs
982 | NEW_TK primitive_type dim_exprs dims
983 | NEW_TK class_or_interface_type dim_exprs dims
984 /* Added, JDK1.1 anonymous array. Initial documentation rule
985 modified */
986 | NEW_TK class_or_interface_type dims array_initializer
987 | NEW_TK primitive_type dims array_initializer
990 dim_exprs:
991 dim_expr
992 | dim_exprs dim_expr
995 dim_expr:
996 OSB_TK expression CSB_TK
999 dims:
1000 OSB_TK CSB_TK
1001 { bracket_count = 1; }
1002 | dims OSB_TK CSB_TK
1003 { bracket_count++; }
1006 field_access:
1007 primary DOT_TK identifier
1008 | SUPER_TK DOT_TK identifier
1011 /* We include method invocation in the complexity measure on the
1012 theory that most method calls are virtual and therefore involve a
1013 decision point. */
1014 method_invocation:
1015 name OP_TK CP_TK
1016 { USE_ABSORBER; ++complexity; }
1017 | name OP_TK argument_list CP_TK
1018 { USE_ABSORBER; ++complexity; }
1019 | primary DOT_TK identifier OP_TK CP_TK { ++complexity; }
1020 | primary DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; }
1021 | SUPER_TK DOT_TK identifier OP_TK CP_TK { ++complexity; }
1022 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; }
1025 array_access:
1026 name OSB_TK expression CSB_TK
1027 { USE_ABSORBER; }
1028 | primary_no_new_array OSB_TK expression CSB_TK
1031 postfix_expression:
1032 primary
1033 | name
1034 { USE_ABSORBER; }
1035 | post_increment_expression
1036 | post_decrement_expression
1039 post_increment_expression:
1040 postfix_expression INCR_TK
1043 post_decrement_expression:
1044 postfix_expression DECR_TK
1047 unary_expression:
1048 pre_increment_expression
1049 | pre_decrement_expression
1050 | PLUS_TK unary_expression
1051 | MINUS_TK unary_expression
1052 | unary_expression_not_plus_minus
1055 pre_increment_expression:
1056 INCR_TK unary_expression
1059 pre_decrement_expression:
1060 DECR_TK unary_expression
1063 unary_expression_not_plus_minus:
1064 postfix_expression
1065 | NOT_TK unary_expression
1066 | NEG_TK unary_expression
1067 | cast_expression
1070 cast_expression: /* Error handling here is potentially weak */
1071 OP_TK primitive_type dims CP_TK unary_expression
1072 | OP_TK primitive_type CP_TK unary_expression
1073 | OP_TK expression CP_TK unary_expression_not_plus_minus
1074 | OP_TK name dims CP_TK unary_expression_not_plus_minus
1077 multiplicative_expression:
1078 unary_expression
1079 | multiplicative_expression MULT_TK unary_expression
1080 | multiplicative_expression DIV_TK unary_expression
1081 | multiplicative_expression REM_TK unary_expression
1084 additive_expression:
1085 multiplicative_expression
1086 | additive_expression PLUS_TK multiplicative_expression
1087 | additive_expression MINUS_TK multiplicative_expression
1090 shift_expression:
1091 additive_expression
1092 | shift_expression LS_TK additive_expression
1093 | shift_expression SRS_TK additive_expression
1094 | shift_expression ZRS_TK additive_expression
1097 relational_expression:
1098 shift_expression
1099 | relational_expression LT_TK shift_expression
1100 | relational_expression GT_TK shift_expression
1101 | relational_expression LTE_TK shift_expression
1102 | relational_expression GTE_TK shift_expression
1103 | relational_expression INSTANCEOF_TK reference_type
1106 equality_expression:
1107 relational_expression
1108 | equality_expression EQ_TK relational_expression
1109 | equality_expression NEQ_TK relational_expression
1112 and_expression:
1113 equality_expression
1114 | and_expression AND_TK equality_expression
1117 exclusive_or_expression:
1118 and_expression
1119 | exclusive_or_expression XOR_TK and_expression
1122 inclusive_or_expression:
1123 exclusive_or_expression
1124 | inclusive_or_expression OR_TK exclusive_or_expression
1127 conditional_and_expression:
1128 inclusive_or_expression
1129 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
1130 { ++complexity; }
1133 conditional_or_expression:
1134 conditional_and_expression
1135 | conditional_or_expression BOOL_OR_TK conditional_and_expression
1136 { ++complexity; }
1139 conditional_expression: /* Error handling here is weak */
1140 conditional_or_expression
1141 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
1142 { ++complexity; }
1145 assignment_expression:
1146 conditional_expression
1147 | assignment
1150 assignment:
1151 left_hand_side assignment_operator assignment_expression
1154 left_hand_side:
1155 name
1156 { USE_ABSORBER; }
1157 | field_access
1158 | array_access
1161 assignment_operator:
1162 ASSIGN_ANY_TK
1163 | ASSIGN_TK
1166 expression:
1167 assignment_expression
1170 constant_expression:
1171 expression
1176 /* Create a new parser context */
1178 void
1179 java_push_parser_context (void)
1181 struct parser_ctxt *new = xcalloc (1, sizeof (struct parser_ctxt));
1183 new->next = ctxp;
1184 ctxp = new;
1187 static void
1188 push_class_context (const char *name)
1190 struct class_context *ctx;
1192 ctx = xmalloc (sizeof (struct class_context));
1193 ctx->name = (char *) name;
1194 ctx->next = current_class_context;
1195 current_class_context = ctx;
1198 static void
1199 pop_class_context (void)
1201 struct class_context *ctx;
1203 if (current_class_context == NULL)
1204 return;
1206 ctx = current_class_context->next;
1207 if (current_class_context->name != anonymous_context)
1208 free (current_class_context->name);
1209 free (current_class_context);
1211 current_class_context = ctx;
1212 if (current_class_context == NULL)
1213 anonymous_count = 0;
1216 /* Recursively construct the class name. This is just a helper
1217 function for get_class_name(). */
1218 static int
1219 make_class_name_recursive (struct obstack *stack, struct class_context *ctx)
1221 if (! ctx)
1222 return 0;
1224 make_class_name_recursive (stack, ctx->next);
1226 /* Replace an anonymous context with the appropriate counter value. */
1227 if (ctx->name == anonymous_context)
1229 char buf[50];
1230 ++anonymous_count;
1231 sprintf (buf, "%d", anonymous_count);
1232 ctx->name = xstrdup (buf);
1235 obstack_grow (stack, ctx->name, strlen (ctx->name));
1236 obstack_1grow (stack, '$');
1238 return ISDIGIT (ctx->name[0]);
1241 /* Return a newly allocated string holding the name of the class. */
1242 static char *
1243 get_class_name (void)
1245 char *result;
1246 int last_was_digit;
1247 struct obstack name_stack;
1249 obstack_init (&name_stack);
1251 /* Duplicate the logic of parse.y:maybe_make_nested_class_name(). */
1252 last_was_digit = make_class_name_recursive (&name_stack,
1253 current_class_context->next);
1255 if (! last_was_digit
1256 && method_depth
1257 && current_class_context->name != anonymous_context)
1259 char buf[50];
1260 ++anonymous_count;
1261 sprintf (buf, "%d", anonymous_count);
1262 obstack_grow (&name_stack, buf, strlen (buf));
1263 obstack_1grow (&name_stack, '$');
1266 if (current_class_context->name == anonymous_context)
1268 char buf[50];
1269 ++anonymous_count;
1270 sprintf (buf, "%d", anonymous_count);
1271 current_class_context->name = xstrdup (buf);
1272 obstack_grow0 (&name_stack, buf, strlen (buf));
1274 else
1275 obstack_grow0 (&name_stack, current_class_context->name,
1276 strlen (current_class_context->name));
1278 result = xstrdup (obstack_finish (&name_stack));
1279 obstack_free (&name_stack, NULL);
1281 return result;
1284 /* Actions defined here */
1286 static void
1287 report_class_declaration (const char * name)
1289 extern int flag_dump_class, flag_list_filename;
1291 push_class_context (name);
1292 if (flag_dump_class)
1294 char *name = get_class_name ();
1296 if (!previous_output)
1298 if (flag_list_filename)
1299 fprintf (out, "%s: ", input_filename);
1300 previous_output = 1;
1303 if (package_name)
1304 fprintf (out, "%s.%s ", package_name, name);
1305 else
1306 fprintf (out, "%s ", name);
1308 free (name);
1312 static void
1313 report_main_declaration (struct method_declarator *declarator)
1315 extern int flag_find_main;
1317 if (flag_find_main
1318 && modifier_value == 2
1319 && !strcmp (declarator->method_name, "main")
1320 && declarator->args
1321 && declarator->args [0] == '['
1322 && (! strcmp (declarator->args+1, "String")
1323 || ! strcmp (declarator->args + 1, "java.lang.String"))
1324 && current_class_context)
1326 if (!previous_output)
1328 char *name = get_class_name ();
1329 if (package_name)
1330 fprintf (out, "%s.%s ", package_name, name);
1331 else
1332 fprintf (out, "%s", name);
1333 free (name);
1334 previous_output = 1;
1339 void
1340 report (void)
1342 extern int flag_complexity;
1343 if (flag_complexity)
1344 fprintf (out, "%s %d\n", input_filename, complexity);
1347 /* Reset global status used by the report functions. */
1349 void reset_report (void)
1351 previous_output = 0;
1352 package_name = NULL;
1353 current_class_context = NULL;
1354 complexity = 0;
1357 void
1358 yyerror (const char *msg ATTRIBUTE_UNUSED)
1360 fprintf (stderr, "%s: %d: %s\n", input_filename, lineno, msg);
1361 exit (1);