1 /* Parser grammar for quick source code scan of Java(TM) language programs.
2 Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
3 Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
4
5 This file is part of GNU CC.
6
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)
10 any later version.
11
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.
16
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.
21
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. */
25
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.
29
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"
33
34 Some rules have been modified to support JDK1.1 inner classes
35 definitions and other extensions. */
36
37 %{
38 #define JC1_LITE
39
40 #include "config.h"
41 #include "system.h"
42
43 #include "obstack.h"
44 #include "toplev.h"
45
46 #define obstack_chunk_alloc xmalloc
47 #define obstack_chunk_free free
48
49 extern char *input_filename;
50 extern FILE *finput, *out;
51
52 /* Obstack for the lexer. */
53 struct obstack temporary_obstack;
54
55 /* The current parser context. */
56 static struct parser_ctxt *ctxp;
57
58 /* Error and warning counts, current line number, because they're used
59 elsewhere */
60 int java_error_count;
61 int java_warning_count;
62 int lineno;
63
64 /* Tweak default rules when necessary. */
65 static int absorber;
66 #define USE_ABSORBER absorber = 0
67
68 /* Keep track of the current package name. */
69 static const char *package_name;
70
71 /* Keep track of whether things have be listed before. */
72 static int previous_output;
73
74 /* Record modifier uses */
75 static int modifier_value;
76
77 /* Record (almost) cyclomatic complexity. */
78 static int complexity;
79
80 /* Keeps track of number of bracket pairs after a variable declarator
81 id. */
82 static int bracket_count;
83
84 /* Numbers anonymous classes */
85 static int anonymous_count;
86
87 /* This is used to record the current class context. */
88 struct class_context
89 {
90 char *name;
91 struct class_context *next;
92 };
93
94 /* The global class context. */
95 static struct class_context *current_class_context;
96
97 /* A special constant used to represent an anonymous context. */
98 static const char *anonymous_context = "ANONYMOUS";
99
100 /* Count of method depth. */
101 static int method_depth;
102
103 /* Record a method declaration */
104 struct method_declarator {
105 const char *method_name;
106 const char *args;
107 };
108 #define NEW_METHOD_DECLARATOR(D,N,A) \
109 { \
110 (D) = \
111 (struct method_declarator *)xmalloc (sizeof (struct method_declarator)); \
112 (D)->method_name = (N); \
113 (D)->args = (A); \
114 }
115
116 /* Two actions for this grammar */
117 static int make_class_name_recursive PARAMS ((struct obstack *stack,
118 struct class_context *ctx));
119 static char *get_class_name PARAMS ((void));
120 static void report_class_declaration PARAMS ((const char *));
121 static void report_main_declaration PARAMS ((struct method_declarator *));
122 static void push_class_context PARAMS ((const char *));
123 static void pop_class_context PARAMS ((void));
124
125 void report PARAMS ((void));
126
127 #include "lex.h"
128 #include "parse.h"
129 %}
130
131 %union {
132 char *node;
133 struct method_declarator *declarator;
134 int value; /* For modifiers */
135 }
136
137 %{
138 extern int flag_assert;
139
140 #include "lex.c"
141 %}
142
143 %pure_parser
144
145 /* Things defined here have to match the order of what's in the
146 binop_lookup table. */
147
148 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
149 %token LS_TK SRS_TK ZRS_TK
150 %token AND_TK XOR_TK OR_TK
151 %token BOOL_AND_TK BOOL_OR_TK
152 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
153
154 /* This maps to the same binop_lookup entry than the token above */
155
156 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
157 %token REM_ASSIGN_TK
158 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
159 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
160
161
162 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
163
164 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
165 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
166 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
167 %token PAD_TK ABSTRACT_TK MODIFIER_TK
168 %token STRICT_TK
169
170 /* Keep those two in order, too */
171 %token DECR_TK INCR_TK
172
173 /* From now one, things can be in any order */
174
175 %token DEFAULT_TK IF_TK THROW_TK
176 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
177 %token THROWS_TK BREAK_TK IMPORT_TK
178 %token ELSE_TK INSTANCEOF_TK RETURN_TK
179 %token VOID_TK CATCH_TK INTERFACE_TK
180 %token CASE_TK EXTENDS_TK FINALLY_TK
181 %token SUPER_TK WHILE_TK CLASS_TK
182 %token SWITCH_TK CONST_TK TRY_TK
183 %token FOR_TK NEW_TK CONTINUE_TK
184 %token GOTO_TK PACKAGE_TK THIS_TK
185 %token ASSERT_TK
186
187 %token BYTE_TK SHORT_TK INT_TK LONG_TK
188 %token CHAR_TK INTEGRAL_TK
189
190 %token FLOAT_TK DOUBLE_TK FP_TK
191
192 %token ID_TK
193
194 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
195
196 %token ASSIGN_ANY_TK ASSIGN_TK
197 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
198
199 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
200 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
201
202 %type <node> ID_TK identifier name simple_name qualified_name type
203 primitive_type reference_type array_type formal_parameter_list
204 formal_parameter class_or_interface_type class_type interface_type
205 %type <declarator> method_declarator
206 %type <value> MODIFIER_TK
207
208 %%
209 /* 19.2 Production from 2.3: The Syntactic Grammar */
210 goal:
211 compilation_unit
212 ;
213
214 /* 19.3 Productions from 3: Lexical structure */
215 literal:
216 INT_LIT_TK
217 | FP_LIT_TK
218 | BOOL_LIT_TK
219 | CHAR_LIT_TK
220 | STRING_LIT_TK
221 | NULL_TK
222 ;
223
224 /* 19.4 Productions from 4: Types, Values and Variables */
225 type:
226 primitive_type
227 | reference_type
228 ;
229
230 primitive_type:
231 INTEGRAL_TK
232 {
233 /* use preset global here. FIXME */
234 $$ = xstrdup ("int");
235 }
236 | FP_TK
237 {
238 /* use preset global here. FIXME */
239 $$ = xstrdup ("double");
240 }
241 | BOOLEAN_TK
242 {
243 /* use preset global here. FIXME */
244 $$ = xstrdup ("boolean");
245 }
246 ;
247
248 reference_type:
249 class_or_interface_type
250 | array_type
251 ;
252
253 class_or_interface_type:
254 name
255 ;
256
257 class_type:
258 class_or_interface_type /* Default rule */
259 ;
260
261 interface_type:
262 class_or_interface_type
263 ;
264
265 array_type:
266 primitive_type dims
267 {
268 while (bracket_count-- > 0)
269 $$ = concat ("[", $1, NULL);
270 }
271 | name dims
272 {
273 while (bracket_count-- > 0)
274 $$ = concat ("[", $1, NULL);
275 }
276 ;
277
278 /* 19.5 Productions from 6: Names */
279 name:
280 simple_name /* Default rule */
281 | qualified_name /* Default rule */
282 ;
283
284 simple_name:
285 identifier /* Default rule */
286 ;
287
288 qualified_name:
289 name DOT_TK identifier
290 {
291 $$ = concat ($1, ".", $3, NULL);
292 }
293 ;
294
295 identifier:
296 ID_TK
297 ;
298
299 /* 19.6: Production from 7: Packages */
300 compilation_unit:
301 | package_declaration
302 | import_declarations
303 | type_declarations
304 | package_declaration import_declarations
305 | package_declaration type_declarations
306 | import_declarations type_declarations
307 | package_declaration import_declarations type_declarations
308 ;
309
310 import_declarations:
311 import_declaration
312 | import_declarations import_declaration
313 ;
314
315 type_declarations:
316 type_declaration
317 | type_declarations type_declaration
318 ;
319
320 package_declaration:
321 PACKAGE_TK name SC_TK
322 { package_name = $2; }
323 ;
324
325 import_declaration:
326 single_type_import_declaration
327 | type_import_on_demand_declaration
328 ;
329
330 single_type_import_declaration:
331 IMPORT_TK name SC_TK
332 ;
333
334 type_import_on_demand_declaration:
335 IMPORT_TK name DOT_TK MULT_TK SC_TK
336 ;
337
338 type_declaration:
339 class_declaration
340 | interface_declaration
341 | empty_statement
342 ;
343
344 /* 19.7 Shortened from the original:
345 modifiers: modifier | modifiers modifier
346 modifier: any of public... */
347 modifiers:
348 MODIFIER_TK
349 {
350 if ($1 == PUBLIC_TK)
351 modifier_value++;
352 if ($1 == STATIC_TK)
353 modifier_value++;
354 USE_ABSORBER;
355 }
356 | modifiers MODIFIER_TK
357 {
358 if ($2 == PUBLIC_TK)
359 modifier_value++;
360 if ($2 == STATIC_TK)
361 modifier_value++;
362 USE_ABSORBER;
363 }
364 ;
365
366 /* 19.8.1 Production from $8.1: Class Declaration */
367 class_declaration:
368 modifiers CLASS_TK identifier super interfaces
369 {
370 report_class_declaration($3);
371 modifier_value = 0;
372 }
373 class_body
374 | CLASS_TK identifier super interfaces
375 { report_class_declaration($2); }
376 class_body
377 ;
378
379 super:
380 | EXTENDS_TK class_type
381 ;
382
383 interfaces:
384 | IMPLEMENTS_TK interface_type_list
385 ;
386
387 interface_type_list:
388 interface_type
389 { USE_ABSORBER; }
390 | interface_type_list C_TK interface_type
391 { USE_ABSORBER; }
392 ;
393
394 class_body:
395 OCB_TK CCB_TK
396 { pop_class_context (); }
397 | OCB_TK class_body_declarations CCB_TK
398 { pop_class_context (); }
399 ;
400
401 class_body_declarations:
402 class_body_declaration
403 | class_body_declarations class_body_declaration
404 ;
405
406 class_body_declaration:
407 class_member_declaration
408 | static_initializer
409 | constructor_declaration
410 | block /* Added, JDK1.1, instance initializer */
411 ;
412
413 class_member_declaration:
414 field_declaration
415 | method_declaration
416 | class_declaration /* Added, JDK1.1 inner classes */
417 | interface_declaration /* Added, JDK1.1 inner classes */
418 | empty_statement
419 ;
420
421 /* 19.8.2 Productions from 8.3: Field Declarations */
422 field_declaration:
423 type variable_declarators SC_TK
424 { USE_ABSORBER; }
425 | modifiers type variable_declarators SC_TK
426 { modifier_value = 0; }
427 ;
428
429 variable_declarators:
430 /* Should we use build_decl_list () instead ? FIXME */
431 variable_declarator /* Default rule */
432 | variable_declarators C_TK variable_declarator
433 ;
434
435 variable_declarator:
436 variable_declarator_id
437 | variable_declarator_id ASSIGN_TK variable_initializer
438 ;
439
440 variable_declarator_id:
441 identifier
442 { bracket_count = 0; USE_ABSORBER; }
443 | variable_declarator_id OSB_TK CSB_TK
444 { ++bracket_count; }
445 ;
446
447 variable_initializer:
448 expression
449 | array_initializer
450 ;
451
452 /* 19.8.3 Productions from 8.4: Method Declarations */
453 method_declaration:
454 method_header
455 { ++method_depth; }
456 method_body
457 { --method_depth; }
458 ;
459
460 method_header:
461 type method_declarator throws
462 { USE_ABSORBER; }
463 | VOID_TK method_declarator throws
464 | modifiers type method_declarator throws
465 { modifier_value = 0; }
466 | modifiers VOID_TK method_declarator throws
467 {
468 report_main_declaration ($3);
469 modifier_value = 0;
470 }
471 ;
472
473 method_declarator:
474 identifier OP_TK CP_TK
475 {
476 struct method_declarator *d;
477 NEW_METHOD_DECLARATOR (d, $1, NULL);
478 $$ = d;
479 }
480 | identifier OP_TK formal_parameter_list CP_TK
481 {
482 struct method_declarator *d;
483 NEW_METHOD_DECLARATOR (d, $1, $3);
484 $$ = d;
485 }
486 | method_declarator OSB_TK CSB_TK
487 ;
488
489 formal_parameter_list:
490 formal_parameter
491 | formal_parameter_list C_TK formal_parameter
492 {
493 $$ = concat ($1, ",", $3, NULL);
494 }
495 ;
496
497 formal_parameter:
498 type variable_declarator_id
499 {
500 USE_ABSORBER;
501 if (bracket_count)
502 {
503 int i;
504 char *n = xmalloc (bracket_count + 1 + strlen ($$));
505 for (i = 0; i < bracket_count; ++i)
506 n[i] = '[';
507 strcpy (n + bracket_count, $$);
508 $$ = n;
509 }
510 else
511 $$ = $1;
512 }
513 | modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
514 {
515 if (bracket_count)
516 {
517 int i;
518 char *n = xmalloc (bracket_count + 1 + strlen ($$));
519 for (i = 0; i < bracket_count; ++i)
520 n[i] = '[';
521 strcpy (n + bracket_count, $$);
522 $$ = n;
523 }
524 else
525 $$ = $2;
526 }
527 ;
528
529 throws:
530 | THROWS_TK class_type_list
531 ;
532
533 class_type_list:
534 class_type
535 { USE_ABSORBER; }
536 | class_type_list C_TK class_type
537 { USE_ABSORBER; }
538 ;
539
540 method_body:
541 block
542 | SC_TK
543 ;
544
545 /* 19.8.4 Productions from 8.5: Static Initializers */
546 static_initializer:
547 static block
548 ;
549
550 static: /* Test lval.sub_token here */
551 MODIFIER_TK
552 { USE_ABSORBER; }
553 ;
554
555 /* 19.8.5 Productions from 8.6: Constructor Declarations */
556 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
557 - If a forbidded modifier is found, the the error is either the use of
558 a forbidded modifier for a constructor OR bogus attempt to declare a
559 method without having specified the return type. FIXME */
560 constructor_declaration:
561 constructor_declarator throws constructor_body
562 | modifiers constructor_declarator throws constructor_body
563 { modifier_value = 0; }
564 /* extra SC_TK, FIXME */
565 | constructor_declarator throws constructor_body SC_TK
566 /* extra SC_TK, FIXME */
567 | modifiers constructor_declarator throws constructor_body SC_TK
568 { modifier_value = 0; }
569 /* I'm not happy with the SC_TK addition. It isn't in the grammer and should
570 probably be matched by and empty statement. But it doesn't work. FIXME */
571 ;
572
573 constructor_declarator:
574 simple_name OP_TK CP_TK
575 { USE_ABSORBER; }
576 | simple_name OP_TK formal_parameter_list CP_TK
577 { USE_ABSORBER; }
578 ;
579
580 constructor_body:
581 OCB_TK CCB_TK
582 | OCB_TK explicit_constructor_invocation CCB_TK
583 | OCB_TK block_statements CCB_TK
584 | OCB_TK explicit_constructor_invocation block_statements CCB_TK
585 ;
586
587 /* Error recovery for that rule moved down expression_statement: rule. */
588 explicit_constructor_invocation:
589 this_or_super OP_TK CP_TK SC_TK
590 | this_or_super OP_TK argument_list CP_TK SC_TK
591 /* Added, JDK1.1 inner classes. Modified because the rule
592 'primary' couldn't work. */
593 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
594 { USE_ABSORBER; }
595 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
596 { USE_ABSORBER; }
597 ;
598
599 this_or_super: /* Added, simplifies error diagnostics */
600 THIS_TK
601 | SUPER_TK
602 ;
603
604 /* 19.9 Productions from 9: Interfaces */
605 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
606 interface_declaration:
607 INTERFACE_TK identifier
608 { report_class_declaration ($2); modifier_value = 0; }
609 interface_body
610 | modifiers INTERFACE_TK identifier
611 { report_class_declaration ($3); modifier_value = 0; }
612 interface_body
613 | INTERFACE_TK identifier extends_interfaces
614 { report_class_declaration ($2); modifier_value = 0; }
615 interface_body
616 | modifiers INTERFACE_TK identifier extends_interfaces
617 { report_class_declaration ($3); modifier_value = 0; }
618 interface_body
619 ;
620
621 extends_interfaces:
622 EXTENDS_TK interface_type
623 | extends_interfaces C_TK interface_type
624 ;
625
626 interface_body:
627 OCB_TK CCB_TK
628 { pop_class_context (); }
629 | OCB_TK interface_member_declarations CCB_TK
630 { pop_class_context (); }
631 ;
632
633 interface_member_declarations:
634 interface_member_declaration
635 | interface_member_declarations interface_member_declaration
636 ;
637
638 interface_member_declaration:
639 constant_declaration
640 | abstract_method_declaration
641 | class_declaration /* Added, JDK1.1 inner classes */
642 | interface_declaration /* Added, JDK1.1 inner classes */
643 ;
644
645 constant_declaration:
646 field_declaration
647 ;
648
649 abstract_method_declaration:
650 method_header SC_TK
651 ;
652
653 /* 19.10 Productions from 10: Arrays */
654 array_initializer:
655 OCB_TK CCB_TK
656 | OCB_TK variable_initializers CCB_TK
657 | OCB_TK C_TK CCB_TK
658 | OCB_TK variable_initializers C_TK CCB_TK
659 ;
660
661 variable_initializers:
662 variable_initializer
663 | variable_initializers C_TK variable_initializer
664 ;
665
666 /* 19.11 Production from 14: Blocks and Statements */
667 block:
668 OCB_TK CCB_TK
669 | OCB_TK block_statements CCB_TK
670 ;
671
672 block_statements:
673 block_statement
674 | block_statements block_statement
675 ;
676
677 block_statement:
678 local_variable_declaration_statement
679 | statement
680 | class_declaration /* Added, JDK1.1 inner classes */
681 ;
682
683 local_variable_declaration_statement:
684 local_variable_declaration SC_TK /* Can't catch missing ';' here */
685 ;
686
687 local_variable_declaration:
688 type variable_declarators
689 { USE_ABSORBER; }
690 | modifiers type variable_declarators /* Added, JDK1.1 final locals */
691 { modifier_value = 0; }
692 ;
693
694 statement:
695 statement_without_trailing_substatement
696 | labeled_statement
697 | if_then_statement
698 | if_then_else_statement
699 | while_statement
700 | for_statement
701 ;
702
703 statement_nsi:
704 statement_without_trailing_substatement
705 | labeled_statement_nsi
706 | if_then_else_statement_nsi
707 | while_statement_nsi
708 | for_statement_nsi
709 ;
710
711 statement_without_trailing_substatement:
712 block
713 | empty_statement
714 | expression_statement
715 | switch_statement
716 | do_statement
717 | break_statement
718 | continue_statement
719 | return_statement
720 | synchronized_statement
721 | throw_statement
722 | try_statement
723 | assert_statement
724 ;
725
726 empty_statement:
727 SC_TK
728 ;
729
730 label_decl:
731 identifier REL_CL_TK
732 { USE_ABSORBER; }
733 ;
734
735 labeled_statement:
736 label_decl statement
737 ;
738
739 labeled_statement_nsi:
740 label_decl statement_nsi
741 ;
742
743 /* We concentrate here a bunch of error handling rules that we couldn't write
744 earlier, because expression_statement catches a missing ';'. */
745 expression_statement:
746 statement_expression SC_TK
747 ;
748
749 statement_expression:
750 assignment
751 | pre_increment_expression
752 | pre_decrement_expression
753 | post_increment_expression
754 | post_decrement_expression
755 | method_invocation
756 | class_instance_creation_expression
757 ;
758
759 if_then_statement:
760 IF_TK OP_TK expression CP_TK statement { ++complexity; }
761 ;
762
763 if_then_else_statement:
764 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
765 { ++complexity; }
766 ;
767
768 if_then_else_statement_nsi:
769 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
770 { ++complexity; }
771 ;
772
773 switch_statement:
774 SWITCH_TK OP_TK expression CP_TK switch_block
775 ;
776
777 switch_block:
778 OCB_TK CCB_TK
779 | OCB_TK switch_labels CCB_TK
780 | OCB_TK switch_block_statement_groups CCB_TK
781 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
782 ;
783
784 switch_block_statement_groups:
785 switch_block_statement_group
786 | switch_block_statement_groups switch_block_statement_group
787 ;
788
789 switch_block_statement_group:
790 switch_labels block_statements { ++complexity; }
791 ;
792
793
794 switch_labels:
795 switch_label
796 | switch_labels switch_label
797 ;
798
799 switch_label:
800 CASE_TK constant_expression REL_CL_TK
801 | DEFAULT_TK REL_CL_TK
802 ;
803
804 while_expression:
805 WHILE_TK OP_TK expression CP_TK { ++complexity; }
806 ;
807
808 while_statement:
809 while_expression statement
810 ;
811
812 while_statement_nsi:
813 while_expression statement_nsi
814 ;
815
816 do_statement_begin:
817 DO_TK
818 ;
819
820 do_statement:
821 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
822 { ++complexity; }
823 ;
824
825 for_statement:
826 for_begin SC_TK expression SC_TK for_update CP_TK statement
827 | for_begin SC_TK SC_TK for_update CP_TK statement
828 ;
829
830 for_statement_nsi:
831 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
832 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
833 ;
834
835 for_header:
836 FOR_TK OP_TK
837 ;
838
839 for_begin:
840 for_header for_init { ++complexity; }
841 ;
842 for_init: /* Can be empty */
843 | statement_expression_list
844 | local_variable_declaration
845 ;
846
847 for_update: /* Can be empty */
848 | statement_expression_list
849 ;
850
851 statement_expression_list:
852 statement_expression
853 | statement_expression_list C_TK statement_expression
854 ;
855
856 break_statement:
857 BREAK_TK SC_TK
858 | BREAK_TK identifier SC_TK
859 ;
860
861 /* `continue' with a label is considered for complexity but ordinary
862 continue is not. */
863 continue_statement:
864 CONTINUE_TK SC_TK
865 | CONTINUE_TK identifier SC_TK { ++complexity; }
866 ;
867
868 return_statement:
869 RETURN_TK SC_TK
870 | RETURN_TK expression SC_TK
871 ;
872
873 throw_statement:
874 THROW_TK expression SC_TK { ++complexity; }
875 ;
876
877 assert_statement:
878 ASSERT_TK expression REL_CL_TK expression SC_TK
879 | ASSERT_TK expression SC_TK
880 | ASSERT_TK error
881 {yyerror ("Missing term"); RECOVER;}
882 | ASSERT_TK expression error
883 {yyerror ("';' expected"); RECOVER;}
884 ;
885 synchronized_statement:
886 synchronized OP_TK expression CP_TK block
887 | synchronized OP_TK expression CP_TK error
888 ;
889
890 synchronized: /* Test lval.sub_token here */
891 MODIFIER_TK
892 { USE_ABSORBER; }
893 ;
894
895 try_statement:
896 TRY_TK block catches
897 | TRY_TK block finally
898 | TRY_TK block catches finally
899 ;
900
901 catches:
902 catch_clause
903 | catches catch_clause
904 ;
905
906 catch_clause:
907 CATCH_TK OP_TK formal_parameter CP_TK block { ++complexity; }
908 ;
909
910 finally:
911 FINALLY_TK block { ++complexity; }
912 ;
913
914 /* 19.12 Production from 15: Expressions */
915 primary:
916 primary_no_new_array
917 | array_creation_expression
918 ;
919
920 primary_no_new_array:
921 literal
922 | THIS_TK
923 | OP_TK expression CP_TK
924 | class_instance_creation_expression
925 | field_access
926 | method_invocation
927 | array_access
928 | type_literals
929 /* Added, JDK1.1 inner classes. Documentation is wrong
930 refering to a 'ClassName' (class_name) rule that doesn't
931 exist. Used name instead. */
932 | name DOT_TK THIS_TK
933 { USE_ABSORBER; }
934 ;
935
936 type_literals:
937 name DOT_TK CLASS_TK
938 { USE_ABSORBER; }
939 | array_type DOT_TK CLASS_TK
940 { USE_ABSORBER; }
941 | primitive_type DOT_TK CLASS_TK
942 { USE_ABSORBER; }
943 | VOID_TK DOT_TK CLASS_TK
944 { USE_ABSORBER; }
945 ;
946
947 class_instance_creation_expression:
948 NEW_TK class_type OP_TK argument_list CP_TK
949 | NEW_TK class_type OP_TK CP_TK
950 | anonymous_class_creation
951 | something_dot_new identifier OP_TK CP_TK
952 | something_dot_new identifier OP_TK CP_TK class_body
953 | something_dot_new identifier OP_TK argument_list CP_TK
954 | something_dot_new identifier OP_TK argument_list CP_TK class_body
955 ;
956
957 anonymous_class_creation:
958 NEW_TK class_type OP_TK CP_TK
959 { report_class_declaration (anonymous_context); }
960 class_body
961 | NEW_TK class_type OP_TK argument_list CP_TK
962 { report_class_declaration (anonymous_context); }
963 class_body
964 ;
965
966 something_dot_new: /* Added, not part of the specs. */
967 name DOT_TK NEW_TK
968 { USE_ABSORBER; }
969 | primary DOT_TK NEW_TK
970 ;
971
972 argument_list:
973 expression
974 | argument_list C_TK expression
975 | argument_list C_TK error
976 ;
977
978 array_creation_expression:
979 NEW_TK primitive_type dim_exprs
980 | NEW_TK class_or_interface_type dim_exprs
981 | NEW_TK primitive_type dim_exprs dims
982 | NEW_TK class_or_interface_type dim_exprs dims
983 /* Added, JDK1.1 anonymous array. Initial documentation rule
984 modified */
985 | NEW_TK class_or_interface_type dims array_initializer
986 | NEW_TK primitive_type dims array_initializer
987 ;
988
989 dim_exprs:
990 dim_expr
991 | dim_exprs dim_expr
992 ;
993
994 dim_expr:
995 OSB_TK expression CSB_TK
996 ;
997
998 dims:
999 OSB_TK CSB_TK
1000 { bracket_count = 1; }
1001 | dims OSB_TK CSB_TK
1002 { bracket_count++; }
1003 ;
1004
1005 field_access:
1006 primary DOT_TK identifier
1007 | SUPER_TK DOT_TK identifier
1008 ;
1009
1010 /* We include method invocation in the complexity measure on the
1011 theory that most method calls are virtual and therefore involve a
1012 decision point. */
1013 method_invocation:
1014 name OP_TK CP_TK
1015 { USE_ABSORBER; ++complexity; }
1016 | name OP_TK argument_list CP_TK
1017 { USE_ABSORBER; ++complexity; }
1018 | primary DOT_TK identifier OP_TK CP_TK { ++complexity; }
1019 | primary DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; }
1020 | SUPER_TK DOT_TK identifier OP_TK CP_TK { ++complexity; }
1021 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; }
1022 ;
1023
1024 array_access:
1025 name OSB_TK expression CSB_TK
1026 { USE_ABSORBER; }
1027 | primary_no_new_array OSB_TK expression CSB_TK
1028 ;
1029
1030 postfix_expression:
1031 primary
1032 | name
1033 { USE_ABSORBER; }
1034 | post_increment_expression
1035 | post_decrement_expression
1036 ;
1037
1038 post_increment_expression:
1039 postfix_expression INCR_TK
1040 ;
1041
1042 post_decrement_expression:
1043 postfix_expression DECR_TK
1044 ;
1045
1046 unary_expression:
1047 pre_increment_expression
1048 | pre_decrement_expression
1049 | PLUS_TK unary_expression
1050 | MINUS_TK unary_expression
1051 | unary_expression_not_plus_minus
1052 ;
1053
1054 pre_increment_expression:
1055 INCR_TK unary_expression
1056 ;
1057
1058 pre_decrement_expression:
1059 DECR_TK unary_expression
1060 ;
1061
1062 unary_expression_not_plus_minus:
1063 postfix_expression
1064 | NOT_TK unary_expression
1065 | NEG_TK unary_expression
1066 | cast_expression
1067 ;
1068
1069 cast_expression: /* Error handling here is potentially weak */
1070 OP_TK primitive_type dims CP_TK unary_expression
1071 | OP_TK primitive_type CP_TK unary_expression
1072 | OP_TK expression CP_TK unary_expression_not_plus_minus
1073 | OP_TK name dims CP_TK unary_expression_not_plus_minus
1074 ;
1075
1076 multiplicative_expression:
1077 unary_expression
1078 | multiplicative_expression MULT_TK unary_expression
1079 | multiplicative_expression DIV_TK unary_expression
1080 | multiplicative_expression REM_TK unary_expression
1081 ;
1082
1083 additive_expression:
1084 multiplicative_expression
1085 | additive_expression PLUS_TK multiplicative_expression
1086 | additive_expression MINUS_TK multiplicative_expression
1087 ;
1088
1089 shift_expression:
1090 additive_expression
1091 | shift_expression LS_TK additive_expression
1092 | shift_expression SRS_TK additive_expression
1093 | shift_expression ZRS_TK additive_expression
1094 ;
1095
1096 relational_expression:
1097 shift_expression
1098 | relational_expression LT_TK shift_expression
1099 | relational_expression GT_TK shift_expression
1100 | relational_expression LTE_TK shift_expression
1101 | relational_expression GTE_TK shift_expression
1102 | relational_expression INSTANCEOF_TK reference_type
1103 ;
1104
1105 equality_expression:
1106 relational_expression
1107 | equality_expression EQ_TK relational_expression
1108 | equality_expression NEQ_TK relational_expression
1109 ;
1110
1111 and_expression:
1112 equality_expression
1113 | and_expression AND_TK equality_expression
1114 ;
1115
1116 exclusive_or_expression:
1117 and_expression
1118 | exclusive_or_expression XOR_TK and_expression
1119 ;
1120
1121 inclusive_or_expression:
1122 exclusive_or_expression
1123 | inclusive_or_expression OR_TK exclusive_or_expression
1124 ;
1125
1126 conditional_and_expression:
1127 inclusive_or_expression
1128 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
1129 { ++complexity; }
1130 ;
1131
1132 conditional_or_expression:
1133 conditional_and_expression
1134 | conditional_or_expression BOOL_OR_TK conditional_and_expression
1135 { ++complexity; }
1136 ;
1137
1138 conditional_expression: /* Error handling here is weak */
1139 conditional_or_expression
1140 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
1141 { ++complexity; }
1142 ;
1143
1144 assignment_expression:
1145 conditional_expression
1146 | assignment
1147 ;
1148
1149 assignment:
1150 left_hand_side assignment_operator assignment_expression
1151 ;
1152
1153 left_hand_side:
1154 name
1155 { USE_ABSORBER; }
1156 | field_access
1157 | array_access
1158 ;
1159
1160 assignment_operator:
1161 ASSIGN_ANY_TK
1162 | ASSIGN_TK
1163 ;
1164
1165 expression:
1166 assignment_expression
1167 ;
1168
1169 constant_expression:
1170 expression
1171 ;
1172
1173 %%
1174
1175 /* Create a new parser context */
1176
1177 void
1178 java_push_parser_context ()
1179 {
1180 struct parser_ctxt *new =
1181 (struct parser_ctxt *) xcalloc (1, sizeof (struct parser_ctxt));
1182
1183 new->next = ctxp;
1184 ctxp = new;
1185 }
1186
1187 static void
push_class_context(name)1188 push_class_context (name)
1189 const char *name;
1190 {
1191 struct class_context *ctx;
1192
1193 ctx = (struct class_context *) xmalloc (sizeof (struct class_context));
1194 ctx->name = (char *) name;
1195 ctx->next = current_class_context;
1196 current_class_context = ctx;
1197 }
1198
1199 static void
pop_class_context()1200 pop_class_context ()
1201 {
1202 struct class_context *ctx;
1203
1204 if (current_class_context == NULL)
1205 return;
1206
1207 ctx = current_class_context->next;
1208 if (current_class_context->name != anonymous_context)
1209 free (current_class_context->name);
1210 free (current_class_context);
1211
1212 current_class_context = ctx;
1213 if (current_class_context == NULL)
1214 anonymous_count = 0;
1215 }
1216
1217 /* Recursively construct the class name. This is just a helper
1218 function for get_class_name(). */
1219 static int
make_class_name_recursive(stack,ctx)1220 make_class_name_recursive (stack, ctx)
1221 struct obstack *stack;
1222 struct class_context *ctx;
1223 {
1224 if (! ctx)
1225 return 0;
1226
1227 make_class_name_recursive (stack, ctx->next);
1228
1229 /* Replace an anonymous context with the appropriate counter value. */
1230 if (ctx->name == anonymous_context)
1231 {
1232 char buf[50];
1233 ++anonymous_count;
1234 sprintf (buf, "%d", anonymous_count);
1235 ctx->name = xstrdup (buf);
1236 }
1237
1238 obstack_grow (stack, ctx->name, strlen (ctx->name));
1239 obstack_1grow (stack, '$');
1240
1241 return ISDIGIT (ctx->name[0]);
1242 }
1243
1244 /* Return a newly allocated string holding the name of the class. */
1245 static char *
get_class_name()1246 get_class_name ()
1247 {
1248 char *result;
1249 int last_was_digit;
1250 struct obstack name_stack;
1251
1252 obstack_init (&name_stack);
1253
1254 /* Duplicate the logic of parse.y:maybe_make_nested_class_name(). */
1255 last_was_digit = make_class_name_recursive (&name_stack,
1256 current_class_context->next);
1257
1258 if (! last_was_digit
1259 && method_depth
1260 && current_class_context->name != anonymous_context)
1261 {
1262 char buf[50];
1263 ++anonymous_count;
1264 sprintf (buf, "%d", anonymous_count);
1265 obstack_grow (&name_stack, buf, strlen (buf));
1266 obstack_1grow (&name_stack, '$');
1267 }
1268
1269 if (current_class_context->name == anonymous_context)
1270 {
1271 char buf[50];
1272 ++anonymous_count;
1273 sprintf (buf, "%d", anonymous_count);
1274 current_class_context->name = xstrdup (buf);
1275 obstack_grow0 (&name_stack, buf, strlen (buf));
1276 }
1277 else
1278 obstack_grow0 (&name_stack, current_class_context->name,
1279 strlen (current_class_context->name));
1280
1281 result = xstrdup (obstack_finish (&name_stack));
1282 obstack_free (&name_stack, NULL);
1283
1284 return result;
1285 }
1286
1287 /* Actions defined here */
1288
1289 static void
report_class_declaration(name)1290 report_class_declaration (name)
1291 const char * name;
1292 {
1293 extern int flag_dump_class, flag_list_filename;
1294
1295 push_class_context (name);
1296 if (flag_dump_class)
1297 {
1298 char *name = get_class_name ();
1299
1300 if (!previous_output)
1301 {
1302 if (flag_list_filename)
1303 fprintf (out, "%s: ", input_filename);
1304 previous_output = 1;
1305 }
1306
1307 if (package_name)
1308 fprintf (out, "%s.%s ", package_name, name);
1309 else
1310 fprintf (out, "%s ", name);
1311
1312 free (name);
1313 }
1314 }
1315
1316 static void
report_main_declaration(declarator)1317 report_main_declaration (declarator)
1318 struct method_declarator *declarator;
1319 {
1320 extern int flag_find_main;
1321
1322 if (flag_find_main
1323 && modifier_value == 2
1324 && !strcmp (declarator->method_name, "main")
1325 && declarator->args
1326 && declarator->args [0] == '['
1327 && (! strcmp (declarator->args+1, "String")
1328 || ! strcmp (declarator->args + 1, "java.lang.String"))
1329 && current_class_context)
1330 {
1331 if (!previous_output)
1332 {
1333 char *name = get_class_name ();
1334 if (package_name)
1335 fprintf (out, "%s.%s ", package_name, name);
1336 else
1337 fprintf (out, "%s", name);
1338 free (name);
1339 previous_output = 1;
1340 }
1341 }
1342 }
1343
1344 void
report()1345 report ()
1346 {
1347 extern int flag_complexity;
1348 if (flag_complexity)
1349 fprintf (out, "%s %d\n", input_filename, complexity);
1350 }
1351
1352 /* Reset global status used by the report functions. */
1353
reset_report()1354 void reset_report ()
1355 {
1356 previous_output = 0;
1357 package_name = NULL;
1358 current_class_context = NULL;
1359 complexity = 0;
1360 }
1361
1362 void
yyerror(msg)1363 yyerror (msg)
1364 const char *msg ATTRIBUTE_UNUSED;
1365 {
1366 fprintf (stderr, "%s: %d: %s\n", input_filename, lineno, msg);
1367 exit (1);
1368 }
1369