OSDN Git Service

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