OSDN Git Service

2004-09-28 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / parse-scan.y
index 0223934..e05fdb5 100644 (file)
@@ -1,21 +1,22 @@
 /* Parser grammar for quick source code scan of Java(TM) language programs.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
+   Free Software Foundation, Inc.
    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
+along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.
 
@@ -39,31 +40,34 @@ definitions and other extensions.  */
 
 #include "config.h"
 #include "system.h"
-
+#include "coretypes.h"
+#include "tm.h"
+#include "input.h"
 #include "obstack.h"
+#include "toplev.h"
 
-extern char *input_filename;
 extern FILE *finput, *out;
+/* Current position in real source file.  */
+
+location_t input_location;
 
 /* Obstack for the lexer.  */
 struct obstack temporary_obstack;
 
 /* The current parser context.  */
-static struct parser_ctxt *ctxp;
+struct parser_ctxt *ctxp;
 
-/* Error and warning counts, current line number, because they're used
-   elsewhere  */
+/* Error and warning counts, because they're used elsewhere  */
 int java_error_count;
 int java_warning_count;
-int lineno;
 
 /* Tweak default rules when necessary.  */
 static int absorber;
 #define USE_ABSORBER absorber = 0
 
-/* Keep track of the current class name and package name.  */
-static char *current_class;
-static char *package_name;
+/* Keep track of the current package name.  */
+static const char *package_name;
 
 /* Keep track of whether things have be listed before.  */
 static int previous_output;
@@ -71,22 +75,54 @@ static int previous_output;
 /* Record modifier uses  */
 static int modifier_value;
 
+/* 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;
+
+/* This is used to record the current class context.  */
+struct class_context
+{
+  char *name;
+  struct class_context *next;
+};
+
+/* The global class context.  */
+static struct class_context *current_class_context;
+
+/* A special constant used to represent an anonymous context.  */
+static const char *anonymous_context = "ANONYMOUS";
+
+/* Count of method depth.  */
+static int method_depth; 
+
 /* Record a method declaration  */
 struct method_declarator {
-  char *method_name;
-  char *args;
+  const char *method_name;
+  const char *args;
 };
 #define NEW_METHOD_DECLARATOR(D,N,A)                                        \
 {                                                                           \
-  (D) =                                                                     \
-    (struct method_declarator *)xmalloc (sizeof (struct method_declarator)); \
+  (D) = xmalloc (sizeof (struct method_declarator));                        \
   (D)->method_name = (N);                                                   \
   (D)->args = (A);                                                          \
 }
 
 /* Two actions for this grammar */
-static void report_class_declaration PROTO ((char *));
-static void report_main_declaration PROTO ((struct method_declarator *));
+static int make_class_name_recursive (struct obstack *stack,
+                                     struct class_context *ctx);
+static char *get_class_name (void);
+static void report_class_declaration (const char *);
+static void report_main_declaration (struct method_declarator *);
+static void push_class_context (const char *);
+static void pop_class_context (void);
+
+void report (void); 
 
 #include "lex.h"
 #include "parse.h"
@@ -98,6 +134,12 @@ static void report_main_declaration PROTO ((struct method_declarator *));
   int value;                   /* For modifiers */
 }
 
+%{
+extern int flag_assert;
+
+#include "lex.c"
+%}
+
 %pure_parser
 
 /* Things defined here have to match the order of what's in the
@@ -123,6 +165,7 @@ static void report_main_declaration PROTO ((struct method_declarator *));
 %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
@@ -139,6 +182,7 @@ static void report_main_declaration PROTO ((struct method_declarator *));
 %token   SWITCH_TK       CONST_TK           TRY_TK
 %token   FOR_TK          NEW_TK             CONTINUE_TK
 %token   GOTO_TK         PACKAGE_TK         THIS_TK
+%token   ASSERT_TK
 
 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
 %token   CHAR_TK         INTEGRAL_TK
@@ -219,20 +263,15 @@ interface_type:
 ;
 
 array_type:
-       primitive_type OSB_TK CSB_TK
-|      name OSB_TK CSB_TK
+       primitive_type dims
                {
-                 char *n = xmalloc (strlen ($1)+2);
-                 n [0] = '[';
-                 strcpy (n+1, $1);
-                 $$ = n;
+                 while (bracket_count-- > 0) 
+                   $$ = concat ("[", $1, NULL);
                }
-|      array_type OSB_TK CSB_TK
-               {       
-                 char *n = xmalloc (strlen ($1)+2);
-                 n [0] = '[';
-                 strcpy (n+1, $1);
-                 $$ = n;
+|      name dims
+               {
+                 while (bracket_count-- > 0) 
+                   $$ = concat ("[", $1, NULL);
                }
 ;
 
@@ -249,9 +288,7 @@ simple_name:
 qualified_name:
        name DOT_TK identifier
                { 
-                 char *n = xmalloc (strlen ($1)+strlen ($3)+2);
-                 sprintf (n, "%s.%s", $1, $3);
-                 $$ = n;
+                 $$ = concat ($1, ".", $3, NULL);
                }
 ;
 
@@ -301,7 +338,7 @@ type_import_on_demand_declaration:
 type_declaration:
        class_declaration
 |      interface_declaration
-|      SC_TK
+|      empty_statement
 ;
 
 /* 19.7 Shortened from the original:
@@ -356,7 +393,9 @@ interface_type_list:
 
 class_body:
        OCB_TK CCB_TK
+               { pop_class_context (); }
 |      OCB_TK class_body_declarations CCB_TK
+               { pop_class_context (); }
 ;
 
 class_body_declarations:
@@ -376,6 +415,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  */
@@ -399,8 +439,9 @@ variable_declarator:
 
 variable_declarator_id:
        identifier
-               { USE_ABSORBER; }
+               { bracket_count = 0; USE_ABSORBER; }
 |      variable_declarator_id OSB_TK CSB_TK
+               { ++bracket_count; }
 ;
 
 variable_initializer:
@@ -410,7 +451,10 @@ variable_initializer:
 
 /* 19.8.3 Productions from 8.4: Method Declarations  */
 method_declaration:
-       method_header method_body
+       method_header
+               { ++method_depth; }
+       method_body
+               { --method_depth; }
 ;
 
 method_header: 
@@ -446,9 +490,7 @@ formal_parameter_list:
        formal_parameter
 |      formal_parameter_list C_TK formal_parameter
                {
-                 char *n = xmalloc (strlen ($1)+strlen($3)+2);
-                 sprintf (n, "%s,%s", $1, $3);
-                 $$ = n;
+                 $$ = concat ($1, ",", $3, NULL);
                }
 ;
 
@@ -456,10 +498,32 @@ formal_parameter:
        type variable_declarator_id
                { 
                  USE_ABSORBER;
-                 $$ = $1;
+                 if (bracket_count)
+                   {
+                     int i;
+                     char *n = xmalloc (bracket_count + 1 + strlen ($$));
+                     for (i = 0; i < bracket_count; ++i)
+                       n[i] = '[';
+                     strcpy (n + bracket_count, $$);
+                     $$ = n;
+                   }
+                 else
+                   $$ = $1;
                }
 |      modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
-               { $$ = $2; }
+               {
+                 if (bracket_count)
+                   {
+                     int i;
+                     char *n = xmalloc (bracket_count + 1 + strlen ($$));
+                     for (i = 0; i < bracket_count; ++i)
+                       n[i] = '[';
+                     strcpy (n + bracket_count, $$);
+                     $$ = n;
+                   }
+                 else
+                   $$ = $2;
+               }
 ;
 
 throws:
@@ -475,14 +539,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 */
@@ -492,8 +554,8 @@ static:                             /* Test lval.sub_token here */
 
 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
-   - If a forbidded modifier is found, the the error is either the use of
-     a forbidded modifier for a constructor OR bogus attempt to declare a
+   - If a forbidden modifier is found, the error is either the use of
+     a forbidden modifier for a constructor OR bogus attempt to declare a
      method without having specified the return type. FIXME */
 constructor_declaration:
        constructor_declarator throws constructor_body
@@ -504,7 +566,7 @@ constructor_declaration:
 /* extra SC_TK, FIXME */
 |      modifiers constructor_declarator throws constructor_body SC_TK
                { modifier_value = 0; }
-/* I'm not happy with the SC_TK addition. It isn't in the grammer and should
+/* I'm not happy with the SC_TK addition. It isn't in the grammar and should
    probably be matched by and empty statement. But it doesn't work. FIXME */
 ;
 
@@ -542,12 +604,18 @@ this_or_super:                    /* Added, simplifies error diagnostics */
 /* 19.9 Productions from 9: Interfaces  */
 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
 interface_declaration:
-       INTERFACE_TK identifier interface_body
-|      modifiers INTERFACE_TK identifier interface_body
-               { modifier_value = 0; }
-|      INTERFACE_TK identifier extends_interfaces interface_body
-|      modifiers INTERFACE_TK identifier extends_interfaces interface_body
-               { modifier_value = 0; }
+       INTERFACE_TK identifier
+               { report_class_declaration ($2); modifier_value = 0; }
+       interface_body
+|      modifiers INTERFACE_TK identifier
+               { report_class_declaration ($3); modifier_value = 0; }
+       interface_body
+|      INTERFACE_TK identifier extends_interfaces
+               { report_class_declaration ($2); modifier_value = 0; }
+       interface_body
+|      modifiers INTERFACE_TK identifier extends_interfaces
+               { report_class_declaration ($3); modifier_value = 0; }
+       interface_body
 ;
 
 extends_interfaces:
@@ -557,7 +625,9 @@ extends_interfaces:
 
 interface_body:
        OCB_TK CCB_TK
+               { pop_class_context (); }
 |      OCB_TK interface_member_declarations CCB_TK
+               { pop_class_context (); }
 ;
 
 interface_member_declarations:
@@ -650,6 +720,7 @@ statement_without_trailing_substatement:
 |      synchronized_statement
 |      throw_statement
 |      try_statement
+|      assert_statement
 ;
 
 empty_statement:
@@ -686,15 +757,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:
@@ -714,7 +787,7 @@ switch_block_statement_groups:
 ;
 
 switch_block_statement_group:
-       switch_labels block_statements
+       switch_labels block_statements { ++complexity; }
 ;
 
 
@@ -729,7 +802,7 @@ switch_label:
 ;
 
 while_expression:
-       WHILE_TK OP_TK expression CP_TK
+       WHILE_TK OP_TK expression CP_TK { ++complexity; }
 ;
 
 while_statement:
@@ -746,6 +819,7 @@ do_statement_begin:
 
 do_statement: 
        do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
+       { ++complexity; }
 ;
 
 for_statement:
@@ -763,7 +837,7 @@ for_header:
 ;
 
 for_begin:
-       for_header for_init
+       for_header for_init { ++complexity; }
 ;
 for_init:                      /* Can be empty */
 |      statement_expression_list
@@ -784,9 +858,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:
@@ -795,9 +871,17 @@ return_statement:
 ;
 
 throw_statement:
-       THROW_TK expression SC_TK
+       THROW_TK expression SC_TK { ++complexity; }
 ;
 
+assert_statement:
+       ASSERT_TK expression REL_CL_TK expression SC_TK
+|      ASSERT_TK expression SC_TK
+|      ASSERT_TK error
+               {yyerror ("Missing term"); RECOVER;}
+|      ASSERT_TK expression error
+               {yyerror ("';' expected"); RECOVER;}
+;
 synchronized_statement:
        synchronized OP_TK expression CP_TK block
 |      synchronized OP_TK expression CP_TK error
@@ -820,11 +904,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  */
@@ -841,38 +925,44 @@ 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
+           referring to a 'ClassName' (class_name) rule that doesn't
            exist. Used name instead.  */
 |      name DOT_TK THIS_TK
                { 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 (anonymous_context); }
+       class_body         
+|      NEW_TK class_type OP_TK argument_list CP_TK
+               { report_class_declaration (anonymous_context); }
+       class_body
+;
+
 something_dot_new:             /* Added, not part of the specs. */
        name DOT_TK NEW_TK
                { USE_ABSORBER; }
@@ -907,7 +997,9 @@ dim_expr:
 
 dims:                          
        OSB_TK CSB_TK
+               { bracket_count = 1; }
 |      dims OSB_TK CSB_TK
+               { bracket_count++; }
 ;
 
 field_access:
@@ -915,15 +1007,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:
@@ -1031,16 +1126,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:
@@ -1074,50 +1172,144 @@ constant_expression:
 
 %%
 \f
-#include "lex.c"
-
 /* Create a new parser context */
 
 void
-java_push_parser_context ()
+java_push_parser_context (void)
 {
-  struct parser_ctxt *new = 
-    (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
+  struct parser_ctxt *new = xcalloc (1, sizeof (struct parser_ctxt));
 
-  bzero (new, sizeof (struct parser_ctxt));
   new->next = ctxp;
   ctxp = new;
 }  
 
+static void
+push_class_context (const char *name)
+{
+  struct class_context *ctx;
+
+  ctx = xmalloc (sizeof (struct class_context));
+  ctx->name = (char *) name;
+  ctx->next = current_class_context;
+  current_class_context = ctx;
+}
+
+static void
+pop_class_context (void)
+{
+  struct class_context *ctx;
+
+  if (current_class_context == NULL)
+    return;
+
+  ctx = current_class_context->next;
+  if (current_class_context->name != anonymous_context)
+    free (current_class_context->name);
+  free (current_class_context);
+
+  current_class_context = ctx;
+  if (current_class_context == NULL)
+    anonymous_count = 0;
+}
+
+/* Recursively construct the class name.  This is just a helper
+   function for get_class_name().  */
+static int
+make_class_name_recursive (struct obstack *stack, struct class_context *ctx)
+{
+  if (! ctx)
+    return 0;
+
+  make_class_name_recursive (stack, ctx->next);
+
+  /* Replace an anonymous context with the appropriate counter value.  */
+  if (ctx->name == anonymous_context)
+    {
+      char buf[50];
+      ++anonymous_count;
+      sprintf (buf, "%d", anonymous_count);
+      ctx->name = xstrdup (buf);
+    }
+
+  obstack_grow (stack, ctx->name, strlen (ctx->name));
+  obstack_1grow (stack, '$');
+
+  return ISDIGIT (ctx->name[0]);
+}
+
+/* Return a newly allocated string holding the name of the class.  */
+static char *
+get_class_name (void)
+{
+  char *result;
+  int last_was_digit;
+  struct obstack name_stack;
+
+  obstack_init (&name_stack);
+
+  /* Duplicate the logic of parse.y:maybe_make_nested_class_name().  */
+  last_was_digit = make_class_name_recursive (&name_stack,
+                                             current_class_context->next);
+
+  if (! last_was_digit
+      && method_depth
+      && current_class_context->name != anonymous_context)
+    {
+      char buf[50];
+      ++anonymous_count;
+      sprintf (buf, "%d", anonymous_count);
+      obstack_grow (&name_stack, buf, strlen (buf));
+      obstack_1grow (&name_stack, '$');
+    }
+
+  if (current_class_context->name == anonymous_context)
+    {
+      char buf[50];
+      ++anonymous_count;
+      sprintf (buf, "%d", anonymous_count);
+      current_class_context->name = xstrdup (buf);
+      obstack_grow0 (&name_stack, buf, strlen (buf));
+    }
+  else
+    obstack_grow0 (&name_stack, current_class_context->name,
+                  strlen (current_class_context->name));
+
+  result = xstrdup (obstack_finish (&name_stack));
+  obstack_free (&name_stack, NULL);
+
+  return result;
+}
+
 /* Actions defined here */
 
 static void
-report_class_declaration (name)
-     char * name;
+report_class_declaration (const char * name)
 {
   extern int flag_dump_class, flag_list_filename;
 
+  push_class_context (name);
   if (flag_dump_class)
     {
+      char *name = get_class_name ();
+
       if (!previous_output)
        {
          if (flag_list_filename)
            fprintf (out, "%s: ", input_filename);
          previous_output = 1;
        }
-       
+
       if (package_name)
        fprintf (out, "%s.%s ", package_name, name);
       else
        fprintf (out, "%s ", name);
+
+      free (name);
     }
-      
-  current_class = name;
 }
 
 static void
-report_main_declaration (declarator)
-     struct method_declarator *declarator;
+report_main_declaration (struct method_declarator *declarator)
 {
   extern int flag_find_main;
 
@@ -1128,40 +1320,43 @@ report_main_declaration (declarator)
       && declarator->args [0] == '[' 
       && (! strcmp (declarator->args+1, "String")
          || ! strcmp (declarator->args + 1, "java.lang.String"))
-      && current_class)
+      && current_class_context)
     {
       if (!previous_output)
        {
+         char *name = get_class_name ();
          if (package_name)
-           fprintf (out, "%s.%s ", package_name, current_class);
+           fprintf (out, "%s.%s ", package_name, name);
          else
-           fprintf (out, current_class);
+           fprintf (out, "%s", name);
+         free (name);
          previous_output = 1;
        }
     }
 }
 
-/* Reset global status used by the report functions.  */
-
-void reset_report ()
+void
+report (void)
 {
-  previous_output = 0;
-  current_class = package_name = NULL;
+  extern int flag_complexity;
+  if (flag_complexity)
+    fprintf (out, "%s %d\n", input_filename, complexity);
 }
 
+/* Reset global status used by the report functions.  */
+
 void
-yyerror (msg)
-     char *msg;
+reset_report (void)
 {
+  previous_output = 0;
+  package_name = NULL;
+  current_class_context = NULL;
+  complexity = 0;
 }
 
-char *
-xstrdup (s)
-     const char *s;
+void
+yyerror (const char *msg ATTRIBUTE_UNUSED)
 {
-  char *ret;
-
-  ret = xmalloc (strlen (s) + 1);
-  strcpy (ret, s);
-  return ret;
+  fprintf (stderr, "%s: %d: %s\n", input_filename, input_line, msg);
+  exit (1);
 }