OSDN Git Service

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