OSDN Git Service

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