OSDN Git Service

* g++.old-deja/g++.other/dwarf2-1.C: Move...
[pf3gnuchains/gcc-fork.git] / gcc / java / parse-scan.y
index 73a46ab..28d7946 100644 (file)
@@ -63,12 +63,11 @@ static int absorber;
 #define USE_ABSORBER absorber = 0
 
 /* Keep track of the current class name and package name.  */
-static const char *current_class;
+static char *current_class;
 static const char *package_name;
 
 /* Keep track of the current inner class qualifier. */
-static char *inner_qualifier;
-static int   inner_qualifier_length;
+static int current_class_length;
 
 /* Keep track of whether things have be listed before.  */
 static int previous_output;
@@ -76,10 +75,16 @@ static int previous_output;
 /* Record modifier uses  */
 static int modifier_value;
 
-/* Keep track of number of bracket pairs after a variable declarator
+/* Record (almost) cyclomatic complexity.  */
+static int complexity; 
+
+/* Keeps track of number of bracket pairs after a variable declarator
    id.  */
 static int bracket_count; 
 
+/* Numbers anonymous classes */
+static int anonymous_count;
+
 /* Record a method declaration  */
 struct method_declarator {
   const char *method_name;
@@ -99,6 +104,8 @@ static void report_main_declaration PARAMS ((struct method_declarator *));
 static void push_class_context PARAMS ((const char *));
 static void pop_class_context PARAMS ((void));
 
+void report PARAMS ((void)); 
+
 #include "lex.h"
 #include "parse.h"
 %}
@@ -138,6 +145,7 @@ static void pop_class_context PARAMS ((void));
 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
+%token   STRICT_TK
 
 /* Keep those two in order, too */
 %token   DECR_TK INCR_TK
@@ -234,14 +242,15 @@ interface_type:
 ;
 
 array_type:
-       primitive_type OSB_TK CSB_TK
-|      name OSB_TK CSB_TK
+       primitive_type dims
                {
-                 $$ = concat ("[", $1, NULL);
+                 while (bracket_count-- > 0) 
+                   $$ = concat ("[", $1, NULL);
                }
-|      array_type OSB_TK CSB_TK
-               {       
-                 $$ = concat ("[", $1, NULL);
+|      name dims
+               {
+                 while (bracket_count-- > 0) 
+                   $$ = concat ("[", $1, NULL);
                }
 ;
 
@@ -308,7 +317,7 @@ type_import_on_demand_declaration:
 type_declaration:
        class_declaration
 |      interface_declaration
-|      SC_TK
+|      empty_statement
 ;
 
 /* 19.7 Shortened from the original:
@@ -385,6 +394,7 @@ class_member_declaration:
 |      method_declaration
 |      class_declaration       /* Added, JDK1.1 inner classes */
 |      interface_declaration   /* Added, JDK1.1 inner classes */
+|      empty_statement
 ;
 
 /* 19.8.2 Productions from 8.3: Field Declarations  */
@@ -505,14 +515,12 @@ class_type_list:
 
 method_body:
        block
-|      block SC_TK
 |      SC_TK
 ;
 
 /* 19.8.4 Productions from 8.5: Static Initializers  */
 static_initializer:
        static block
-|      static block SC_TK      /* Shouldn't be here. FIXME */
 ;
 
 static:                                /* Test lval.sub_token here */
@@ -724,15 +732,17 @@ statement_expression:
 ;
 
 if_then_statement:
-       IF_TK OP_TK expression CP_TK statement
+       IF_TK OP_TK expression CP_TK statement { ++complexity; }
 ;
 
 if_then_else_statement:
        IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
+       { ++complexity; }
 ;
 
 if_then_else_statement_nsi:
        IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
+       { ++complexity; }
 ;
 
 switch_statement:
@@ -752,7 +762,7 @@ switch_block_statement_groups:
 ;
 
 switch_block_statement_group:
-       switch_labels block_statements
+       switch_labels block_statements { ++complexity; }
 ;
 
 
@@ -767,7 +777,7 @@ switch_label:
 ;
 
 while_expression:
-       WHILE_TK OP_TK expression CP_TK
+       WHILE_TK OP_TK expression CP_TK { ++complexity; }
 ;
 
 while_statement:
@@ -784,6 +794,7 @@ do_statement_begin:
 
 do_statement: 
        do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
+       { ++complexity; }
 ;
 
 for_statement:
@@ -801,7 +812,7 @@ for_header:
 ;
 
 for_begin:
-       for_header for_init
+       for_header for_init { ++complexity; }
 ;
 for_init:                      /* Can be empty */
 |      statement_expression_list
@@ -822,9 +833,11 @@ break_statement:
 |      BREAK_TK identifier SC_TK
 ;
 
+/* `continue' with a label is considered for complexity but ordinary
+   continue is not.  */
 continue_statement:
        CONTINUE_TK SC_TK
-|       CONTINUE_TK identifier SC_TK
+       |       CONTINUE_TK identifier SC_TK { ++complexity; }
 ;
 
 return_statement:
@@ -833,7 +846,7 @@ return_statement:
 ;
 
 throw_statement:
-       THROW_TK expression SC_TK
+       THROW_TK expression SC_TK { ++complexity; }
 ;
 
 synchronized_statement:
@@ -858,11 +871,11 @@ catches:
 ;
 
 catch_clause:
-       CATCH_TK OP_TK formal_parameter CP_TK block
+       CATCH_TK OP_TK formal_parameter CP_TK block { ++complexity; }
 ;
 
 finally:
-       FINALLY_TK block
+       FINALLY_TK block { ++complexity; }
 ;
 
 /* 19.12 Production from 15: Expressions  */
@@ -879,14 +892,7 @@ primary_no_new_array:
 |      field_access
 |      method_invocation
 |      array_access
-       /* type DOT_TK CLASS_TK doens't work. So we split the rule
-          'type' into its components. Missing is something for array,
-          which will complete the reference_type part. FIXME */
-|      name DOT_TK CLASS_TK           /* Added, JDK1.1 class literals */
-               { USE_ABSORBER; }
-|      primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
-               { USE_ABSORBER; }
-|      VOID_TK DOT_TK CLASS_TK        /* Added, JDK1.1 class literals */
+|      type_literals
         /* Added, JDK1.1 inner classes. Documentation is wrong
            refering to a 'ClassName' (class_name) rule that doesn't
            exist. Used name instead.  */
@@ -894,23 +900,36 @@ primary_no_new_array:
                { USE_ABSORBER; }
 ;
 
+type_literals:
+       name DOT_TK CLASS_TK
+               { USE_ABSORBER; }
+|      array_type DOT_TK CLASS_TK
+               { USE_ABSORBER; }
+|      primitive_type DOT_TK CLASS_TK
+               { USE_ABSORBER; }
+|      VOID_TK DOT_TK CLASS_TK
+               { USE_ABSORBER; }
+;
+
 class_instance_creation_expression:
        NEW_TK class_type OP_TK argument_list CP_TK
 |      NEW_TK class_type OP_TK CP_TK
-        /* Added, JDK1.1 inner classes but modified to use
-           'class_type' instead of 'TypeName' (type_name) mentionned
-           in the documentation but doesn't exist. */
-|      NEW_TK class_type OP_TK argument_list CP_TK class_body
-|      NEW_TK class_type OP_TK CP_TK class_body         
-        /* Added, JDK1.1 inner classes, modified to use name or
-          primary instead of primary solely which couldn't work in
-          all situations.  */
+|      anonymous_class_creation
 |      something_dot_new identifier OP_TK CP_TK
 |      something_dot_new identifier OP_TK CP_TK class_body
 |      something_dot_new identifier OP_TK argument_list CP_TK
 |      something_dot_new identifier OP_TK argument_list CP_TK class_body
 ;
 
+anonymous_class_creation:
+       NEW_TK class_type OP_TK CP_TK
+               { report_class_declaration (NULL); }
+       class_body         
+|      NEW_TK class_type OP_TK argument_list CP_TK
+               { report_class_declaration (NULL); }
+       class_body
+;
+
 something_dot_new:             /* Added, not part of the specs. */
        name DOT_TK NEW_TK
                { USE_ABSORBER; }
@@ -945,7 +964,9 @@ dim_expr:
 
 dims:                          
        OSB_TK CSB_TK
+               { bracket_count = 1; }
 |      dims OSB_TK CSB_TK
+               { bracket_count++; }
 ;
 
 field_access:
@@ -953,15 +974,18 @@ field_access:
 |      SUPER_TK DOT_TK identifier
 ;
 
+/* We include method invocation in the complexity measure on the
+   theory that most method calls are virtual and therefore involve a
+   decision point.  */
 method_invocation:
        name OP_TK CP_TK
-               { USE_ABSORBER; }
+               { USE_ABSORBER; ++complexity; }
 |      name OP_TK argument_list CP_TK
-               { USE_ABSORBER; }
-|      primary DOT_TK identifier OP_TK CP_TK
-|      primary DOT_TK identifier OP_TK argument_list CP_TK
-|      SUPER_TK DOT_TK identifier OP_TK CP_TK
-|      SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
+               { USE_ABSORBER; ++complexity; }
+|      primary DOT_TK identifier OP_TK CP_TK { ++complexity; }
+|      primary DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; }
+|      SUPER_TK DOT_TK identifier OP_TK CP_TK { ++complexity; }
+|      SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; }
 ;
 
 array_access:
@@ -1069,16 +1093,19 @@ inclusive_or_expression:
 conditional_and_expression:
        inclusive_or_expression
 |      conditional_and_expression BOOL_AND_TK inclusive_or_expression
+       { ++complexity; }
 ;
 
 conditional_or_expression:
        conditional_and_expression
 |      conditional_or_expression BOOL_OR_TK conditional_and_expression
+       { ++complexity; }
 ;
 
 conditional_expression:                /* Error handling here is weak */
        conditional_or_expression
 |      conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
+       { ++complexity; }
 ;
 
 assignment_expression:
@@ -1128,29 +1155,61 @@ static void
 push_class_context (name)
     const char *name;
 {
-  size_t name_length = strlen (name);
-  inner_qualifier = xrealloc (inner_qualifier, 
-                             inner_qualifier_length + name_length+2);
-  memcpy (inner_qualifier+inner_qualifier_length, name, name_length);
-  inner_qualifier_length += name_length;
-  inner_qualifier [inner_qualifier_length] = '$';
-  inner_qualifier [++inner_qualifier_length] = '\0';
+  /* If we already have CURRENT_CLASS set, we're in an inter
+     class. Mangle its name. */
+  if (current_class)
+    {
+      const char *p;
+      char anonymous [3];
+      int additional_length;
+      
+      /* NAME set to NULL indicates an anonymous class, which are named by
+        numbering them. */
+      if (!name)
+       {
+         sprintf (anonymous, "%d", ++anonymous_count);
+         p = anonymous;
+       }
+      else
+       p = name;
+      
+      additional_length = strlen (p)+1; /* +1 for `$' */
+      current_class = xrealloc (current_class, 
+                               current_class_length + additional_length + 1);
+      current_class [current_class_length] = '$';
+      strcpy (&current_class [current_class_length+1], p);
+      current_class_length += additional_length;
+    }
+  else
+    {
+      if (!name)
+       return;
+      current_class_length = strlen (name);
+      current_class = xmalloc (current_class_length+1);
+      strcpy (current_class, name);
+    }
 }
 
 static void
 pop_class_context ()
 {
-  while (--inner_qualifier_length > 0
-        && inner_qualifier [inner_qualifier_length-1] != '$')
+  /* Go back to the last `$' and cut. */
+  while (--current_class_length > 0
+        && current_class [current_class_length] != '$')
     ;
-  inner_qualifier = xrealloc (inner_qualifier, inner_qualifier_length+1);
-  inner_qualifier [inner_qualifier_length] = '\0';
-  if (inner_qualifier_length == -1)
-    inner_qualifier_length = 0;
+  if (current_class_length)
+    {
+      current_class = xrealloc (current_class, current_class_length+1);
+      current_class [current_class_length] = '\0';
+    }
+  else
+    {
+      current_class = NULL;
+      anonymous_count = 0;
+    }
 }
 
 /* Actions defined here */
-#define INNER_QUALIFIER (inner_qualifier ? inner_qualifier : "")
 
 static void
 report_class_declaration (name)
@@ -1158,6 +1217,7 @@ report_class_declaration (name)
 {
   extern int flag_dump_class, flag_list_filename;
 
+  push_class_context (name);
   if (flag_dump_class)
     {
       if (!previous_output)
@@ -1168,13 +1228,10 @@ report_class_declaration (name)
        }
        
       if (package_name)
-       fprintf (out, "%s.%s%s ", package_name, INNER_QUALIFIER, name);
+       fprintf (out, "%s.%s ", package_name, current_class);
       else
-       fprintf (out, "%s%s ", INNER_QUALIFIER, name);
+       fprintf (out, "%s ", current_class);
     }
-
-  push_class_context (name);
-  current_class = name;
 }
 
 static void
@@ -1203,12 +1260,22 @@ report_main_declaration (declarator)
     }
 }
 
+void
+report ()
+{
+  extern int flag_complexity;
+  if (flag_complexity)
+    fprintf (out, "%s %d\n", input_filename, complexity);
+}
+
 /* Reset global status used by the report functions.  */
 
 void reset_report ()
 {
   previous_output = 0;
-  current_class = package_name = NULL;
+  package_name = NULL;
+  current_class = NULL;
+  complexity = 0;
 }
 
 void