xref: /openbsd/gnu/usr.bin/gcc/gcc/java/parse-scan.y (revision c87b03e5)
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