OSDN Git Service

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