OSDN Git Service

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