OSDN Git Service

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