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