2004-12-21 Anirban Bhattacharjee <banirban@novell.com>
[mono.git] / mcs / mbas / mb-parser.jay
index 8463b685797863637342a9f23ce8bf603fd2871b..2d7d5fd0c715bddc8e27a1dc59a3f68706cf575d 100644 (file)
@@ -2,12 +2,14 @@
 //
 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
 //
-// Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
-//                Anirban Bhattacharjee (banirban@novell.com)
+// Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+//         Anirban Bhattacharjee (banirban@novell.com)
+//          Jambunathan K (kjambunathan@novell.com)
 //
 // Licensed under the terms of the GNU GPL
 //
-// Copyright (C) 2001 A Rafael D Teixeira
+// Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
+// Copyright (C) 2003, 2004 Novell
 //
 //
 
@@ -40,6 +42,7 @@ namespace Mono.MonoBASIC
        {
        
 
+
                /// <summary>
                ///   Current block is used to add statements as we find
                ///   them.  
@@ -258,7 +261,7 @@ namespace Mono.MonoBASIC
                        // are not broken.
 
                        public void HandleToken(IfElseStateMachine.Token tok)
-                       {
+                       {       
                                err = (int) errTable[(int)state, (int)tok];
 
                                if(err != 0)
@@ -364,6 +367,13 @@ namespace Mono.MonoBASIC
                                }
                        }
                }
+
+               bool allow_global_attribs = true;
+
+               bool expecting_global_attribs = false;
+               bool expecting_local_attribs = false;
+
+               bool local_attrib_section_added = false;
 %}
 
 %token EOF
@@ -565,13 +575,6 @@ namespace Mono.MonoBASIC
 %token OP_NE                  "<>"
 %token OP_XOR                 "xor"
 //%token OP_MODULUS             //"mod"
-%token OP_MULT_ASSIGN         "*="
-%token OP_DIV_ASSIGN          "/="
-%token OP_IDIV_ASSIGN         "\\="
-%token OP_ADD_ASSIGN          "+="
-%token OP_SUB_ASSIGN          "-="
-%token OP_CONCAT_ASSIGN       "&="
-%token OP_EXP_ASSIGN          "^="
 
 /* VB.NET 2003 new bit-shift operators */
 %token OP_SHIFT_LEFT             "<<"
@@ -623,15 +626,21 @@ logical_end_of_line
 
 compilation_unit
        : logical_end_of_line
+         opt_option_directives
+         opt_imports_directives 
+         declarations 
+         EOF
+         {
+               $$=$4;
+         }
+       |logical_end_of_line
          opt_option_directives
          opt_imports_directives 
          opt_attributes
-         opt_declarations 
          EOF
          {
-               $$=$5;
+               /* ????? */ ;
          }
-       
        ;
          
 opt_option_directives
@@ -711,7 +720,7 @@ option_compare_directive
 opt_declarations
        : /* empty */
        | declarations
-       ;
+       ;               
 
 declarations
        : declaration
@@ -719,14 +728,25 @@ declarations
        ;
        
 declaration
-       : namespace_declaration
-       | type_declaration
+       : declaration_qualifiers
+         {
+               // FIXME: Need to check declaration qualifiers for multi-file compilation
+               // FIXME: Qualifiers cannot be applied to namespaces
+               allow_global_attribs = false;
+         }
+         namespace_declaration
+       |declaration_qualifiers
+         {
+                 // FIXME: Need to check declaration qualifiers for multi-file compilation
+                 allow_global_attribs = false;
+         }
+         type_spec_declaration
          {
                string name = "";
                int mod_flags;
 
-               if ($1 is Class || $1 is Struct || $1 is Module ){
-                       TypeContainer c = (TypeContainer) $1;
+               if ($3 is Class || $3 is Struct || $3 is Module ){
+                       TypeContainer c = (TypeContainer) $3;
                        mod_flags = c.ModFlags;
                        name = c.Name;
                } else
@@ -809,77 +829,183 @@ opt_params
        | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS    { $$ = $2; }
        ;
 
-global_attribute_list
-       : global_attribute
-       | global_attribute_list COMMA global_attribute
-       ;
+opt_attributes
+       : /* empty */
+       | attribute_sections    
+         { 
+               $$ = $1; 
+               local_attrib_section_added = false;
+         }
+       ;
 
-global_attribute
-       : attribute_modifier COLON attribute
+attribute_sections
+       :  attribute_section    
+         { 
+               $$ = $1;
+               if ($1 == null) {
+                       expecting_local_attribs = false;
+                       expecting_global_attribs = false;
+                       break;
+               }
+               
+               if (expecting_local_attribs) {
+                       local_attrib_section_added = true;
+                       allow_global_attribs = false;
 
-attribute_modifier
-       : ASSEMBLY 
-       | MODULE
-       | identifier 
-          { 
-               Report.Error (658, lexer.Location, "`" + (string)$1 + "' is an invalid attribute target");
+                       $$ = new Attributes ((ArrayList) $1);
+               }       
+
+               if (expecting_global_attribs) {
+                       $$ = null;
+                       CodeGen.AddGlobalAttributes ((ArrayList) $1);
+               }
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
+         }
+       | attribute_sections  
+          {
+               $$ = lexer.Location;
           }
-       ;
+          attribute_section    
+         {
+               $$ = $1;
+               if ($3 != null) {
+                       ArrayList attrs = (ArrayList) $3;
+
+                       if (expecting_local_attribs) {
+                               if (local_attrib_section_added) {
+                                       expecting_local_attribs = false;
+                                       expecting_global_attribs = false;
+                                       Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
+                                       break;
+                               }
 
-opt_attributes
-       : /* empty */
-       | attributes    { $$ = $1; }
-       ;
+                               if ($1 == null)
+                                       $$ = new Attributes (attrs);
+                               else 
+                                       ((Attributes) $1).Add (attrs);
 
-attr_begin
-       : OP_LT
-       ;
+                               local_attrib_section_added = true;
+                               allow_global_attribs = false;
+                       }
 
-attr_end
-       : OP_GT
+                       if (expecting_global_attribs) {
+                               $$ = null;
+                               CodeGen.AddGlobalAttributes ((ArrayList) $3);
+                       }
+               }       
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
+         }
        ;
 
-attributes
-       : attr_begin attribute_list attr_end
+attribute_section
+       : OP_LT attribute_list OP_GT opt_end_of_stmt
          {
-               AttributeSection sect = new AttributeSection (null, (ArrayList) $2);
-               $$ = new Attributes (sect, lexer.Location);
+               $$ = null;
+               if ($2 != null) {
+                       if (expecting_global_attribs && !(bool) $4) {
+                               Report.Error (30205, lexer.Location, "End of statement expected");
+                               break;
+                       }
+                       
+                       if (expecting_local_attribs)  {
+                               if ((bool) $4) {
+                                       Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
+                                       break;
+                               }
+                       }
+
+                       $$ = $2;
+               }
          }
-       | attr_begin global_attribute_list attr_end logical_end_of_line
        ; 
 
+opt_end_of_stmt
+       : /* empty */ { $$ = false; }
+       | end_of_stmt   { $$ = true; }
+       ;
+
 attribute_list
        : attribute 
          {
-               ArrayList attrs = new ArrayList ();
-               attrs.Add ($1);
-
+               ArrayList attrs = null;
+               if ($1 != null) {
+                       attrs = new ArrayList ();
+                       attrs.Add ($1);
+               }
                $$ = attrs;
-              
          }     
        | attribute_list COMMA attribute
          {
-               ArrayList attrs = (ArrayList) $1;
-               attrs.Add ($3);
+               ArrayList attrs = null;
+               
+               if ($3 != null) {
+                       attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
+                       attrs.Add ($3);
+               }
 
                $$ = attrs;
          }     
        ;
 
 attribute 
-       : attribute_name
-         {
+       :  namespace_or_type_name
+          {
                $$ = lexer.Location;
-         }
-         opt_attribute_arguments
-         {
-               $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
-         }       
+          }
+          opt_attribute_arguments
+          {
+               $$ = null;
+               
+               if (expecting_global_attribs)
+                       Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
+               else {
+                       expecting_local_attribs = true;
+                       $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+               }
+          }
+         | attribute_target_specifier 
+           {
+               $$ = lexer.Location;
+           }
+           COLON 
+           namespace_or_type_name
+          {
+                 $$ = lexer.Location;
+          }
+          opt_attribute_arguments
+          {
+               $$ = null;
+
+               string attribute_target = (string) $1;
+               if (attribute_target != "assembly" && attribute_target != "module") {
+                       Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
+                       break;
+               }
+               if (!allow_global_attribs) {
+                       Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
+                       break;
+               }
+
+               if (expecting_local_attribs) {
+                       Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
+                       break;
+               }                       
+
+               expecting_global_attribs = true;
+               $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
+           }   
        ;
 
-attribute_name
-       : namespace_or_type_name 
+attribute_target_specifier
+       :  ASSEMBLY     { $$ = "assembly"; }
+       | MODULE        { $$ = "module"; }
+       | namespace_or_type_name
        ;
+       
                        
 opt_attribute_arguments
        : /* empty */   { $$ = null; }
@@ -975,14 +1101,13 @@ namespace_declaration
          }
        ;
 
-type_declaration
+declaration_qualifiers
        : opt_attributes 
          opt_modifiers 
          { 
                current_attributes = (Attributes) $1; 
                current_modifiers = (int) $2; 
          }       
-         type_spec_declaration
        ;
 
 type_spec_declaration
@@ -1239,7 +1364,7 @@ must_override_declaration
        ;
        
 must_override_sub_declaration
-       : MUSTOVERRIDE SUB identifier opt_params logical_end_of_line
+       : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
          {     
                if (current_container is Module)
                        Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
@@ -1250,7 +1375,7 @@ must_override_sub_declaration
                current_modifiers |= Modifiers.ABSTRACT;
                                        
                Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
-                                           (Parameters) $4, null, null, lexer.Location);
+                                           (Parameters) $4, null, (ArrayList) $5, lexer.Location);
                                            
                if (!(current_container is Class))
                        Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");               
@@ -1261,7 +1386,7 @@ must_override_sub_declaration
 
        
 must_override_func_declaration
-       : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
+       : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
          {     
                Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.  
                        system_object_expr : (Expression) $4 ) : (Expression) $6;
@@ -1275,7 +1400,7 @@ must_override_func_declaration
                current_modifiers |= Modifiers.ABSTRACT;
                                                        
                Method method = new Method ((Expression) ftype, (int) current_modifiers, 
-                                               (string) $3,(Parameters) $5, null, null
+                                               (string) $3,(Parameters) $5, null, (ArrayList) $7
                                                lexer.Location);
                                            
                if (!(current_container is Class))
@@ -1310,7 +1435,11 @@ sub_declaration
                if ($4 != null) { 
                        // we have an event handler to take care of 
 
-                       string evt_def = ((MemberAccess)$6).ToString();
+                 Expression handles_exp = (Expression) $4;
+                 Location loc = lexer.Location;
+                 
+                 if (handles_exp is MemberAccess) {
+                       string evt_def = ((MemberAccess)$4).ToString();
                        int pos = evt_def.LastIndexOf (".");
                        string evt_target = evt_def.Substring (0, pos);
                        bool found = false;
@@ -1318,11 +1447,11 @@ sub_declaration
                        if (current_container.Properties != null) {
                                foreach (Property p in current_container.Properties) {
                                        if (p.Name == evt_target) {
-                                               Location loc = lexer.Location;
+                                               
 
                                                Statement addhnd = (Statement) new AddHandler ((Expression) $4, 
                                                                                        DecomposeQI((string) $2, loc), 
-                                                                                       DecomposeQI(evt_target, loc), loc);
+                                                                                       loc);
 
                                                current_container.AddEventHandler (addhnd);
                                                found = true;
@@ -1330,11 +1459,20 @@ sub_declaration
                                        }
                                }               
                        }
-
+                       
                        if (!found){
                                Report.Error(30506, lexer.Location,
                                                evt_target + " is not declared with WithEvents");
                        }
+                 } else if (handles_exp is BaseAccess) {
+                               string evt_id = ((BaseAccess) $4).member;
+                               Statement addhnd = (Statement) new AddHandler ((Expression) $4, 
+                                                                                       DecomposeQI((string) $2, loc), 
+                                                                                       loc);   
+                                                                                       
+                               current_container.AddEventHandler (addhnd);
+                 }
+                 
                }       
          }       
        ;
@@ -1446,7 +1584,7 @@ event_declaration
                VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
 
                Event e = new Event ((Expression) $4, var.identifier, 
-                                    null, current_modifiers, null, null, 
+                                    null, current_modifiers, 
                                     current_attributes, (ArrayList) $5,
                                     lexer.Location);
 
@@ -1483,7 +1621,7 @@ event_declaration
                
                Event e = new Event (DecomposeQI (delName, lexer.Location),
                                         (string) $2, 
-                                    null, current_modifiers, null, null, 
+                                    null, current_modifiers, 
                                     current_attributes, (ArrayList) $4, 
                                     lexer.Location);
 
@@ -1493,13 +1631,17 @@ event_declaration
        
 enum_declaration
        : ENUM identifier opt_type_spec logical_end_of_line
-         opt_enum_member_declarations // FIXME: BC30280: Enum must contain atleast one member
+         opt_enum_member_declarations 
          { 
                Location enum_location = lexer.Location;
                string full_name = MakeName ((string) $2);
                Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
                ArrayList enum_members = (ArrayList) $5;
                
+               if (enum_members.Count == 0)
+                       Report.Error (30280, enum_location,
+                               "Enum can not have empty member list");
+               
                // Module members are static by default, but enums *can't* be declared static
                // so we must fix it if mbas was the one actually responsible for this
                // instead of triggering an error.
@@ -1599,29 +1741,23 @@ interface_declaration
 
 opt_interface_base
        : /* empty */                     { $$ = null; }
-       | interface_base
-       ;
-
-interface_base
-       : INHERITS interface_type_list    { $$ = $2; }
+       | interface_bases
        ;
 
-interface_type_list
-       : interface_type
+interface_bases
+       : interface_base
+       | interface_bases interface_base
          {
-               ArrayList interfaces = new ArrayList ();
-
-               interfaces.Add ($1);
-               $$ = interfaces;
-         }
-       | interface_type_list COMMA interface_type
-         {
-               ArrayList interfaces = (ArrayList) $1;
-               interfaces.Add ($3);
-               $$ = interfaces;
+               ArrayList bases = (ArrayList) $1;
+               bases.AddRange ((ArrayList) $2);
+               $$ = bases;
          }
        ;
 
+interface_base
+       : INHERITS type_list logical_end_of_line  { $$ = $2; }
+       ;
+
 interface_body
        : opt_interface_member_declarations
        ;
@@ -1681,7 +1817,7 @@ interface_method_declaration
        ;
 
 interface_property_declaration
-       : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line
+       : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
          {
                Expression ftype = ($5 == null) ? (($3 == null) ? 
                                TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
@@ -1731,7 +1867,7 @@ interface_event_declaration
                VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
 
                Event e = new Event ((Expression) $4, var.identifier, 
-                                    null, current_modifiers, null, null, 
+                                    null, current_modifiers, 
                                     current_attributes, lexer.Location);
 
                CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
@@ -1752,7 +1888,7 @@ interface_event_declaration
          
                Event e = new Event (DecomposeQI (delName, lexer.Location),
                                         (string) $2, 
-                                    null, current_modifiers, null, null, 
+                                    null, current_modifiers, 
                                     current_attributes, lexer.Location);
 
                CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
@@ -1765,7 +1901,7 @@ property_declaration
        ;
        
 abstract_propery_declaration
-       : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line
+       : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
          {     
                Expression ftype = ($6 == null) ? (($4 == null) ? 
                                TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
@@ -1822,8 +1958,18 @@ abstract_propery_declaration
        
        
  non_abstract_propery_declaration
-         : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec opt_implement_clause logical_end_of_line
-         {
+         : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
+         {
+               if ((current_modifiers & Modifiers.DEFAULT) > 0) {
+                       if (current_container.DefaultPropName != null)
+                               Report.Error (30359, 
+                                               lexer.Location,
+                                               "Type '" + current_container.Name +
+                                               "' cannot have more than one 'Default Property' ");
+                                               
+                       current_container.DefaultPropName = (string) $2;
+               }               
+         
                get_implicit_value_parameter_type  = 
                        ($5 == null) ? (($3 == null) ? 
                                TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
@@ -2004,7 +2150,7 @@ opt_set_parameter
                set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
                set_implicit_value_parameter_name = "Value";
        }       
-       | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_spec CLOSE_PARENS
+       | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
        {
                Parameter.Modifier pm = (Parameter.Modifier)$2;
                if ((pm | Parameter.Modifier.VAL) != 0)
@@ -2014,11 +2160,11 @@ opt_set_parameter
                                
                set_implicit_value_parameter_type = (Expression) $4;
                
-               if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
+               if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
                        Report.Error (31064, 
                                lexer.Location, 
                                "Set value parameter type can not be different from property type");
-               
+                               
                if ($2 != null)
                        set_implicit_value_parameter_name = (string) $3;
                else
@@ -2125,7 +2271,7 @@ delegate_declaration
        | DELEGATE FUNCTION       
          identifier OPEN_PARENS 
          opt_formal_parameter_list
-         CLOSE_PARENS opt_type_spec logical_end_of_line
+         CLOSE_PARENS opt_type_with_ranks logical_end_of_line
          {
                Location l = lexer.Location;
                
@@ -2148,18 +2294,29 @@ delegate_declaration
        ;
        
 opt_evt_handler
-       : /* empty */
-         {     $$ = null; }
-       | HANDLES qualified_identifier
+       : /* empty */           {       $$ = null; }
+         | HANDLES evt_handler         {       $$ = $2; }
+    ;
+
+evt_handler
+       : qualified_identifier
+         {
+               $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);     
+         }
+       | base_access
+         {
+               $$ = $1;
+         }
+       | ME DOT qualified_identifier
          {
-               $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);     
+               $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);     
          }
-       | HANDLES MYBASE DOT qualified_identifier
+       /*| MYBASE DOT qualified_identifier
          {
                // FIXME: this is blatantly wrong and crash-prone
                $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
-         }
-       ;       
+         }*/
+       ;
 
 constructor_declaration
        : SUB NEW opt_params logical_end_of_line
@@ -2200,38 +2357,40 @@ opt_formal_parameter_list
        ;
        
 formal_parameter_list
-       : fixed_parameters              
+       : parameters            
          { 
                ArrayList pars_list = (ArrayList) $1;
-
-               Parameter [] pars = new Parameter [pars_list.Count];
-               pars_list.CopyTo (pars);
-               $$ = new Parameters (pars, null, lexer.Location); 
+               Parameter [] pars = null; 
+               Parameter array_parameter = null;
+               int non_array_count = pars_list.Count;
+               if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
+                       array_parameter = (Parameter) pars_list [pars_list.Count - 1];
+                       non_array_count = pars_list.Count - 1;
+               }
+               foreach (Parameter par in pars_list)
+                       if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
+                               Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
+                               non_array_count = 0; 
+                               array_parameter = null;
+                               break;
+                       }
+               if (non_array_count > 0) {
+                       pars = new Parameter [non_array_count];
+                       pars_list.CopyTo (0, pars, 0, non_array_count);
+               }
+               $$ = new Parameters (pars, array_parameter, lexer.Location); 
          } 
-       | fixed_parameters COMMA parameter_array
-         {
-               ArrayList pars_list = (ArrayList) $1;
-
-               Parameter [] pars = new Parameter [pars_list.Count];
-               pars_list.CopyTo (pars);
-
-               $$ = new Parameters (pars, (Parameter) $3, lexer.Location); 
-         }
-       | parameter_array 
-         {
-               $$ = new Parameters (null, (Parameter) $1, lexer.Location);
-         }
        ;
 
-fixed_parameters
-       : fixed_parameter       
+parameters
+       : parameter     
          {
                ArrayList pars = new ArrayList ();
 
                pars.Add ($1);
                $$ = pars;
          }
-       | fixed_parameters COMMA fixed_parameter
+       | parameters COMMA parameter
          {
                ArrayList pars = (ArrayList) $1;
 
@@ -2240,58 +2399,47 @@ fixed_parameters
          }
        ;
 
-fixed_parameter
+parameter
        : opt_attributes
          opt_parameter_modifier
-         identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
+         identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
          {
                Parameter.Modifier pm = (Parameter.Modifier)$2;
                bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
                Expression ptype;
                
                if (opt_parm && ($7 == null))
-                       Report.Error (30812, "Optional parameters must have a default value");
+                       Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
+
+               if (!opt_parm && ($7 != null))
+                       Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
+
+               if ((pm & Parameter.Modifier.PARAMS) != 0) {
+                       if ((pm & ~Parameter.Modifier.PARAMS) != 0)
+                               Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
+               }
                
-               if (opt_parm) {
-                       if ((pm & Parameter.Modifier.REF) !=0)
-                               pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
-                       else
-                               pm = Parameter.Modifier.NONE;   //FIXME: should take into account BYREF
-               }       
+               if ((pm & Parameter.Modifier.REF) !=0)
+                       pm |= Parameter.Modifier.ISBYREF;
                
                if ($4 != null && $6 != null && $4 != $6)
-                       Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
+                       Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
 
                ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
                if ($5 != null) {
-                       string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
-                       ptype = DecomposeQI (t, lexer.Location);
-               }                       
+                       string t = ptype.ToString ();
+                       if (t.IndexOf('[') >= 0)
+                               Report.Error (31087, lexer.Location, "Array types specified in too many places");
+                       else    
+                               ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
+               }
+               if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
+                       Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
                $$ = new Parameter (ptype, (string) $3, pm,
                                        (Attributes) $1, (Expression) $7, opt_parm);
          }
        ;
        
-parameter_array
-       : PARAM_ARRAY identifier opt_parens AS type 
-         { 
-               string s_patype = ((Expression) $5).ToString();
-               if ((bool) $3)
-                       s_patype += "[]";
-                       
-               Expression patype = DecomposeQI (s_patype, Location.Null);
-               $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
-               // note  ("type must be a single-dimension array type"); 
-         }
-       ;
-               
-opt_parens
-       : /* empty */
-         {     $$ = false;     }
-       | OPEN_PARENS CLOSE_PARENS
-         {     $$ = true;      }
-       ;
-       
 opt_parameter_modifier
        : /* empty */           { $$ = Parameter.Modifier.VAL;  }
        | parameter_modifiers   { $$ = $1;                      }
@@ -2306,6 +2454,7 @@ parameter_modifier
        : BYREF                 { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
        | BYVAL                 { $$ = Parameter.Modifier.VAL; }
        | OPTIONAL              { $$ = Parameter.Modifier.OPTIONAL; } 
+       | PARAM_ARRAY           { $$ = Parameter.Modifier.PARAMS; } 
        ;       
 
 opt_statement_list
@@ -2318,8 +2467,8 @@ statement_list
        | statement_list end_of_stmt statement
        ;
        
-statement 
-           declaration_statement
+statement 
+         : declaration_statement
            {
                  if ($1 != null && (Block) $1 != current_block){
                        current_block.AddStatement ((Statement) $1);
@@ -2333,13 +2482,13 @@ statement :
                  current_block.AddStatement ((Statement) $1);
            } 
          | labeled_statement 
-         | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
+         | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
            {
-                 AddHandler ((Expression) $2, (string) $5);
+                       AddHandler ((Expression) $2, (Expression) $5);
            }
-         | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
+         | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF evt_handler
                {
-                 RemoveHandler ((Expression) $2, (string) $5);
+                 RemoveHandler ((Expression) $2, (Expression) $5);
            }
          | RAISEEVENT identifier opt_raise_event_args  //OPEN_PARENS opt_argument_list CLOSE_PARENS
            {
@@ -2566,43 +2715,77 @@ iteration_statement
        ;
 
 foreach_statement
-       : FOR EACH identifier IN 
+       : FOR EACH identifier opt_type_spec IN 
          {
                oob_stack.Push (lexer.Location);
          }       
          expression end_of_stmt
          {
-               
-               start_block();
-               Block foreach_block = current_block;
                Location l = lexer.Location;            
                LocalVariableReference v = null;
                VariableInfo vi;
 
-               vi = foreach_block.GetVariableInfo ((string) $3);
-               if (vi != null) {
-                       // Get a reference to this variable.
-                       v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
+               if ($4 != null) 
+               {
+                       start_block();
+                       VariableDeclaration decl = new VariableDeclaration ((string) $3, 
+                                       (Expression) $4, null, lexer.Location, null);
+                       
+                       vi = current_block.AddVariable (
+                               (Expression) $4, decl.identifier, current_local_parameters, decl.Location);
+
+                       Expression expr;
+                       if (decl.expression_or_array_initializer is Expression)
+                               expr = (Expression) decl.expression_or_array_initializer;
+                       else if (decl.expression_or_array_initializer == null) 
+                               expr = null;
+                       else 
+                       {
+                               ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+                               expr = new ArrayCreation ((Expression) $4, "", init, decl.Location);
+                       }
+               
+                       v = new LocalVariableReference (current_block, decl.identifier, l);
+
+                       if (expr != null) 
+                       {
+                               Assign a = new Assign (v, expr, decl.Location);
+                               current_block.AddStatement (new StatementExpression (a, lexer.Location));
+                       }
                }
                else
-                       Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
-       
+               {
+                       vi = current_block.GetVariableInfo ((string) $3);
+
+                       if (vi != null) {
+                               // Get a reference to this variable.
+                               v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
+                       }
+                       else
+                               Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
+               }
+               
                oob_stack.Push (v);
+               start_block();  
          }       
          opt_statement_list
          NEXT opt_identifier
          {
-               Block foreach_block = current_block;
                LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
-               Block prev_block = end_block();
+               Block foreach_block = end_block();
                Location l = (Location) oob_stack.Pop ();
 
                Foreach f = null;
-               if (v != null) {
-                       f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
-               }
+               if (v != null)
+                       f = new Foreach (null, v, (Expression) $7, foreach_block, l);
                
-               $$ = f;
+               if ($4 != null)
+               {
+                       current_block.AddStatement (f);
+                       $$ = end_block ();
+               }
+               else
+                       $$ = f;
          }       
        ;
 
@@ -2749,8 +2932,13 @@ opt_identifier
        | identifier
        ;
 
+opt_when
+       : /* empty */   {  $$ = null;  }
+       | WHEN boolean_expression { $$ = $2; }
+       ;
+       
 catch_clause 
-       : CATCH opt_catch_args end_of_stmt
+       : CATCH opt_catch_args opt_when end_of_stmt
        {
                Expression type = null;
                string id = null;
@@ -2766,14 +2954,12 @@ catch_clause
 
                                one.Add (new VariableDeclaration (id, type, loc));
 
-
                                $1 = current_block;
                                current_block = new Block (current_block);
                                Block b = declare_local_variables (type, one, loc);
                                current_block = b;
                        }
                }
-       
        } 
        opt_statement_list {
                Expression type = null;
@@ -2793,10 +2979,9 @@ catch_clause
                                        current_block = current_block.Parent;
                        }
                }
-
-               $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
+               $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, lexer.Location);
        }
-        ;
+    ;
 
 opt_catch_args
        : /* empty */ {  $$ = null; }
@@ -2873,29 +3058,48 @@ while_statement
        }
        ;
        
-               
 for_statement
-       : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
+       : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
          {
-               start_block();
+               if ($3 != null)
+               {
+                       start_block();
+                       ArrayList VarDeclaration = new ArrayList ();
+                       VarDeclaration.Add (new VariableDeclaration ((string) $2, 
+                               (Expression) $3, null, lexer.Location, null));
+
+                       DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
+                       Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
+                       current_block = b;
+               }
+               oob_stack.Push (lexer.Location);                
+               start_block();
          }
          opt_statement_list
          NEXT opt_identifier 
          {
-               Block statement = end_block();
-               Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
-               
-               Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
-               Expression test_expr =  new Binary (Binary.Operator.LessThanOrEqual,
-                                               for_var, (Expression) $6, lexer.Location);
-               Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
-                                for_var, (Expression) $7, lexer.Location), lexer.Location);
-                                
-               Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);                     
-               Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
-               
-               $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);            
-         }       
+                       Block inner_statement = end_block();
+                       Location l = (Location) oob_stack.Pop ();
+                       Expression for_var = (Expression) DecomposeQI ((string)$2, l);
+                       
+            Expression assign_expr = new Assign (for_var, (Expression) $5, l);
+            Expression test_expr =  new Binary (Binary.Operator.LessThanOrEqual,
+                                                            for_var, (Expression) $7, l);
+            Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
+                                             for_var, (Expression) $8, l), l);
+
+            Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
+            Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
+
+            For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
+                       if ($3 != null)
+                       {
+                               current_block.AddStatement (f);
+                               $$ = end_block();
+                       }
+                       else
+                               $$ = f;
+         }
        ;
 
 opt_step
@@ -2913,11 +3117,28 @@ if_statement
          {
                $$ = $3;
          }
-       | if_statement_open THEN pre_embedded_statement
+       | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
          {
-               Location l = (Location) oob_stack.Pop ();
-               tmp_expr = (Expression)expr_stack.Pop(); 
-               $$ = new If ((Expression) tmp_expr, end_block(), l);
+               if ($4 == null)
+               {
+                       Location l = (Location) oob_stack.Pop ();
+                       tmp_expr = (Expression)expr_stack.Pop(); 
+                       $$ = new If ((Expression) tmp_expr, end_block(), l);
+               }
+               else
+               {
+                       Location l = (Location) oob_stack.Pop ();
+                       tmp_expr = (Expression)expr_stack.Pop(); 
+                       tmp_block = (Block) tmp_blocks.Pop ();
+                       $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
+               }
+         }
+       | if_statement_open THEN else_pre_embedded_statement
+         {
+                       Location l = (Location) oob_stack.Pop ();
+                       tmp_expr = (Expression)expr_stack.Pop(); 
+                       tmp_block = (Block) tmp_blocks.Pop ();
+                       $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l);
          }
        ;
 
@@ -2929,6 +3150,30 @@ pre_embedded_statement
                current_block.AddStatement ((Statement) $1);
          } 
        ;       
+
+opt_else_pre_embedded_statement
+       : /* empty */
+       | else_pre_embedded_statement
+       ;
+       
+else_pre_embedded_statement    
+       : ELSE
+         {
+               Block bl = end_block(); 
+        tmp_blocks.Push(bl); 
+        
+               start_block();
+         }
+       | ELSE embedded_statement 
+         {
+               Block bl = end_block(); 
+        tmp_blocks.Push(bl); 
+        
+               start_block();
+               Statement s = (Statement) $2;
+               current_block.AddStatement ((Statement) $2);
+         } 
+       ;       
        
 if_statement_open
        : IF boolean_expression 
@@ -2951,7 +3196,7 @@ if_statement_rest
          END IF
          { 
                Location l = (Location) oob_stack.Pop ();
-                Expression expr = (Expression)expr_stack.Pop(); 
+        Expression expr = (Expression)expr_stack.Pop(); 
                $$ = new If ((Expression) expr, (Statement) end_block(), l);
          }       
        | end_of_stmt
@@ -2959,7 +3204,7 @@ if_statement_rest
          ELSE end_of_stmt 
          { 
                Block bl = end_block(); 
-               tmp_blocks.Push(bl); 
+        tmp_blocks.Push(bl); 
                start_block();
          }
          opt_statement_list
@@ -3100,7 +3345,7 @@ case_section
                topmost.statements.Add (new Break (lexer.Location));
                $$ = new SwitchSection ((ArrayList) $2, topmost);
          }
-         | CASE ELSE ends
+       | CASE ELSE ends
            /* FIXME: we should somehow flag an error 
               (BC30321 'Case' cannot follow a 'Case Else' 
               in the same 'Select' statement.) 
@@ -3195,7 +3440,7 @@ object_creation_expression
        ;
        
 array_creation_expression
-       : object_creation_expression array_initializer
+       : object_creation_expression opt_rank_specifiers array_initializer
          {
                New n = (New) $1;
                ArrayList dims = new ArrayList();
@@ -3208,7 +3453,10 @@ array_creation_expression
                        
                Expression atype = n.RequestedType;
 
-               ArrayList init = (ArrayList) $2;
+               if ($2 != null)
+                       atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
+
+               ArrayList init = (ArrayList) $3;
                if (init.Count == 0)
                        init = null;
        
@@ -3219,7 +3467,7 @@ array_creation_expression
                else
                {
                        string rank = VariableDeclaration.BuildRank (dims);
-                       $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location); 
+                       $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location); 
                }
                //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
          }
@@ -3377,16 +3625,7 @@ variable_declarator
                                        Report.Error (30638, "Array bounds cannot appear in type specifiers."); 
                                
                                current_rank_specifiers = new ArrayList ();
-                               current_rank_specifiers.Add (args);
-                               
-                               /*string s_vartype = vartype.ToString();                                
-                               s_vartype += "[";
-                               if (args != null)
-                                       for (int x = 0; x < args.Count; x++)
-                                               s_vartype += ",";
-                                       
-                               s_vartype += "]";       
-                               vartype = DecomposeQI(s_vartype, Location.Null);        */
+                               current_rank_specifiers.Add (args);                             
                        }
                        else
                                vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
@@ -3426,7 +3665,7 @@ variable_declarator
                                        VariableDeclaration.VBFixIndexLists (ref a_dims);
                                        varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
                                }
-                               vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
+                               vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
                        }
 
                        if (vartype is New) {
@@ -3483,19 +3722,15 @@ opt_type_with_ranks
        : opt_type_spec 
        | AS type rank_specifiers
          {
-               $$ = TypeManager.system_object_expr; 
+               $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
          }
        ;
        
 opt_type_decl
-       : opt_type_spec
+       : opt_type_with_ranks
          {
                $$ = $1;
          }
-       | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
-         {
-               $$ = new Pair ($2, $4);
-         }
        | AS NEW type
          {
                New n = new New ((Expression)$3, null, lexer.Location);
@@ -3598,59 +3833,37 @@ rank_specifiers
         ;              
        
 rank_specifier
-       : OPEN_PARENS opt_dim_separators CLOSE_PARENS
+       : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
          {
                $$ = $2;
          }
        ;
                
-opt_dim_separators
+opt_dim_specifiers
        : /* empty */
-         {
-               ArrayList ds = new ArrayList();
-               ds.Add (new EmptyExpression());
-               $$ = ds;                
-         }
-       | dim_separators
-         {
-               ArrayList ds = (ArrayList) $1;
-               ds.Add (new EmptyExpression());
-               $$ = ds;        
-         }     
-       | dim_specifiers
-         {
-               $$ = $1;
-         }       
-       ;
-
-dim_separators
-       : COMMA
          {
                ArrayList ds = new ArrayList();
                ds.Add (new EmptyExpression());
                $$ = ds;
-         }
-       | dim_separators COMMA
-         {
-               ArrayList ds = (ArrayList) $1;
-               ds.Add (new EmptyExpression());
-               $$ = ds;                
-         }
-       ;
-
-dim_specifiers
-       : expression
+         }     
+       | expression
          {
                ArrayList ds = new ArrayList();
                ds.Add ((Expression) $1);
                $$ = ds;
          }     
-       | dim_specifiers COMMA expression
+       | opt_dim_specifiers COMMA expression
          {
                ArrayList ds = (ArrayList) $1;
                ds.Add ((Expression) $3);
                $$ = ds;                
          }     
+       | opt_dim_specifiers COMMA 
+         {
+               ArrayList ds = (ArrayList) $1;
+               ds.Add (new EmptyExpression());
+               $$ = ds;                
+         }     
        ;
        
 primary_expression
@@ -3666,11 +3879,7 @@ primary_expression
                string name = (string) $1;
                $$ = DecomposeQI (name, lexer.Location);
          }
-       //FIXME: address_of_expression is apparently missing here
        | get_type_expression
-         {
-               // TODO
-         }
        | member_access
        | invocation_expression
        //| element_access
@@ -3762,7 +3971,7 @@ member_access
                }
          }
        ;
-
+       
 predefined_type
        : builtin_types
        ;
@@ -3776,7 +3985,16 @@ invocation_expression
                }
                $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
 //             Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
-         } 
+         }
+       | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
+         {
+               if ($2 == null) {
+                       Location l = lexer.Location;
+                       Report.Error (1, l, "THIS IS CRAZY");
+               }
+               $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
+//             Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
+         }
        ;
        
 base_access
@@ -3908,7 +4126,7 @@ cast_operator
 get_type_expression
        : GETTYPE OPEN_PARENS type CLOSE_PARENS
          {
-               //TODO
+               $$ = new TypeOf ((Expression) $3, lexer.Location);
          }
        ;
        
@@ -4038,11 +4256,14 @@ relational_expression
          }
        | relational_expression IS shift_expression
          {
-               //FIXME: Is this rule correctly defined ?
+               //FIXME: Should be a different op for reference equality but allows tests to use Is
+               $$ = new Binary (Binary.Operator.Equality,
+                                (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | TYPEOF shift_expression IS namespace_or_type_name
+       | TYPEOF shift_expression IS type
          {
-                 //FIXME: Is this rule correctly defined ?
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
          }
        ;
 
@@ -4097,6 +4318,63 @@ assignment_expression
          { 
                $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
          }
+       | prefixed_unary_expression STAR ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression DIV ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression PLUS ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression MINUS ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression OP_CONCAT ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               // FIXME should be strings only
+               $$ = new CompoundAssign (
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression OP_EXP ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               /* TODO: $$ = new CompoundAssign (
+                       Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
+         }
        | prefixed_unary_expression ASSIGN ADDRESSOF expression
          { 
            ArrayList args = new ArrayList();
@@ -4180,10 +4458,6 @@ floating_point_type
        | DOUBLE        { $$ = TypeManager.system_double_expr; }
        ;
 
-interface_type
-       : namespace_or_type_name
-       ;
-       
 pp_directive
        : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
          { 
@@ -4562,23 +4836,43 @@ public class VariableDeclaration {
        }
        
        public static string BuildRank (ArrayList rank)
+       {
+               bool allEmpty;
+               return BuildRank(rank, out allEmpty);
+       }
+            
+       public static string BuildRank (ArrayList rank, out bool allEmpty)
        {
                string res = "";
 
                res += "[";
-               for (int x = 0; x < (rank.Count -1 ); x++)
-                       res += ",";
+               allEmpty = true;
+               bool first = true;
+               foreach (object e in rank) {
+                       if (!(e is EmptyExpression))
+                               allEmpty = false;
+                       if (!first)
+                               res += ",";
+                       first = false;
+               }
                        
                res += "]";
                return res;
        }
                
-       public static string BuildRanks (Parser t)
+       public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
        {
                string res = "";
 
-               foreach (ArrayList rank in t.current_rank_specifiers)
-                       res += BuildRank (rank);
+               bool allEmpty = true;
+               foreach (ArrayList rank in rank_specifiers) {
+                       bool tmp;
+                       res = BuildRank (rank, out tmp) + res;
+                       if (!tmp)
+                               allEmpty = false;
+               }
+               if (!allEmpty && mustBeEmpty)
+                       Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");    
 
                return res;
        }       
@@ -4684,9 +4978,9 @@ Block end_block ()
        return (res);
 }
 
-private void AddHandler (Expression evt_definition, string handler_name)
+private void AddHandler (Expression evt_definition, Expression handler_exp)
 {
-       AddHandler (current_block, evt_definition, handler_name);
+       AddHandler (current_block, evt_definition, handler_exp);
 }
 
 void CheckAttributeTarget (string a)
@@ -4703,13 +4997,16 @@ void CheckAttributeTarget (string a)
        }
 }
 
-private void AddHandler (Block b, Expression evt_id, string handler_name)
+private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
 {
-       Location loc = lexer.Location;
-       string evt_target = evt_id.ToString();
-       evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
-       Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
-       b.AddStatement (s);
+       Expression evt_target;
+       Location loc = lexer.Location;
+       
+       Statement addhnd = (Statement) new AddHandler (evt_id, 
+                                                                                                       handles_exp, 
+                                                                                                       loc);                                                                                                   
+                                                                                                       
+       b.AddStatement (addhnd);
 }
 
 private void RaiseEvent (string evt_name, ArrayList args)
@@ -4721,13 +5018,15 @@ private void RaiseEvent (string evt_name, ArrayList args)
        current_block.AddStatement (s); 
 }
 
-private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
+private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
 {
+       Expression evt_target;
        Location loc = lexer.Location;
-       string evt_target = evt_definition.ToString();
-       evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
-       Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
-       b.AddStatement (s);
+       
+       Statement rmhnd = (Statement) new RemoveHandler (evt_definition, 
+                                                                                                       handler_exp, 
+                                                                                                       loc);
+       b.AddStatement (rmhnd);
 }
 
 // <summary>
@@ -4747,9 +5046,9 @@ string GetQualifiedIdentifier (Expression expr)
        
 }
 
-private void RemoveHandler (Expression evt_definition, string handler_name)
+private void RemoveHandler (Expression evt_definition, Expression handler_exp)
 {
-       RemoveHandler (current_block, evt_definition, handler_name);
+       RemoveHandler (current_block, evt_definition, handler_exp);
 }
 
 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
@@ -4807,6 +5106,11 @@ protected override int parse ()
        with_stack = new Stack();
        statement_stack = new Stack();  
 
+       allow_global_attribs = true;
+       expecting_global_attribs = false;
+       expecting_local_attribs = false;
+       local_attrib_section_added = false;
+
        UseExtendedSyntax = name.EndsWith(".mbs");
        OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
        OptionStrict = InitialOptionStrict || UseExtendedSyntax;
@@ -4819,7 +5123,7 @@ protected override int parse ()
        
        StringBuilder value = new StringBuilder ();
        try {
-               if (yacc_verbose_flag)
+               if (yacc_verbose_flag > 0)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
                else {
                        yyparse (lexer);
@@ -4830,7 +5134,9 @@ protected override int parse ()
                Report.Error(e.code, e.loc, e.Message);
        }
        catch (Exception e) {
-               Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.EffectiveSource + "\n" + e.ToString());
+               if (Report.Stacktrace)
+                       Console.WriteLine(e);
+               Report.Error (29999, lexer.Location, "Parsing error");
        }
 
        RootContext.VerifyImports();