Fix for build breakage on cygwin-head-mono
[mono.git] / mcs / mbas / mb-parser.jay
index c27a21a4bab710f0c15ad8edf4446c841dee6c1b..1ea514f560fa16b8317bbc5174bf2d349c057287 100644 (file)
@@ -2,16 +2,18 @@
 //
 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
 //
-// Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+// Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+//         Anirban Bhattacharjee (banirban@novell.com)
+//          Jambunathan K (kjambunathan@novell.com)
+//          Manjula GHM (mmanjula@novell.com)
+//          Sudharsan V (vsudharsan@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
 //
-// TODO:
-//     Nearly everything
 //
-
 namespace Mono.MonoBASIC
 {
        using System.Text;
@@ -41,6 +43,7 @@ namespace Mono.MonoBASIC
        {
        
 
+
                /// <summary>
                ///   Current block is used to add statements as we find
                ///   them.  
@@ -122,14 +125,30 @@ namespace Mono.MonoBASIC
                // </summary>
                Expression set_implicit_value_parameter_type;           
                
-               Location member_location;
-               
                // An out-of-band stack.
                //
                Stack oob_stack;
                
                ArrayList current_rank_specifiers;
 
+               //To handle the End of a block 
+               // We use grammer, priority, strings, and an integer called Parenta
+               //
+               // FIX ME: Need to implement some better method than this and in 
+               // some cases parser will come out without proceding further
+               // if it comes acorss error.
+
+                public string[] end_blocks = {"Nothing", "Next", "Loop", "End If", "End Sub", "End Module", "End Namespace", "End Class", "End Function", "End Structure", "End Enum", "End Interface", "End Property", "End With", "End Synclock", "End Try", "End While", "End Select", "End Set", "End Get"};
+                
+               public string[] open_blocks = {"Block", "For", "Do", "If", "Sub", "Module", "Namespace", "Class", "Function", "Structure", "Enum", "Interface", "Property", "With", "Synclock", "Try", "While", "Select", "Set", "Get","\nCompilation failed"};
+
+               public int[] error_numbers = {29999, 30092, 30091, 30087, 30429, 30622, 30623, 30460, 30430, 30621, 30184, 30252, 30431, 30093, 30674, 30383, 30090, 30088, 30632, 30630, 29999};
+
+                public int[] end_priority = {0,1,1,1,2,3,4,3,2,3,1,2,2,1,1,1,1,1,1,1,1};
+                                                                                                                             
+               int Parent = 0;
+               Location try_top;
+
                DoOptions do_type;
                //
                // Switch stack.
@@ -259,7 +278,7 @@ namespace Mono.MonoBASIC
                        // are not broken.
 
                        public void HandleToken(IfElseStateMachine.Token tok)
-                       {
+                       {       
                                err = (int) errTable[(int)state, (int)tok];
 
                                if(err != 0)
@@ -296,7 +315,6 @@ namespace Mono.MonoBASIC
                        {
                                public bool CanAcceptTokens;
                                public bool CanSelectBlock;
-
                        }
 
                        State currentState;
@@ -365,6 +383,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
@@ -415,12 +440,14 @@ namespace Mono.MonoBASIC
 %token DEFAULT 
 %token DELEGATE        
 %token DIM
+%token DIRECTCAST
 %token DO      
 %token DOUBLE  
 %token EACH    
 %token ELSE
 %token ELSEIF
 %token END
+%token ENDIF
 %token ENUM    
 %token EOL
 %token ERASE
@@ -434,7 +461,8 @@ namespace Mono.MonoBASIC
 %token FRIEND
 %token FUNCTION
 %token GET
-//%token GETTYPE
+%token GETTYPE
+%token GOSUB
 %token GOTO    
 %token HANDLES
 %token IF      
@@ -512,6 +540,7 @@ namespace Mono.MonoBASIC
 %token UNICODE
 %token UNTIL
 %token VARIANT 
+%token WEND
 %token WHEN    
 %token WHILE   
 %token WITH
@@ -543,7 +572,7 @@ namespace Mono.MonoBASIC
 %token DIV            "/"
 %token OP_EXP         "^"
 %token INTERR         "?"
-%token OP_IDIV        "\\"
+%token OP_IDIV        "\\" //FIXME: This should be "\"
 %token OP_CONCAT      "&"
 %token EXCLAMATION    "!"
 
@@ -562,13 +591,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             "<<"
@@ -614,26 +636,28 @@ end_of_stmt
        ;       
 
 logical_end_of_line
-       : EOL
+       :
+         EOL 
        | logical_end_of_line pp_directive 
        ;
 
-opt_logical_end_of_line
-       : /* empty */
-       | logical_end_of_line
-       ;
-
 compilation_unit
-       : logical_end_of_line
+       : logical_end_of_line _mark_
+         opt_option_directives
+         opt_imports_directives 
+         declarations 
+         EOF
+         {
+               $$=$4;
+         }
+       | logical_end_of_line _mark_ 
          opt_option_directives
          opt_imports_directives 
          opt_attributes
-         opt_declarations 
          EOF
          {
-               $$=$5;
+               /* ????? */ ;
          }
-       
        ;
          
 opt_option_directives
@@ -650,6 +674,14 @@ option_directive
        : option_explicit_directive
        | option_strict_directive
        | option_compare_directive
+       | OPTION _mark_ logical_end_of_line
+               {
+                Report.Error(30206 ,(Location)$2, "Option must be followed by 'Compare' or 'Explicit' or 'Strict'");
+               }
+       | OPTION _mark_ IDENTIFIER logical_end_of_line
+               {
+                Report.Error(30206 ,(Location)$2, "Option must be followed by 'Compare' or 'Explicit' or 'Strict'");
+               }
        ;
        
 on_off
@@ -679,26 +711,26 @@ text_or_binary
        ;
          
 option_explicit_directive
-       : OPTION EXPLICIT on_off logical_end_of_line
+       : OPTION EXPLICIT _mark_ on_off logical_end_of_line
          {
                if (!UseExtendedSyntax)
-                       OptionExplicit = (bool)$3;
+                       OptionExplicit = (bool)$4;
                else
                        Report.Warning (
-                               9999, lexer.Location
+                               9999, (Location)$3
                                "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
          }
        ;
          
                        
 option_strict_directive
-       : OPTION STRICT on_off logical_end_of_line
+       : OPTION STRICT _mark_ on_off logical_end_of_line
          {
                if (!UseExtendedSyntax)
-                       OptionStrict = (bool)$3;
+                       OptionStrict = (bool)$4;
                else
                        Report.Warning (
-                               9999, lexer.Location
+                               9999, (Location)$3
                                "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
          }
        ;
@@ -713,7 +745,7 @@ option_compare_directive
 opt_declarations
        : /* empty */
        | declarations
-       ;
+       ;               
 
 declarations
        : declaration
@@ -721,24 +753,41 @@ 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 _mark_ 
+         {
+                 // 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 ($4 is Class || $4 is Struct || $4 is Module ){
+                       TypeContainer c = (TypeContainer) $4;
                        mod_flags = c.ModFlags;
                        name = c.Name;
                } else
                        break;
 
-               if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+               if ((mod_flags & (Modifiers.PRIVATE)) != 0){
                        Report.Error (
-                               1527, lexer.Location
+                               31089, (Location)$2
                                "Namespace elements cannot be explicitly " +
-                               "declared private or protected in '" + name + "'");
+                               "declared private in '" + name + "'");
+                       }
+               else if ((mod_flags & (Modifiers.PROTECTED)) != 0){
+                       Report.Error (
+                               31047, (Location)$2, 
+                               "Namespace elements cannot be explicitly " +
+                               "declared protected in '" + name + "'");
                }
          }
        ;
@@ -768,9 +817,9 @@ opt_type_character
        
 
 qualified_identifier
-       : identifier
-       | qualified_identifier DOT identifier 
-         { 
+       : identifier 
+       | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
+         {
            $$ = (($1).ToString ()) + "." + ($3.ToString ()); 
          }
        ;
@@ -791,149 +840,247 @@ imports_directive
 
 imports_terms
        : imports_term
-       | imports_terms COMMA imports_terms
+       | imports_terms COMMA imports_term
        ;
        
 imports_term
-       : qualified_identifier
+       : namespace_or_type_name 
          {
                RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
          }
-       | qualified_identifier ASSIGN qualified_identifier
+       | identifier _mark_ ASSIGN namespace_or_type_name 
          {
-               RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
+               RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $4, (Location)$2);
          }
+       | identifier _mark_ ASSIGN
+         {
+               Report.Error(30203, (Location)$2, "Alias Statement no complete: Expression Expected");
+         }
+       | _mark_ /* empty */ 
+         {
+               Report.Error(30203, (Location)$1, "No namespace imported: Expression Expected");
+         }
        ;
 
 opt_params
        : /* empty */   { $$ = Parameters.EmptyReadOnlyParameters; }
        | OPEN_PARENS CLOSE_PARENS      { $$ = Parameters.EmptyReadOnlyParameters; }
-       | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS    { $$ = $2; }
+       | OPEN_PARENS _mark_ opt_formal_parameter_list CLOSE_PARENS     { $$ = $3; }
+       | OPEN_PARENS _mark_
+         {
+               Report.Error(30203,(Location)$2, "Identifier Expected"); 
+               $$ = Parameters.EmptyReadOnlyParameters;
+         }
+       | OPEN_PARENS _mark_ opt_formal_parameter_list 
+         {
+               Report.Error(30198,(Location)$2, "'(' is not having a matching ')'"); 
+               $$ = $3;
+         }
+       | _mark_ opt_formal_parameter_list CLOSE_PARENS 
+         {
+               Report.Error(30205,(Location)$1, "')' is not having a matching '('"); 
+               $$ = $2;
+         }
        ;
-       
+
 opt_attributes
-       : /* empty */
-       | attribute_sections    { $$ = $1; }
-       ;
+       : /* empty */
+       | attribute_sections    
+         { 
+               $$ = $1; 
+               local_attrib_section_added = false;
+         }
+       ;
 
 attribute_sections
-       : attribute_section
-          { 
-               AttributeSection sect = (AttributeSection) $1;
-
-               if (sect.Target == "assembly") 
-                       RootContext.AddGlobalAttributeSection (current_container, sect);
-               
-               $$ = new Attributes ((AttributeSection) $1, lexer.Location);
-               
-          }    
-          /* 
-             FIXME: we should check if extended syntax is enabled;
-                    otherwise an exception should be thrown since VB.NET 
-                    only allows one attribute section 
-          */  
-       | attribute_sections attribute_section
-         {
-               Attributes attrs = null;
-               AttributeSection sect = (AttributeSection) $2;
-
-               if (sect.Target == "assembly")
-                       RootContext.AddGlobalAttributeSection (current_container, sect);
-
-               if ($1 != null) {
-                       attrs = (Attributes) $1;
-                       attrs.AddAttributeSection (sect);
-               }
-               
-               $$ = attrs;
-         }     
-       ;
-       
-attribute_section
-       : OP_LT attribute_target_specifier attribute_list OP_GT
+       :  attribute_section    
          { 
-               string target = null;
-               
-               if ($2 != null)
-                       target = (string) $2;
+               $$ = $1;
+               if ($1 == null) {
+                       expecting_local_attribs = false;
+                       expecting_global_attribs = false;
+                       break;
+               }
                
-               $$ = new AttributeSection (target, (ArrayList) $3);
-         }     
-       | OP_LT attribute_list OP_GT
-         {
-               $$ = new AttributeSection (null, (ArrayList) $2);
-         }     
-       ; 
+               if (expecting_local_attribs) {
+                       local_attrib_section_added = true;
+                       allow_global_attribs = false;
 
-attribute_target_specifier
-       : attribute_target COLON
+                       $$ = 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;
+               $$ = $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;
+                               }
+
+                               if ($1 == null)
+                                       $$ = new Attributes (attrs);
+                               else 
+                                       ((Attributes) $1).Add (attrs);
+
+                               local_attrib_section_added = true;
+                               allow_global_attribs = false;
+                       }
+
+                       if (expecting_global_attribs) {
+                               $$ = null;
+                               CodeGen.AddGlobalAttributes ((ArrayList) $3);
+                       }
+               }       
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
          }
        ;
 
-attribute_target
-       : identifier
-         {
-               CheckAttributeTarget ((string) $1);
-               $$ = $1;
-         }
-        | EVENT  { $$ = "event"; }       
-        | RETURN { $$ = "return"; }
+attribute_section
+       : OP_LT attribute_list OP_GT opt_end_of_stmt
+         {
+               $$ = 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;
+               }
+         }
+       ; 
+
+opt_end_of_stmt
+       : /* empty */ { $$ = false; }
+       | end_of_stmt   { $$ = true; }
        ;
-       
+
 attribute_list
-       : attribute 
-         {
-               ArrayList attrs = new ArrayList ();
-               attrs.Add ($1);
+       : attribute 
+         {
+               ArrayList attrs = null;
+               if ($1 != null) {
+                       attrs = new ArrayList ();
+                       attrs.Add ($1);
+               }
+               $$ = attrs;
+         }     
+       | attribute_list COMMA attribute
+         {
+               ArrayList attrs = null;
+               
+               if ($3 != null) {
+                       attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
+                       attrs.Add ($3);
+               }
 
-               $$ = attrs;
-              
-         }     
-       | attribute_list COMMA attribute
-         {
-               ArrayList attrs = (ArrayList) $1;
-               attrs.Add ($3);
+               $$ = attrs;
+         }     
+       ;
 
-               $$ = attrs;
-         }     
-       ;
-       
 attribute 
-       : attribute_name
-         {
-               $$ = lexer.Location;
-         }
-         opt_attribute_arguments
-         {
-               $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
-         }       
+       :  namespace_or_type_name
+          {
+               $$ = lexer.Location;
+          }
+          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_target_specifier
+       :  ASSEMBLY     { $$ = "assembly"; }
+       | MODULE        { $$ = "module"; }
+       | namespace_or_type_name
        ;
        
-attribute_name
-       : type_name 
-       ;
                        
 opt_attribute_arguments
        : /* empty */   { $$ = null; }
-       | OPEN_PARENS attribute_arguments CLOSE_PARENS
+       | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
          {
                $$ = $2;
          }     
        ;
+
+opt_attribute_arguments_list
+       : /* empty */
+       | attribute_arguments_list
+       ;               
        
-attribute_arguments
-       : opt_positional_argument_list
+attribute_arguments_list
+       : positional_argument_list
          {
-               if ($1 == null)
-                       $$ = null;
-               else {
-                       ArrayList args = new ArrayList ();
-                       args.Add ($1);
-               
-                       $$ = args;
-               }
+               ArrayList args = new ArrayList ();
+               args.Add ($1);
+       
+               $$ = args;
          }
         | positional_argument_list COMMA named_argument_list
          {
@@ -953,21 +1100,15 @@ attribute_arguments
          }
         ;
 
-
-opt_positional_argument_list
-       : /* empty */           { $$ = null; } 
-       | positional_argument_list
-       ;
-
 positional_argument_list
-       : expression
+       : constant_expression
          {
                ArrayList args = new ArrayList ();
                args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
 
                $$ = args;
          }
-        | positional_argument_list COMMA expression
+        | positional_argument_list COMMA constant_expression
         {
                ArrayList args = (ArrayList) $1;
                args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
@@ -994,7 +1135,7 @@ named_argument_list
         ;
 
 named_argument
-       : identifier ATTR_ASSIGN expression
+       : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
          {
                $$ = new DictionaryEntry (
                        (string) $1, 
@@ -1003,34 +1144,43 @@ named_argument
        ;
                                
 namespace_declaration
-       : opt_attributes NAMESPACE qualified_identifier logical_end_of_line
+       : NAMESPACE _mark_ qualified_identifier logical_end_of_line
          {
-               Attributes attrs = (Attributes) $1;
-
-               if (attrs != null) {
-                       foreach (AttributeSection asec in attrs.AttributeSections)
-                               if (asec.Target == "assembly")
-                                       RootContext.AddGlobalAttributeSection (current_container, asec);
-               }
-                         
                current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
+               
          } 
-         opt_imports_directives
          opt_declarations
-         END NAMESPACE logical_end_of_line
+         opt_end_block
+         {
+               int i = (int)$7;
+               if (end_priority[6]>=end_priority[i] && i!=6)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=6 && Parent!=6) 
+                       {
+                       Report.Error(30626,(Location)$2,"'NameSpace' is not having a matching 'End NameSpace'"); 
+                       Parent=i;
+                       }
+               if(i!=6)
+                       Parent=i;
+               if(Parent==6)
+                       Parent=0;
+         }
+         logical_end_of_line
          { 
                current_namespace = current_namespace.Parent;
          }
        ;
 
-type_declaration
+declaration_qualifiers
        : opt_attributes 
          opt_modifiers 
          { 
                current_attributes = (Attributes) $1; 
                current_modifiers = (int) $2; 
          }       
-         type_spec_declaration
        ;
 
 type_spec_declaration
@@ -1043,7 +1193,7 @@ type_spec_declaration
        ;
 
 class_declaration
-       : CLASS identifier logical_end_of_line opt_inherits opt_implements
+       : CLASS identifier _mark_ end_of_stmt opt_inherits opt_implements
          {
                // Module members are static by default, but Class *can't* be declared static
                // so we must fix it, if mbas was the one actually responsible for this
@@ -1056,17 +1206,45 @@ class_declaration
                
                name = MakeName ((string) $2);
                new_class = new Class (current_container, name, current_modifiers, 
-                                      (Attributes) current_attributes, lexer.Location);
+                                      (Attributes) current_attributes, (Location)$3);
 
                current_container = new_class;
                current_container.Namespace = current_namespace;
                RootContext.Tree.RecordDecl (name, new_class);
          }
          opt_class_member_declarations
-         END CLASS logical_end_of_line
+         opt_end_block
+         {
+               int i = (int)$9;
+               if (end_priority[7]>=end_priority[i] && i!=7)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=7 && Parent!=7) 
+                       {
+                       Report.Error(30481,(Location)$3,"'Class' is not having a matching 'End Class'"); 
+                       Parent=i;
+                       }
+               if(i!=7)
+                       Parent=i;
+               if(Parent==7)
+                       Parent=0;
+         }
+         logical_end_of_line
          {
                Class new_class = (Class) current_container;
-               new_class.Bases = (ArrayList) $4;       
+               
+               ArrayList bases = (ArrayList) $5;
+
+               ArrayList ifaces = (ArrayList) $6;
+               if (ifaces != null){
+                       if (bases != null)      
+                               bases.AddRange(ifaces);
+                       else
+                               bases = ifaces;
+               }
+               new_class.Bases = bases;
        
                current_container = current_container.Parent;
                CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
@@ -1077,12 +1255,12 @@ class_declaration
 
 opt_inherits
        : /* empty */                           { $$ = null; }
-       | INHERITS type_list logical_end_of_line        { $$ = $2; }
+       | INHERITS type_list end_of_stmt        { $$ = $2; }
        ;
 
 opt_implements
        : /* empty */                           { $$ = null; }
-       | IMPLEMENTS type_list logical_end_of_line      { $$ = $2; }
+       | IMPLEMENTS type_list end_of_stmt              { $$ = $2; }
        ;
 
 opt_modifiers
@@ -1124,22 +1302,40 @@ modifier
        ;
 
 module_declaration
-       : MODULE identifier logical_end_of_line
+       : MODULE _mark_ identifier logical_end_of_line
          { 
                Module new_module;
                string name;
-               name = MakeName((string) $2);
+               name = MakeName((string) $3);
                new_module = new Module(current_container, 
                                        name, 
                                        current_modifiers, // already checks then
                                        (Attributes) current_attributes,
-                                       lexer.Location);
+                                       (Location)$2);
                current_container = new_module;
                current_container.Namespace = current_namespace;
                RootContext.Tree.RecordDecl(name, new_module);
          }
          opt_module_member_declarations
-         END MODULE logical_end_of_line
+         opt_end_block
+         {
+               int i = (int)$7;
+               if (end_priority[5]>=end_priority[i] && i!=5)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=5 && Parent!=5) 
+                       {
+                       Report.Error(30625,(Location)$2,"'Module' is not having a matching 'End Module'"); 
+                       Parent=i;
+                       }
+               if(i!=5)
+                       Parent=i;
+               if(Parent==5)
+                       Parent=0;
+         }
+         logical_end_of_line
          {
                Module new_module = (Module)current_container;
 
@@ -1194,7 +1390,7 @@ module_member_declarator
        ;
        
 constant_declaration
-       : CONST constant_declarators logical_end_of_line
+       : CONST constant_declarators end_of_stmt
        {
                // Module members are static by default, but constants *can't* be declared static
                // so we must fix it, if mbas was the one actually responsible for this
@@ -1277,21 +1473,21 @@ must_override_declaration
        ;
        
 must_override_sub_declaration
-       : MUSTOVERRIDE SUB identifier opt_params logical_end_of_line
+       : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause _mark_ logical_end_of_line
          {     
                if (current_container is Module)
-                       Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
+                       Report.Error (30433, (Location)$6, "Methods in a Module cannot be declared 'MustOverride'.");
                        
                if (current_container is Struct)
-                       Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+                       Report.Error (435, (Location)$6, "Methods in a Structure cannot be declared 'MustOverride'.");
                
                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, (Location)$6);
                                            
                if (!(current_container is Class))
-                       Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");               
+                       Report.Error (9999, (Location)$6, "THIS SHOULD NEVER HAPPEN!");         
                        
                $$ = method;                        
          }
@@ -1299,56 +1495,77 @@ 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 _mark_ 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;
+               Expression ftype = ($7 == null) ? (($4 == null) ? TypeManager.  
+                       system_object_expr : (Expression) $4 ) : (Expression) $7;
 
                if (current_container is Module)
-                       Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
+                       Report.Error (30433, (Location)$6,"Methods in a Module cannot be declared 'MustOverride'.");
                        
                if (current_container is Struct)
-                       Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+                       Report.Error (435, (Location)$6,"Methods in a Structure cannot be declared 'MustOverride'.");
                                
                current_modifiers |= Modifiers.ABSTRACT;
                                                        
                Method method = new Method ((Expression) ftype, (int) current_modifiers, 
-                                               (string) $3,(Parameters) $5, null, null
-                                               lexer.Location);
+                                               (string) $3,(Parameters) $5, null, (ArrayList) $8
+                                               (Location)$6);
                                            
                if (!(current_container is Class))
-                       Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
+                       Report.Error (9999, (Location)$6,"THIS SHOULD NEVER HAPPEN!");
                        
                $$ = method;                                    
          }     
        ;
        
 sub_declaration
-       : SUB identifier opt_params opt_evt_handler opt_implement_clause logical_end_of_line
+       : SUB identifier _mark_ opt_params opt_evt_handler opt_implement_clause logical_end_of_line
          { 
-               current_local_parameters = (Parameters) $3;
+               current_local_parameters = (Parameters) $4;
                start_block(); 
 
                // Structure members are Public by default                      
                if ((current_container is Struct) && (current_modifiers == 0))
                        current_modifiers = Modifiers.PUBLIC;           
 
-               member_location = lexer.Location;
          }
          opt_statement_list 
-         END SUB logical_end_of_line
+         opt_end_block 
+         {
+               int i = (int)$10;
+               if (end_priority[4]>=end_priority[i] && i!=4)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=4 && Parent!=4) 
+                       {
+                       Report.Error(30289,(Location)$3,"'Sub' is not having a matching 'End Sub'"); 
+                       Parent=i;
+                       }
+               if(i!=4)
+                       Parent=i;
+               if(Parent==4)
+                       Parent=0;
+         }
+         logical_end_of_line
          {
                Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
                                            (Parameters) current_local_parameters, (Attributes) current_attributes, 
-                                           (Expression) $5, member_location);
+                                           (ArrayList) $6, (Location)$3);
        
                method.Block = (Block) end_block();
                $$ = method;
 
-               if ($4 != null) { 
+               if ($5 != null) { 
                        // we have an event handler to take care of 
 
-                       string evt_def = ((MemberAccess)$6).ToString();
+                 Expression handles_exp = (Expression) $5;
+                 Location loc = (Location)$3;
+                 
+                 if (handles_exp is MemberAccess) {
+                       string evt_def = ((MemberAccess)$5).ToString();
                        int pos = evt_def.LastIndexOf (".");
                        string evt_target = evt_def.Substring (0, pos);
                        bool found = false;
@@ -1356,11 +1573,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
+                                               Statement addhnd = (Statement) new AddHandler ((Expression) $5
                                                                                        DecomposeQI((string) $2, loc), 
-                                                                                       DecomposeQI(evt_target, loc), loc);
+                                                                                       loc);
 
                                                current_container.AddEventHandler (addhnd);
                                                found = true;
@@ -1368,24 +1585,31 @@ sub_declaration
                                        }
                                }               
                        }
-
+                       
                        if (!found){
-                               Report.Error(30506, lexer.Location,
+                               Report.Error(30506, (Location)$3,
                                                evt_target + " is not declared with WithEvents");
                        }
+                 } else if (handles_exp is BaseAccess) {
+                               Statement addhnd = (Statement) new AddHandler ((Expression) $5, 
+                                                                                       DecomposeQI((string) $2, loc), 
+                                                                                       loc);   
+                                                                                       
+                               current_container.AddEventHandler (addhnd);
+                 }
+                 
                }       
          }       
        ;
-       
+
 func_declaration
        : FUNCTION identifier opt_type_character
-         opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
+         opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
          { 
                current_local_parameters = (Parameters) $4;
-               member_location = lexer.Location;
                start_block(); 
                                
-               Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+               Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
 
                // Structure members are Public by default                      
                if ((current_container is Struct) && (current_modifiers == 0))
@@ -1393,28 +1617,46 @@ func_declaration
                // Add local var declaration
                // for return value
                ArrayList retval = new ArrayList ();
-               retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
-               declare_local_variables ((Expression) ftype, retval, lexer.Location);
+               retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, (Location)$5));
+               declare_local_variables ((Expression) ftype, retval, (Location)$5);
          }       
          opt_statement_list
-         END FUNCTION logical_end_of_line
+         opt_end_block 
+         {
+               int i = (int)$11;
+               if (end_priority[8]>=end_priority[i] && i!=8)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=8 && Parent!=8) 
+                       {
+                       Report.Error(30027,(Location)$5,"'Function' is not having a matching 'End Function'"); 
+                       Parent=i;
+                       }
+               if(i!=8)
+                       Parent=i;
+               if(Parent==8)
+                       Parent=0;
+         }
+         logical_end_of_line
          {
-               Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+               Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
 
                Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
                                            (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes,  */
-                                           (Expression) $6, member_location);
+                                           (ArrayList) $7, (Location)$5);
                method.Block = end_block();
                $$ = method;
          }       
        ;               
 
 struct_declaration
-       : STRUCTURE identifier logical_end_of_line
+       : STRUCTURE _mark_ identifier end_of_stmt
          opt_implement_clause
          {
                Struct new_struct;
-               string full_struct_name = MakeName ((string) $2);
+               string full_struct_name = MakeName ((string) $3);
                
                // Module members are static by default, but structures *can't* be declared static
                // so we must fix it, if mbas was the one actually responsible for this
@@ -1424,7 +1666,7 @@ struct_declaration
                        
                new_struct = new Struct (current_container, full_struct_name, 
                                         (int) current_modifiers,
-                                        (Attributes) current_attributes, lexer.Location);
+                                        (Attributes) current_attributes, (Location)$2);
                current_container = new_struct;
                current_container.Namespace = current_namespace;
                RootContext.Tree.RecordDecl (full_struct_name, new_struct);
@@ -1433,14 +1675,33 @@ struct_declaration
          {
                Struct new_struct = (Struct) current_container;
 
-               if ($4 != null)
-                       new_struct.Bases = (ArrayList) $4;
+               if ($5 != null)
+                       new_struct.Bases = (ArrayList) $5;
 
                current_container = current_container.Parent;
                CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
                $$ = new_struct;
          }
-         END STRUCTURE logical_end_of_line
+         opt_end_block 
+         {
+               int i = (int)$9;
+               if (end_priority[9]>=end_priority[i] && i!=9)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=9 && Parent!=9) 
+                       {
+                       
+                       Report.Error(30624,(Location)$2,"'Structure' is not having a matching 'End Structure'"); 
+                       Parent=i;
+                       }
+               if(i!=9)
+                       Parent=i;
+               if(Parent==9)
+                       Parent=0;
+         }
+         logical_end_of_line
        ;
        
 opt_struct_member_declarations
@@ -1479,46 +1740,68 @@ struct_member_declarator
        ;
        
 event_declaration
-       : EVENT identifier AS type logical_end_of_line
+       : EVENT identifier _mark_ AS type opt_implement_clause logical_end_of_line
          {
-               VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
+               VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $5, (Location)$3);
 
-               Event e = new Event ((Expression) $4, var.identifier, 
-                                    null, current_modifiers, null, null, 
-                                    current_attributes, lexer.Location);
+               Event e = new Event ((Expression) $5, var.identifier, 
+                                    null, current_modifiers, 
+                                    current_attributes, (ArrayList) $6,
+                                    (Location)$3);
 
                CheckDef (current_container.AddEvent (e), e.Name, e.Location);
-
          }
-       | EVENT identifier opt_params logical_end_of_line
+       | EVENT identifier _mark_ opt_params opt_implement_clause logical_end_of_line
          {
-               string delName = (string) $2;
-               delName = delName + "EventHandler";
-           Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
-                                               (current_container, TypeManager.system_void_expr, 
-                                            (int) current_modifiers, MakeName(delName), (Parameters) $3, 
-                                            (Attributes) current_attributes, lexer.Location);
-                                                 
-               del.Namespace = current_namespace;
-               CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
-         
-               Event e = new Event (DecomposeQI (delName, lexer.Location),
+               string delName = null;
+
+               if ($5 == null) {
+                       delName = (string) $2;
+                       delName = delName + "EventHandler";
+                       Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
+                                                       (current_container, TypeManager.system_void_expr, 
+                                                       (int) current_modifiers, MakeName(delName), (Parameters) $4, 
+                                                       (Attributes) current_attributes, (Location)$3);
+                                                         
+                       del.Namespace = current_namespace;
+                       CheckDef (current_container.AddDelegate (del), del.Name, (Location)$3);
+               } else {
+                       ArrayList impls = (ArrayList) $5;
+                       if (impls.Count > 1) {
+                               string expstr = "Event '" + ((Expression) impls[1]).ToString () +
+                                       "' can not be implemented with Event '" +
+                                       (string) $2 + "', since it's delegate type does not match " +
+                                       "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
+                               Report.Error (31407, (Location)$3, expstr);
+                       }                       
+                       Expression impl = (Expression) impls[0];  
+                       delName = impl.ToString();
+                       delName = delName.Substring (delName.LastIndexOf(".") + 1);
+                       delName = delName + "EventHandler";
+               }
+               
+               Event e = new Event (DecomposeQI (delName, (Location)$3),
                                         (string) $2, 
-                                    null, current_modifiers, null, null, 
-                                    current_attributes, lexer.Location);
+                                    null, current_modifiers, 
+                                    current_attributes, (ArrayList) $5, 
+                                    (Location)$3);
 
                CheckDef (current_container.AddEvent (e), e.Name, e.Location);
          }
        ;
        
 enum_declaration
-       : ENUM identifier opt_type_spec logical_end_of_line
-         opt_enum_member_declarations
+       : ENUM _mark_ identifier opt_type_spec logical_end_of_line
+         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;
+               Location enum_location = (Location)$2;
+               string full_name = MakeName ((string) $3);
+               Expression enum_type = ($4 == null) ? TypeManager.system_int32_expr : (Expression) $4;
+               ArrayList enum_members = (ArrayList) $6;
+               
+               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
@@ -1544,7 +1827,25 @@ enum_declaration
                RootContext.Tree.RecordDecl (full_name, e);
 
          }
-         END ENUM logical_end_of_line
+         opt_end_block 
+         {
+               int i = (int)$8;
+               if (end_priority[10]>=end_priority[i] && i!=10)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=10 && Parent!=10) 
+                       {
+                       Report.Error(30185,(Location)$2,"'ENUM' is not having a matching 'End ENUM'"); 
+                       Parent=i;
+                       }
+               if(i!=10)
+                       Parent=i;
+               if(Parent==10)
+                       Parent=0;
+        }
+         logical_end_of_line
        ;
 
 opt_enum_member_declarations
@@ -1571,9 +1872,9 @@ enum_member_declarations
        ;
 
 enum_member_declaration
-       : opt_attributes identifier logical_end_of_line
+       : opt_attributes identifier _mark_ logical_end_of_line
          {
-               $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
+               $$ = new VariableDeclaration ((string) $2, null, (Location)$3, (Attributes) $1);
          }
        | opt_attributes identifier
          {
@@ -1581,21 +1882,20 @@ enum_member_declaration
          }
           ASSIGN expression logical_end_of_line
          { 
-               $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
+               $$ = new VariableDeclaration ((string) $2, (Expression)$5, (Location)$3, (Attributes) $1);
          }
        ;
                
 interface_declaration
-       : INTERFACE identifier logical_end_of_line
+       : INTERFACE _mark_ identifier logical_end_of_line
          {
                Interface new_interface;
-               string full_interface_name = MakeName ((string) $2);
+               string full_interface_name = MakeName ((string) $3);
 
                new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
-                                              (Attributes) current_attributes, lexer.Location);
+                                              (Attributes) current_attributes, (Location)$2);
                if (current_interface != null) {
-                       Location l = lexer.Location;
-                       Report.Error (-2, l, "Internal compiler error: interface inside interface");
+                       Report.Error (-2, (Location)$2, "Internal compiler error: interface inside interface");
                }
                current_interface = new_interface;
                new_interface.Namespace = current_namespace;
@@ -1606,40 +1906,52 @@ interface_declaration
          { 
                Interface new_interface = (Interface) current_interface;
 
-               if ($5 != null)
-                       new_interface.Bases = (ArrayList) $5;
+               if ($6 != null)
+                       new_interface.Bases = (ArrayList) $6;
 
                current_interface = null;
                CheckDef (current_container.AddInterface (new_interface),
                          new_interface.Name, new_interface.Location);
 
          }
-         END INTERFACE logical_end_of_line
+         opt_end_block 
+         {
+               int i = (int)$9;
+               if (end_priority[11]>=end_priority[i] && i!=11)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=11 && Parent!=11) 
+                       {
+                       Report.Error(30253,(Location)$2,"'INTERFACE' is not having a matching 'End INTERFACE'"); 
+                       Parent=i;
+                       }
+               if(i!=11)
+                       Parent=i;
+               if(Parent==11)
+                       Parent=0;
+        }
+         logical_end_of_line
        ;
 
 opt_interface_base
        : /* empty */                     { $$ = null; }
-       | interface_base
+       | interface_bases
+       ;
+
+interface_bases
+       : interface_base
+       | interface_bases interface_base
+         {
+               ArrayList bases = (ArrayList) $1;
+               bases.AddRange ((ArrayList) $2);
+               $$ = bases;
+         }
        ;
 
 interface_base
-       : INHERITS interface_type_list    { $$ = $2; }
-       ;
-
-interface_type_list
-       : interface_type
-         {
-               ArrayList interfaces = new ArrayList ();
-
-               interfaces.Add ($1);
-               $$ = interfaces;
-         }
-       | interface_type_list COMMA interface_type
-         {
-               ArrayList interfaces = (ArrayList) $1;
-               interfaces.Add ($3);
-               $$ = interfaces;
-         }
+       : INHERITS type_list logical_end_of_line  { $$ = $2; }
        ;
 
 interface_body
@@ -1657,94 +1969,144 @@ interface_member_declarations
        ;
 
 interface_member_declaration
+       : opt_attributes
+         opt_modifiers
+         { 
+               current_attributes = (Attributes) $1;
+               current_modifiers = ((int)$2) | Modifiers.ABSTRACT; 
+         }
+         interface_member_declarator
+         {
+               $$ = $3;
+         }
+       ;
+       
+interface_member_declarator
        : interface_method_declaration          
          { 
-               InterfaceMethod m = (InterfaceMethod) $1;
-
+               Method m = (Method) $1;
                CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
          }
        | interface_property_declaration        
-         { 
-               InterfaceProperty p = (InterfaceProperty) $1;
-               
-               CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
-          }
        | interface_event_declaration 
-          { 
-               InterfaceEvent e = (InterfaceEvent) $1;
-
-               CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
-         }
        ;
 
-opt_new
-       : /* empty */   { $$ = false; }
-       | NEW           { $$ = true; }
-       ;
-       
 interface_method_declaration
-       : SUB identifier
-         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS logical_end_of_line
+       : SUB identifier opt_params _mark_ logical_end_of_line
          {
-               $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
-                                         (Parameters) $4, current_attributes, lexer.Location);
-         }
-       | FUNCTION identifier opt_type_character
-         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
-         {
-               if ($3 != null && $3 != $8)
-                       Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
+               Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
+                                           (Parameters) $3, current_attributes, null, (Location)$4);
                
-               $$ = new InterfaceMethod (
-                                         (Expression) $8, (string) $2, false, (Parameters) $5,
-                                         current_attributes, lexer.Location);
+               $$ = method;
          }
-       | FUNCTION identifier type_character
-         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+       | FUNCTION identifier opt_type_character opt_params _mark_ opt_type_with_ranks logical_end_of_line
          {
-               $$ = new InterfaceMethod (
-                                         (Expression) $3, (string) $2, false, (Parameters) $5,
-                                         current_attributes, lexer.Location);
+               Expression ftype = ($6 == null) ? (($3 == null) ? TypeManager.  
+                       system_object_expr : (Expression) $3 ) : (Expression) $6;
+               
+               Method method = new Method ((Expression) ftype, (int) current_modifiers, 
+                                               (string) $2,(Parameters) $4, current_attributes, null, 
+                                               (Location)$5);
+               
+               $$ = method;
          }
        ;
 
 interface_property_declaration
-       : opt_modifiers PROPERTY identifier
-         OPEN_PARENS
-         opt_formal_parameter_list
-         CLOSE_PARENS opt_type_spec logical_end_of_line
+       : PROPERTY identifier _mark_ opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
          {
-               // FIXME we MUST pass property parameters
-               $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
-                                           true, true, current_attributes,
-                                           lexer.Location);
+               Expression ftype = ($6 == null) ? (($4 == null) ? 
+                               TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
+
+               current_local_parameters = (Parameters) $5;
+               if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
+                       get_parameters = current_local_parameters.Copy ((Location)$3);
+                       set_parameters = current_local_parameters.Copy ((Location)$3);
+                       
+                       Parameter implicit_value_parameter = new Parameter (
+                                       ftype, "Value", Parameter.Modifier.NONE, null);
+                       
+                       set_parameters.AppendParameter (implicit_value_parameter);
+               }
+               else
+               {
+                       get_parameters = Parameters.EmptyReadOnlyParameters;
+                       set_parameters = new Parameters (null, null ,(Location)$3); 
+                       
+                       Parameter implicit_value_parameter = new Parameter (
+                                       ftype, "Value", Parameter.Modifier.NONE, null);
+                       
+                       set_parameters.AppendParameter (implicit_value_parameter);
+               }
+               lexer.PropertyParsing = true;
+               
+               Accessor get_block = new Accessor (null, null); 
+               Accessor set_block = new Accessor (null, null); 
+                               
+               Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
+                                        get_block, set_block, current_attributes, (Location)$3,
+                                        null, get_parameters, set_parameters, null);
+    
+               CheckDef (current_interface.AddProperty (prop), prop.Name, (Location)$3);
+               
+               get_implicit_value_parameter_type = null;
+               set_implicit_value_parameter_type = null;
+               get_parameters = null;
+               set_parameters = null;
+               current_local_parameters = null;                        
          }
        ;
        
 interface_event_declaration
-       : opt_attributes opt_new EVENT type identifier logical_end_of_line
+       : EVENT identifier AS _mark_ type logical_end_of_line
          {
-               $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
-                                        lexer.Location);
+               VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $5, (Location)$4);
+
+               Event e = new Event ((Expression) $5, var.identifier, 
+                                    null, current_modifiers, 
+                                    current_attributes, (Location)$4);
+
+               CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
+
+         }
+       | EVENT identifier opt_params _mark_ logical_end_of_line
+         {
+               string delName = (string) $2;
+               delName = delName + "EventHandler";
+               int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
+           Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
+                                               (current_container, TypeManager.system_void_expr, 
+                                            (int) delModifiers, MakeName(delName), (Parameters) $3, 
+                                            (Attributes) current_attributes, (Location)$4);
+                                                 
+               del.Namespace = current_namespace;
+               CheckDef (current_interface.AddDelegate (del), del.Name, (Location)$4);
+         
+               Event e = new Event (DecomposeQI (delName, (Location)$4),
+                                        (string) $2, 
+                                    null, current_modifiers, 
+                                    current_attributes, (Location)$4);
+
+               CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
          }
        ;
 
- property_declaration
-       : abstruct_propery_declaration
-       | non_abstruct_propery_declaration 
+property_declaration
+       : abstract_propery_declaration
+       | non_abstract_propery_declaration 
        ;
        
-abstruct_propery_declaration
-       : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters AS type logical_end_of_line
+abstract_propery_declaration
+       : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters _mark_ opt_type_with_ranks logical_end_of_line
          {     
                Expression ftype = ($7 == null) ? (($4 == null) ? 
                                TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $7;
 
                if (current_container is Module)
-                       Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
+                       Report.Error (30503, (Location) $6 , "Properties in a Module cannot be declared 'MustOverride'.");
                        
                if (current_container is Struct)
-                       Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+                       Report.Error (435, (Location) $6 ,"Methods in a Structure cannot be declared 'MustOverride'.");
                                
                current_modifiers |= Modifiers.ABSTRACT;
                
@@ -1752,6 +2114,11 @@ abstruct_propery_declaration
                if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
                        get_parameters = current_local_parameters.Copy (lexer.Location);
                        set_parameters = current_local_parameters.Copy (lexer.Location);
+                       
+                       Parameter implicit_value_parameter = new Parameter (
+                                       ftype, "Value", Parameter.Modifier.NONE, null);
+                       
+                       set_parameters.AppendParameter (implicit_value_parameter);
                }
                else
                {
@@ -1773,7 +2140,7 @@ abstruct_propery_declaration
                                         null, get_parameters, set_parameters, null);
     
                if (!(current_container is Class))
-                       Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
+                       Report.Error (9999, (Location) $6, "THIS SHOULD NEVER HAPPEN!");
                        
                CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
                
@@ -1786,9 +2153,25 @@ abstruct_propery_declaration
        ;
        
        
- non_abstruct_propery_declaration
-         : PROPERTY identifier opt_type_character opt_property_parameters AS type opt_implement_clause logical_end_of_line
-         {
+ non_abstract_propery_declaration
+         : PROPERTY identifier 
+           opt_type_character  
+           opt_property_parameters 
+           _mark_
+           opt_type_with_ranks
+           opt_implement_clause 
+         {
+               if ((current_modifiers & Modifiers.DEFAULT) > 0) {
+                       if (current_container.DefaultPropName != null 
+                                 && current_container.DefaultPropName != (string) $2)
+                               Report.Error (30359, 
+                                               (Location) $5,
+                                               "Type '" + current_container.Name +
+                                               "' cannot have more than one 'Default Property' ");
+                                               
+                       current_container.DefaultPropName = (string) $2;
+               }               
+         
                get_implicit_value_parameter_type  = 
                        ($6 == null) ? (($3 == null) ? 
                                TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
@@ -1796,20 +2179,39 @@ abstruct_propery_declaration
                
                current_local_parameters = (Parameters) $4;
                if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
-                       get_parameters = current_local_parameters.Copy (lexer.Location);
-                       set_parameters = current_local_parameters.Copy (lexer.Location);
+                       get_parameters = current_local_parameters.Copy ((Location)$5);
+                       set_parameters = current_local_parameters.Copy ((Location)$5);
                }
                else
                {
                        get_parameters = Parameters.EmptyReadOnlyParameters;
-                       set_parameters = new Parameters (null, null ,lexer.Location);           
+                       set_parameters = new Parameters (null, null ,(Location)$5);             
                }
                lexer.PropertyParsing = true;
 
-               $$ = lexer.Location;
+               $$ = (Location)$5;
          }
+         logical_end_of_line
          accessor_declarations 
-         END PROPERTY logical_end_of_line
+         opt_end_block 
+         {
+               int i = (int)$11;
+               if (end_priority[12]>=end_priority[i] && i!=12)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=12 && Parent!=12) 
+                       {
+                       Report.Error(30025,(Location)$5,"'Property' is not having a matching 'End Property'"); 
+                       Parent=i;
+                       }
+               if(i!=12)
+                       Parent=i;
+               if(Parent==12)
+                       Parent=0;
+        }
+          logical_end_of_line
          {
                lexer.PropertyParsing = false;
 
@@ -1827,16 +2229,16 @@ abstruct_propery_declaration
                        set_block = (Accessor) pair.Second;
                }
                
-               Location loc = lexer.Location;
+               Location loc = (Location) $5 ;
                
                // Structure members are Public by default                      
                if ((current_container is Struct) && (current_modifiers == 0))
                        current_modifiers = Modifiers.PUBLIC;                           
                        
-               prop = new Property ((Expression) /*$6*/ get_implicit_value_parameter_type, 
+               prop = new Property ((Expression) get_implicit_value_parameter_type, 
                                         (string) $2, current_modifiers, get_block, set_block,
                                     current_attributes, loc, set_implicit_value_parameter_name, 
-                                    get_parameters, set_parameters, (Expression) $7);
+                                    get_parameters, set_parameters, (ArrayList) $7);
                
                CheckDef (current_container.AddProperty (prop), prop.Name, loc);
                get_implicit_value_parameter_type = null;
@@ -1863,10 +2265,26 @@ opt_implement_clause
          {
                $$ = null;
          }
-       | IMPLEMENTS qualified_identifier
+       | IMPLEMENTS implement_clause_list
          {
-               $$ = DecomposeQI ((string)$2, lexer.Location);
+               $$ = $2;
+         }
+       ;
+       
+implement_clause_list
+       : qualified_identifier
+         {
+          ArrayList impl_list = new ArrayList ();
+          impl_list.Add (DecomposeQI ((string)$1, lexer.Location));
+               $$ = impl_list;
          }     
+       | implement_clause_list COMMA qualified_identifier
+         {
+               ArrayList impl_list = (ArrayList) $1;
+               impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
+               $$ = impl_list;
+         }     
+         
        ;
        
 accessor_declarations
@@ -1891,10 +2309,10 @@ opt_set_accessor_declaration
        ;
 
 get_accessor_declaration
-       : opt_attributes GET logical_end_of_line
+       : opt_attributes GET _mark_ logical_end_of_line
          {
                if ((current_modifiers & Modifiers.WRITEONLY) != 0)
-                       Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
+                       Report.Error (30023, (Location)$3, "'WriteOnly' properties cannot have a 'Get' accessor");
          
                current_local_parameters = get_parameters;
                
@@ -1904,11 +2322,29 @@ get_accessor_declaration
                // Add local var declaration
                // for return value
                ArrayList retval = new ArrayList ();
-               retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
+               retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, (Location)$3));
                declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);    
          }
          opt_statement_list
-         END GET logical_end_of_line
+          opt_end_block
+          {
+                int i = (int)$7;
+               if (end_priority[19]>=end_priority[i] && i!=19)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+                if (i!=19 && Parent!=19)
+                        {
+                        Report.Error(30631,(Location)$3,"'GET' is not having a matching 'End Get'");
+                        Parent=i;
+                        }
+                if(i!=19)
+                        Parent=i;
+                if(Parent==19)
+                        Parent=0;
+          }
+         logical_end_of_line
          {
                $$ = new Accessor ((Block) end_block(), (Attributes) $1);
                current_local_parameters = null;
@@ -1917,10 +2353,12 @@ get_accessor_declaration
        ;
 
 set_accessor_declaration
-       : opt_attributes SET opt_set_parameter logical_end_of_line
+       : opt_attributes SET opt_set_parameter _mark_ logical_end_of_line
          {
         if ((current_modifiers & Modifiers.READONLY) != 0)
-                       Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
+                       Report.Error (30022,
+                                     (Location)$4,
+                                     "'ReadOnly' properties cannot have a 'Set' accessor");
                        
                Parameter implicit_value_parameter = new Parameter (
                        set_implicit_value_parameter_type, 
@@ -1934,7 +2372,26 @@ set_accessor_declaration
                lexer.PropertyParsing = false;
          }
          opt_statement_list
-         END SET logical_end_of_line
+          opt_end_block
+          {
+                int i = (int)$8;
+               if (end_priority[18]>=end_priority[i] && i!=18)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+                if (i!=18 && Parent!=18)
+                        {
+                        Report.Error(30633,(Location)$4,"'SET' is not having a matching 'End Set'");
+                        Parent=i;
+                        }
+                if(i!=18)
+                        Parent=i;
+                if(Parent==18)
+                        Parent=0;
+          }
+
+          logical_end_of_line
          {
                $$ = new Accessor ((Block) end_block(), (Attributes) $1);
                current_local_parameters = null;
@@ -1953,7 +2410,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)
@@ -1963,11 +2420,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
@@ -1977,10 +2434,9 @@ opt_set_parameter
                        
 field_declaration
        : opt_dim_stmt 
-         variable_declarators logical_end_of_line
+         variable_declarators end_of_stmt
          {               
                int mod = (int) current_modifiers;
-               
 
                VariableDeclaration.FixupTypes ((ArrayList) $2);
                VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
@@ -2050,13 +2506,13 @@ opt_dim_stmt
        ; 
                
 delegate_declaration
-       : DELEGATE SUB  
+       : DELEGATE SUB _mark_  
          identifier OPEN_PARENS 
          opt_formal_parameter_list
          CLOSE_PARENS 
          logical_end_of_line
          {
-               Location l = lexer.Location;
+               Location l = (Location)$3;
                // Module members are static by default, but delegates *can't* be declared static
                // so we must fix it, if mbas was the one actually responsible for this
                // instead of triggering an error.
@@ -2066,18 +2522,18 @@ delegate_declaration
                Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container, 
                                                 TypeManager.system_void_expr, 
                                             (int) current_modifiers, 
-                                MakeName ((string) $3), (Parameters) $5
+                                MakeName ((string) $4), (Parameters) $6
                                             (Attributes) current_attributes, l);
                                                  
                del.Namespace = current_namespace;
                CheckDef (current_container.AddDelegate (del), del.Name, l);
          }     
-       | DELEGATE FUNCTION       
+       | DELEGATE FUNCTION _mark_        
          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;
+               Location l = (Location)$3;
                
                // Module members are static by default, but delegates *can't* be declared static
                // so we must fix it, if mbas was the one actually responsible for this
@@ -2085,12 +2541,12 @@ delegate_declaration
                if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
                        current_modifiers = (current_modifiers & ~Modifiers.STATIC);
                        
-               Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
+               Expression ftype = ($8 == null) ? TypeManager.system_object_expr : (Expression) $8;
                        
                Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
                        current_container,
-                       ftype, (int) current_modifiers, MakeName ((string) $3), 
-                       (Parameters) $5, (Attributes) current_attributes, l);
+                       ftype, (int) current_modifiers, MakeName ((string) $4), 
+                       (Parameters) $6, (Attributes) current_attributes, l);
 
                del.Namespace = current_namespace;
                CheckDef (current_container.AddDelegate (del), del.Name, l);
@@ -2098,33 +2554,39 @@ 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
          {
-               $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);     
+               $$ = $1;
+         }
+       | ME DOT qualified_identifier
+         {
+               $$ = (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);
-         }
-       ;       
-
-opt_empty_parens
-       : /* empty */
-       | OPEN_PARENS CLOSE_PARENS
-       ;       
+         }*/
+       ;
 
 constructor_declaration
-       : SUB NEW opt_params logical_end_of_line
+       : SUB _mark_ NEW opt_params logical_end_of_line
          {
-               current_local_parameters = (Parameters) $3;
+               current_local_parameters = (Parameters) $4;
                start_block();
                oob_stack.Push (lexer.Location);
 
                Location l = (Location) oob_stack.Pop ();
-               $$ = new Constructor ((string) "New", (Parameters) $3, (ConstructorInitializer) null, l);
+               $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
                $1 = $$;
          }
          opt_statement_list
@@ -2139,7 +2601,25 @@ constructor_declaration
                CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
                current_local_parameters = null;
          }
-         END SUB logical_end_of_line
+         opt_end_block 
+         {
+               int i = (int)$9;
+               if (end_priority[4]>=end_priority[i] && i!=4)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=4 && Parent!=4) 
+                       {
+                       Report.Error(30289,(Location)$2,"'Sub' is not having a matching 'End Sub'"); 
+                       Parent=i;
+                       }
+               if(i!=4)
+                       Parent=i;
+               if(Parent==4)
+                       Parent=0;
+        }
+          logical_end_of_line
        ;
        
 opt_formal_parameter_list
@@ -2155,38 +2635,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;
 
@@ -2195,58 +2677,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 _mark_ 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");
+               if (opt_parm && ($8 == null))
+                       Report.Error (30812, (Location)$4, "Optional parameters must have a default value");
+
+               if (!opt_parm && ($8 != null))
+                       Report.Error (32024, (Location)$4, "Non-Optional parameters should not have a default value");
+
+               if ((pm & Parameter.Modifier.PARAMS) != 0) {
+                       if ((pm & ~Parameter.Modifier.PARAMS) != 0)
+                               Report.Error (30667, (Location)$4, "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
-
-               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);
-               }                       
+               if ($5 != null && $7 != null && $5 != $7)
+                       Report.Error (30302, (Location)$4, "Type character conflicts with declared type."); // TODO: Correct error number and message text
+
+               ptype = (Expression)(($7 == null) ? (($5 == null) ? TypeManager.system_object_expr : $5) : $7);
+               if ($6 != null) {
+                       string t = ptype.ToString ();
+                       if (t.IndexOf('[') >= 0)
+                               Report.Error (31087, (Location)$4, "Array types specified in too many places");
+                       else    
+                               ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $6, true, (Location)$4), (Location)$4);
+               }
+               if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
+                       Report.Error (30050, (Location)$4, "ParamArray parameters must be an array type");
                $$ = new Parameter (ptype, (string) $3, pm,
-                                       (Attributes) $1, (Expression) $7, opt_parm);
+                                       (Attributes) $1, (Expression) $8, 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;                      }
@@ -2261,6 +2732,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
@@ -2270,11 +2742,12 @@ opt_statement_list
 
 statement_list
        : statement 
-       | statement_list end_of_stmt statement
+       | statement_list end_of_stmt 
+         statement
        ;
        
-statement 
-           declaration_statement
+statement 
+         : declaration_statement
            {
                  if ($1 != null && (Block) $1 != current_block){
                        current_block.AddStatement ((Statement) $1);
@@ -2283,18 +2756,16 @@ statement :
            }
          | embedded_statement
            {
-                 Statement s = (Statement) $1;
-
                  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
            {
@@ -2304,8 +2775,6 @@ statement :
          /* | empty_statement */
          | with_statement 
            {
-                 Statement s = (Statement) $1;
-
              current_block.AddStatement ((Statement) $1);
            }     
          ;     
@@ -2317,6 +2786,7 @@ opt_raise_event_args
                $$ = $2;
          }
        ;
+
 label_name
        : identifier
        | LITERAL_INTEGER
@@ -2326,7 +2796,17 @@ label_name
        ;
 
 labeled_statement
-       : label_name COLON opt_logical_end_of_line 
+       : label_name COLON
+         {
+               LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
+
+               if (!current_block.AddLabel ((string) $1, labeled)){
+                       Location l = lexer.Location;
+                       Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
+               }       
+               current_block.AddStatement (labeled);
+         }
+       | label_name COLON
          {
                LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
 
@@ -2358,16 +2838,31 @@ empty_statement
 */
 
 with_statement
-       : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
+       : WITH _mark_ expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
          {
-               // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
-               Expression e = (Expression) $2;
+               // was : Expression e = DecomposeQI ((string) $3, (Location)$2);
+               Expression e = (Expression) $3;
                with_stack.Push(e);
                start_block();
          }
          opt_statement_list
-         END WITH
+         opt_end_block 
          {
+               int i = (int)$7;
+               if (end_priority[13]>=end_priority[i] && i!=13)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=13 && Parent!=13) 
+                       {
+                       Report.Error(30085,(Location)$2,"'With' is not having a matching 'End With'"); 
+                       Parent=i;
+                       }
+               if(i!=13)
+                       Parent=i;
+               if(Parent==13)
+                       Parent=0;
                Block b = end_block();
                with_stack.Pop();
                $$ = b;
@@ -2510,48 +3005,96 @@ iteration_statement
        ;
 
 foreach_statement
-       : FOR EACH identifier IN 
-         {
-               oob_stack.Push (lexer.Location);
-         }       
+       : FOR EACH identifier _mark_ opt_type_spec IN 
          expression end_of_stmt
          {
-               
-               start_block();
-               Block foreach_block = current_block;
-               Location l = lexer.Location;            
+               Location l = (Location)$4;              
                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 ($5 != null) 
+               {
+                       start_block();
+                       VariableDeclaration decl = new VariableDeclaration ((string) $3, 
+                                       (Expression) $5, null, (Location)$4, null);
+                       
+                       vi = current_block.AddVariable (
+                               (Expression) $5, 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) $5, "", 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, (Location)$4));
+                       }
                }
                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, (Location)$4,"Name '" + (string) $3 + "' is not declared.");
+               }
+               
                oob_stack.Push (v);
+               start_block();  
          }       
          opt_statement_list
-         NEXT opt_identifier
+         opt_end_block
+          {
+                int i = (int)$11;
+               if (end_priority[1]>=end_priority[i] && i!=1)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+                if (i!=1 && Parent!=1)
+                        {
+                        Report.Error(30084,(Location)$4,"'For' is not having a matching 'Next'");
+                        Parent=i;
+                        }
+                if(i!=1)
+                        Parent=i;
+                if(Parent==1)
+                        Parent=0;
+          }
+          opt_identifier
          {
-               Block foreach_block = current_block;
                LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
-               Block prev_block = end_block();
-               Location l = (Location) oob_stack.Pop ();
+               Block foreach_block = end_block();
 
                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, (Location)$4);
                
-               $$ = f;
+               if ($5 != null)
+               {
+                       current_block.AddStatement (f);
+                       $$ = end_block ();
+               }
+               else
+                       $$ = f;
          }       
        ;
 
 yield_statement 
-       : YIELD expression
+       : YIELD expression _mark_ 
          {
                if (!UseExtendedSyntax)
                {
@@ -2560,14 +3103,14 @@ yield_statement
                }
 /*             else
                        if (iterator_container == null){
-                               Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+                               Report.Error (204, (Location)$3, "yield statement can only be used within a method, operator or property");
                                $$ = null;
                        } else {
                                iterator_container.SetYields ();
-                               $$ = new Yield ((Expression) $2, lexer.Location);
+                               $$ = new Yield ((Expression) $2, (Location)$3);
                        } */
          }
-       | YIELD STOP
+       | YIELD STOP _mark_ 
          {
                if (!UseExtendedSyntax)
                {
@@ -2576,24 +3119,39 @@ yield_statement
                }
 /*             else
                        if (iterator_container == null){
-                               Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+                               Report.Error (204, (Location)$3, "yield statement can only be used within a method, operator or property");
                                $$ = null;
                        } else {
                                iterator_container.SetYields ();
-                               $$ = new YieldBreak (lexer.Location);
+                               $$ = new YieldBreak ((Location)$3);
                        } */
          }
        ;
 
 synclock_statement
-       : SYNCLOCK expression end_of_stmt
+       : SYNCLOCK _mark_ expression end_of_stmt
          {   
                start_block();  
          }
          opt_statement_list 
-         END SYNCLOCK
+         opt_end_block 
          {
-               $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
+               int i = (int)$7;
+               if (end_priority[14]>=end_priority[i] && i!=14)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=14 && Parent!=14) 
+                       {
+                       Report.Error(30675,(Location)$2,"'Synclock' is not having a matching 'End SyncLock'"); 
+                       Parent=i;
+                       }
+               if(i!=14)
+                       Parent=i;
+               if(Parent==14)
+                       Parent=0;
+               $$ = new Lock ((Expression) $3, (Statement) (Block) end_block(), (Location)$2);
          }
        ;
 
@@ -2603,21 +3161,39 @@ try_statement
        ;
                                
 try_header
-       : TRY end_of_stmt
+       : TRY _mark_ end_of_stmt
          {   
+               try_top=(Location)$2;
                start_block();  
          }
          opt_statement_list 
          opt_catch_clauses
          {
-               tmp_catch_clauses = (ArrayList) $5;
+               tmp_catch_clauses = (ArrayList) $6;
          }
        ;
-                                       
+       
+
+/*FIXME: Try block without a end try is throwing error at a wrong place*/                              
 try_catch
-       : try_header 
-         END TRY
-         { 
+       : try_header    
+         _mark_ opt_end_block 
+         {
+               int i = (int)$3;
+               if (end_priority[15]>=end_priority[i] && i!=15)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=15 && Parent!=15) 
+                       {
+                       Report.Error(30384,try_top,"'Try' is not having a matching 'End Try'"); 
+                       Parent=i;
+                       }
+               if(i!=15)
+                       Parent=i;
+               if(Parent==15)
+                       Parent=0;
                Catch g = null;
                ArrayList s = new ArrayList ();
 
@@ -2632,7 +3208,7 @@ try_catch
                // and g contains the general one.
                Block b = end_block();
 
-               $$ = new Try ((Block) b, s, g, null, lexer.Location);
+               $$ = new Try ((Block) b, s, g, null, try_top);
          }       
        ;       
          
@@ -2646,8 +3222,24 @@ try_catch_finally
                start_block(); 
          }       
          opt_statement_list 
-         END TRY
+         _mark_ opt_end_block 
          {
+               int i = (int)$8;
+               if (end_priority[15]>=end_priority[i] && i!=15)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+                if (i!=15 && Parent!=15)
+                        {
+                        Report.Error(30384,try_top,"'Try' is not having a matching 'End Try'");
+                        Parent=i;
+                        }
+                if(i!=15)
+                        Parent=i;
+                if(Parent==15)
+                        Parent=0;
+
                Catch g = null;
                ArrayList s = new ArrayList ();
                ArrayList catch_list = (ArrayList) tmp_catch_clauses;
@@ -2661,7 +3253,7 @@ try_catch_finally
                        }
                }
 
-               $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
+               $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), try_top);
        
          }     
          ;             
@@ -2693,8 +3285,16 @@ 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 _mark_ end_of_stmt
        {
                Expression type = null;
                string id = null;
@@ -2706,18 +3306,16 @@ catch_clause
                        
                        if (id != null){
                                ArrayList one = new ArrayList ();
-                               Location loc = lexer.Location;
+                               Location loc = (Location)$4;
 
                                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;
@@ -2737,10 +3335,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, (Location)$4);
        }
-        ;
+    ;
 
 opt_catch_args
        : /* empty */ {  $$ = null; }
@@ -2748,28 +3345,55 @@ opt_catch_args
        ;         
 
 catch_args 
-        : identifier AS type
+        : identifier AS _mark_ type
         {
-                $$ = new DictionaryEntry ($3, $1); 
+                $$ = new DictionaryEntry ($4, $1); 
+       }
+       | _mark_ AS type
+       {
+               Report.Error(30203, (Location)$1, "Identifier Expected");
+               $$ = null;
+       }
+       | identifier AS _mark_   
+       {
+               Report.Error(30182, (Location)$3, "Type Expected");
+               $$ = null;
        }
         ;
         
-        
+       
 do_statement
-       : DO opt_do_construct end_of_stmt
+       : DO _mark_ opt_do_construct end_of_stmt
          {
                start_block();
-               oob_stack.Push (lexer.Location);
          }     
          opt_statement_list
-         LOOP opt_do_construct
-         {
-               Expression t_before = (Expression) $2;
-               Expression t_after = (Expression) $7;
+         opt_end_block
+          {
+                int i = (int)$7;
+               if (end_priority[2]>=end_priority[i] && i!=2)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+                if (i!=2 && Parent!=2)
+                        {
+                        Report.Error(30083,(Location)$2,"'Do' is not having a matching 'Loop'");
+                        Parent=i;
+                        }
+                if(i!=2)
+                        Parent=i;
+                if(Parent==2)
+                        Parent=0;
+         }
+         _mark_ opt_do_construct
+         {
+               Expression t_before = (Expression) $3;
+               Expression t_after = (Expression) $10;
                Expression t;
 
                if  ((t_before != null) && (t_after != null))
-                       Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
+                       Report.Error (30238, (Location)$9, "'Loop' cannot have a condition if matching 'Do' has one.");
 
                if ((t_before == null) && (t_after == null))
                        t = new BoolLiteral (true);
@@ -2780,9 +3404,9 @@ do_statement
                
                if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
                    ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
-                        t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
+                        t = new Unary (Unary.Operator.LogicalNot, (Expression) t, (Location)$2);
                         
-               $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
+               $$ = new Do ((Statement) end_block(), (Expression) t, test_type, (Location)$2);
          }
          ;
 
@@ -2808,38 +3432,89 @@ while_statement
        }
        boolean_expression end_of_stmt
        opt_statement_list
-       END WHILE
-       {
+       opt_end_block
+          {
                Location l = (Location) oob_stack.Pop ();
+                int i = (int)$6;
+               if (end_priority[16]>=end_priority[i] && i!=16)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+                if (i!=16 && Parent!=16)
+                        {
+                        Report.Error(30082,l,"'While' is not having a matching 'End While'");
+                        Parent=i;
+                        }
+                if(i!=16)
+                        Parent=i;
+                if(Parent==16)
+                        Parent=0;
                Block b = end_block();
                Expression e = (Expression) $3;
                $$ = new While ((Expression) e, (Statement) b, l);
        }
        ;
        
-               
 for_statement
-       : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
+       : FOR _mark_ identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
          {
-               start_block();
+               if ($4 != null)
+               {
+                       start_block();
+                       ArrayList VarDeclaration = new ArrayList ();
+                       VarDeclaration.Add (new VariableDeclaration ((string) $3, 
+                               (Expression) $4, null, (Location)$2, null));
+
+                       DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), VarDeclaration);
+                       Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location)$2);
+                       current_block = b;
+               }
+               start_block();
          }
          opt_statement_list
-         NEXT opt_identifier 
+         opt_end_block
+          {
+                int i = (int)$13;
+               if (end_priority[1]>=end_priority[i] && i!=1)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+                if (i!=1 && Parent!=1)
+                        {
+                        Report.Error(30084,(Location)$2,"'For' is not having a matching 'Next'");
+                        Parent=i;
+                        }
+                if(i!=1)
+                        Parent=i;
+                if(Parent==1)
+                        Parent=0;
+         }
+          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)$2;
+                       Expression for_var = (Expression) DecomposeQI ((string)$3, l);
+                       
+            Expression assign_expr = new Assign (for_var, (Expression) $6, l);
+            Expression test_expr =  new Binary (Binary.Operator.LessThanOrEqual,
+                                                            for_var, (Expression) $8, l);
+            Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
+                                             for_var, (Expression) $9, 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 ($4 != null)
+                       {
+                               current_block.AddStatement (f);
+                               $$ = end_block();
+                       }
+                       else
+                               $$ = f;
+         }
        ;
 
 opt_step
@@ -2853,33 +3528,75 @@ selection_statement
        ;
 
 if_statement
-       : if_statement_open opt_then if_statement_rest
+       : if_statement_open opt_then end_of_stmt opt_statement_list if_statement_rest
          {
-               $$ = $3;
+               $$ = $5;
          }
-       | 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);
          }
        ;
 
 pre_embedded_statement
        : embedded_statement 
          {
-               Statement s = (Statement) $1;
-
                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();
+               current_block.AddStatement ((Statement) $2);
+         } 
+       ;       
+
+/*FIXME:if without end if not working. Error line shown is nor correct*/
 if_statement_open
-       : IF boolean_expression 
+       : IF 
          {
                oob_stack.Push (lexer.Location);
+         }
+               boolean_expression 
+         {
                start_block();
-               tmp_expr = (Expression) $2;
+               tmp_expr = (Expression) $3;
                expr_stack.Push(tmp_expr);
          }
         ;
@@ -2890,41 +3607,69 @@ opt_then
        ;
        
 if_statement_rest
-       : end_of_stmt
-         opt_statement_list
-         END IF
+       : 
+         opt_end_block 
          { 
                Location l = (Location) oob_stack.Pop ();
-                Expression expr = (Expression)expr_stack.Pop(); 
+               int i = (int)$1;
+               if (end_priority[3]>=end_priority[i] && i!=3)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=3 && Parent!=3) 
+                       {
+                               Report.Error(30081,l,"'If' is not having a matching 'EndIf'"); 
+                               Parent = i;
+                       }
+               if(i!=3)
+                       Parent=i;
+               if(Parent==3)
+                       Parent=0;
+                       Expression expr = (Expression)expr_stack.Pop(); 
                $$ = new If ((Expression) expr, (Statement) end_block(), l);
          }       
-       | end_of_stmt
-         opt_statement_list
+       | 
          ELSE end_of_stmt 
          { 
                Block bl = end_block(); 
-               tmp_blocks.Push(bl); 
+               tmp_blocks.Push(bl); 
                start_block();
          }
          opt_statement_list
-         END IF        
+         opt_end_block 
          {
                Location l = (Location) oob_stack.Pop ();
+               int i = (int)$5;
+               if (end_priority[3]>=end_priority[i] && i!=3)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=3 && Parent!=3) 
+                       {
+                               Report.Error(30081,l,"'If' is not having a matching 'EndIf'"); 
+                               Parent = i;
+                       }
+               if(i!=3)
+                       Parent=i;
+               if(Parent==3)
+                       Parent=0;
                 tmp_expr = (Expression)expr_stack.Pop(); 
                 tmp_block = (Block) tmp_blocks.Pop(); 
                $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
          }     
-       | end_of_stmt
-         opt_statement_list 
-         ELSEIF boolean_expression opt_then 
+       |       
+         opt_elseif boolean_expression opt_then 
          { 
-               tmp_expr = (Expression) $4;                                                  
+               tmp_expr = (Expression) $2;                                                  
                 expr_stack.Push(tmp_expr);                                                 
                tmp_block = end_block();
                 tmp_blocks.Push(tmp_block);
                start_block();
          }
-         else_if_statement_rest 
+         end_of_stmt opt_statement_list        
+         else_if_statement_rest
          {
                Statement stmt = (Statement) statement_stack.Pop();
                 Block bl = (Block) tmp_blocks.Pop();  
@@ -2936,18 +3681,7 @@ if_statement_rest
        
        
 else_if_statement_rest
-       : end_of_stmt
-         opt_statement_list 
-         END IF
-         { 
-               Location l = (Location) oob_stack.Pop ();
-               oob_stack.Push (l);
-               Expression expr = (Expression)expr_stack.Pop(); 
-                Statement stmt = (Statement) new If ((Expression) expr, (Statement)  end_block(), l);
-                statement_stack.Push(stmt);
-         }
-       | end_of_stmt
-         opt_statement_list
+       :
          ELSE end_of_stmt 
          { 
                Block bl = end_block();
@@ -2955,25 +3689,40 @@ else_if_statement_rest
                start_block();
          }
          opt_statement_list
-         END IF        
+         opt_end_block 
          {
                Location l = (Location) oob_stack.Pop ();
+               int i = (int)$5;
+               if (end_priority[3]>=end_priority[i] && i!=3)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=3 && Parent!=3) 
+                       {
+                               Report.Error(30081,l,"'If' is not having a matching 'EndIf'"); 
+                               Parent = i;
+                       }
+               if(i!=3)
+                       Parent=i;
+               if(Parent==3)
+                       Parent=0;
                oob_stack.Push (l);
                Expression expr = (Expression)expr_stack.Pop(); 
                Block bl = (Block)tmp_blocks.Pop(); 
                 Statement stmt = (Statement) new If ((Expression) expr,  (Statement) bl , (Statement)  end_block(), l);
                 statement_stack.Push(stmt);
          }     
-       | end_of_stmt
-         opt_statement_list 
-         ELSEIF boolean_expression opt_then 
+       | 
+         opt_elseif boolean_expression opt_then 
          { 
-                expr_stack.Push((Expression) $4);                                                 
+                expr_stack.Push((Expression) $2);                                                 
                Block bl = end_block();
                 tmp_blocks.Push(bl);
                start_block();
          }
-         else_if_statement_rest 
+         end_of_stmt opt_statement_list        
+         else_if_statement_rest
          {
                Location l = (Location) oob_stack.Pop ();
                oob_stack.Push (l);
@@ -2983,19 +3732,60 @@ else_if_statement_rest
                Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
                 statement_stack.Push(stmt);
          }          
+        |
+         opt_end_block
+         {
+               Location l = (Location) oob_stack.Pop ();
+               int i = (int)$1;
+               if (end_priority[3]>=end_priority[i] && i!=3)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+               if (i!=3 && Parent!=3) 
+                       {
+                               Report.Error(30081,l,"'If' is not having a matching 'EndIf'"); 
+                               Parent = i;
+                       }
+               if(i!=3)
+                       Parent=i;
+               if(Parent==3)
+                       Parent=0;
+               oob_stack.Push (l);
+               Expression expr = (Expression)expr_stack.Pop(); 
+                Statement stmt = (Statement) new If ((Expression) expr, (Statement)  end_block(), l);
+                statement_stack.Push(stmt);
+         }
        ;
-       
+
+/*FIXME:Select without an expression is showing a parser error instead of a expression missing error*/ 
 select_statement
-       : SELECT opt_case expression end_of_stmt
+       : SELECT 
+         _mark_ opt_case expression end_of_stmt
          { 
                oob_stack.Push (lexer.Location);
                switch_stack.Push (current_block);
          }     
          opt_case_sections
-         END SELECT 
-         {
-               $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
+         opt_end_block
+          {
+                int i = (int)$8;
+               if (end_priority[17]>=end_priority[i] && i!=17)
+                       {
+                               Report.Error(error_numbers[i],lexer.Location,"'"+end_blocks[i]+"' found without a matching '"+open_blocks[i]+"'"+open_blocks[20]);
+                               Environment.Exit(1);
+                       }
+                if (i!=17 && Parent!=17)
+                        {
+                                Report.Error(30095,(Location)$2,"'Select' is not having a matching 'End Select'");
+                                Parent = i;
+                        }
+                if(i!=17)
+                        Parent=i;
+                if(Parent==17)
+                        Parent=0;
                current_block = (Block) switch_stack.Pop ();
+               $$ = new Switch ((Expression) $4, (ArrayList) $7, (Location) oob_stack.Pop ());
          }       
        ;
 
@@ -3044,7 +3834,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.) 
@@ -3073,10 +3863,15 @@ case_section
 case_clauses
        : case_clause
          {
-               ArrayList labels = new ArrayList ();
+                if ($1 is ArrayList) //From expression TO expression 
+                         $$ = $1;
+               else {
 
-               labels.Add ($1);
-               $$ = labels;
+                       ArrayList labels = new ArrayList ();
+
+                       labels.Add ($1);
+                       $$ = labels;
+               }
          }     
        | case_clauses COMMA case_clause
          {
@@ -3093,6 +3888,25 @@ case_clause
          {
                $$ = new SwitchLabel ((Expression) $1, lexer.Location);
          }
+       | expression TO expression
+        {
+               //FIXME: need to handle when expressions are character strings.
+                       Constant start = (Constant) $1;
+                       Constant end = (Constant) $3;
+                       int i = 0, s = 0, e = 0;
+                       Location l = lexer.Location ;
+                       ArrayList labels = new ArrayList ();
+
+                       if (start != null) 
+                               s = (int) start.GetValue ();
+                       if(end != null) 
+                               e = (int) end.GetValue ();
+                       for(i = s; i <= e; i++) {
+                               labels.Add(new SwitchLabel ((Expression)new IntLiteral(i), l));
+                       }
+                       $$ = labels;
+        }
+
        ;
        
 opt_is 
@@ -3128,18 +3942,18 @@ statement_expression
        ;
 
 object_creation_expression
-       : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
+       : NEW type OPEN_PARENS _mark_ opt_argument_list CLOSE_PARENS
          {
-               $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
+               $$ = new New ((Expression) $2, (ArrayList) $5, (Location)$4);
          }
-       | NEW type
+       | NEW type _mark_
          {
-               $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
+               $$ = new New ((Expression) $2, new ArrayList(), (Location)$3);
          }
        ;
        
 array_creation_expression
-       : object_creation_expression array_initializer
+       : object_creation_expression opt_rank_specifiers array_initializer
          {
                New n = (New) $1;
                ArrayList dims = new ArrayList();
@@ -3152,7 +3966,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;
        
@@ -3163,42 +3980,29 @@ 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 + "'");
          }
        ;       
 
-/*delegate_creation_expression
-       : NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
-         {
-           ArrayList args = new ArrayList();
-               Argument arg = new Argument ((Expression) $5, Argument.AType.Expression);
-               args.Add (arg);
-         
-               New n = new New ((Expression) $2, (ArrayList) args, lexer.Location);
-               $$ = n;
-         }
-       ;*/
-
 new_expression
        : object_creation_expression
        | array_creation_expression
-       //| delegate_creation_expression
        ;
 
 declaration_statement
-       : local_variable_declaration 
+       : _mark_ local_variable_declaration 
          {
-               if ($1 != null){
-                       DictionaryEntry de = (DictionaryEntry) $1;
+               if ($2 != null){
+                       DictionaryEntry de = (DictionaryEntry) $2;
 
-                       $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
+                       $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, (Location)$1);
                }
          }
        | local_constant_declaration 
          {
-               if ($1 != null){
+               if ($1!= null){
                        DictionaryEntry de = (DictionaryEntry) $1;
 
                        $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
@@ -3207,9 +4011,9 @@ declaration_statement
        ;        
        
 local_variable_declaration
-       : DIM variable_declarators
+       : DIM _mark_ variable_declarators 
          {
-               $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);             
+               $$ = new DictionaryEntry (DecomposeQI("_local_vars_", (Location)$2), $3);               
          }
        ;
 
@@ -3244,33 +4048,32 @@ constant_declarators
        ;
 
 constant_declarator
-       : variable_name opt_type_decl opt_variable_initializer
+       : _mark_ variable_name opt_type_decl opt_variable_initializer
          {
-               VarName vname = (VarName) $1;
+               VarName vname = (VarName) $2;
                string varname = (string) vname.Name;
                current_rank_specifiers = (ArrayList) vname.Rank;
-               object varinit = $3;
-               ArrayList a_dims = null;
+               object varinit = $4;
 
                if (varinit == null)
                        Report.Error (
-                               30438, lexer.Location, "Constant should have a value"
+                               30438, (Location)$1, "Constant should have a value"
                                );
 
-               if (vname.Type != null && $2 != null)
+               if (vname.Type != null && $3 != null)
                        Report.Error (
-                               30302, lexer.Location
+                               30302, (Location)$1
                                "Type character cannot be used with explicit type declaration" );
 
-               Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
+               Expression vartype = ($3 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $3;
 
                if (current_rank_specifiers != null) 
                {
-                       Report.Error (30424, lexer.Location, "Constant doesn't support array");
+                       Report.Error (30424, (Location)$1, "Constant doesn't support array");
                        $$ = null;
                }
                else
-                       $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
+                       $$ = new VariableDeclaration (varname, vartype, varinit, (Location)$1, null);
          }
        ;               
 
@@ -3290,17 +4093,17 @@ variable_declarators
        ;
 
 variable_declarator
-       : variable_names opt_type_decl opt_variable_initializer
+       : _mark_ variable_names opt_type_decl opt_variable_initializer
          {
-           ArrayList names = (ArrayList) $1;
-               object varinit = $3;
+           ArrayList names = (ArrayList) $2;
+               object varinit = $4;
                ArrayList VarDeclarations = new ArrayList();
                Expression vartype;
                ArrayList a_dims = null;
 
                if ((names.Count > 1) && (varinit != null)) 
                        Report.Error (
-                               30671, lexer.Location
+                               30671, (Location)$1
                                "Multiple variables with single type can not have " +
                                "a explicit initialization" );
 
@@ -3310,43 +4113,34 @@ variable_declarator
                        string varname = (string) vname.Name;
                        current_rank_specifiers = (ArrayList) vname.Rank;
                        a_dims = null;
-                       varinit = $3;
+                       varinit = $4;
 
-                       if(vname.Type != null && $2 != null)
+                       if(vname.Type != null && $3 != null)
                                Report.Error (
-                                       30302, lexer.Location
+                                       30302, (Location)$1
                                        "Type character cannot be used with explicit type declaration" );
 
                        // Some checking is required for particularly weird declarations
                        // like Dim a As Integer(,)
-                       if ($2 is Pair) {
-                               vartype = (Expression) ((Pair) $2).First;
+                       if ($3 is Pair) {
+                               vartype = (Expression) ((Pair) $3).First;
                                
-                               /*if ($3 != null && $3 is ArrayList)
+                               /*if ($4 != null && $4 is ArrayList)
                                        Report.Error (205, "End of statement expected.");*/
                                        
-                               ArrayList args = (ArrayList) ((Pair) $2).Second;
+                               ArrayList args = (ArrayList) ((Pair) $3).Second;
                                if (current_rank_specifiers != null)
-                                       Report.Error (31087, lexer.Location,
+                                       Report.Error (31087, (Location)$1,
                                                 "Array types specified in too many places");   
                                
                                if (VariableDeclaration.IndexesSpecifiedInRank (args))            
                                        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;
+                               vartype = ($3 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $3;
 
                        // if the variable is an array with explicit bound
                        // and having explicit initialization throw exception
@@ -3360,7 +4154,7 @@ variable_declarator
                                                if (!((Expression)expr is EmptyExpression ))
                                                {
                                                        Report.Error (
-                                                               30672, lexer.Location
+                                                               30672, (Location)$1
                                                                "Array declared with explicit bound " +
                                                                " can not have explicit initialization");
                                                        broken = true;
@@ -3381,14 +4175,14 @@ variable_declarator
                                if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {   
                                        a_dims = (ArrayList) current_rank_specifiers;
                                        VariableDeclaration.VBFixIndexLists (ref a_dims);
-                                       varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
+                                       varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, (Location)$1);
                                }
-                               vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
+                               vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, (Location)$1), (Location)$1);
                        }
 
                        if (vartype is New) {
                                if (varinit != null) {
-                                       Report.Error (30205, lexer.Location, "End of statement expected");
+                                       Report.Error (30205, (Location)$1, "End of statement expected");
                                        $$ = null;
                                }
                                else
@@ -3397,7 +4191,7 @@ variable_declarator
                                        vartype = ((New)vartype).RequestedType;
                                }
                        }
-                       VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
+                       VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, (Location)$1, null));
            }// end of for
            $$ = VarDeclarations;
          } 
@@ -3440,19 +4234,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);
@@ -3555,81 +4345,60 @@ 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;                
+         }     
        ;
        
-/* Expressions */
 primary_expression
        : literal
          {
-               // 7.5.1: Literals
+               //TODO
          }
-
+       | parenthesized_expression
+       | this_access
+       | base_access
        | qualified_identifier
          {
                string name = (string) $1;
                $$ = DecomposeQI (name, lexer.Location);
          }
-       | parenthesized_expression
+       | get_type_expression
        | member_access
        | invocation_expression
        //| element_access
-       | this_access
-       | base_access
        | new_expression
        | cast_expression
+       | /*empty*/ _mark_ 
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
 
 literal
@@ -3659,7 +4428,7 @@ integer_literal
                else if (v is long)
                        $$ = new LongLiteral ((Int64)v);
                else
-                       Console.WriteLine ("OOPS.  Unexpected result from scanner");
+                       Console.WriteLine ("Unexpected result from scanner");
                        
          }
        ;
@@ -3716,21 +4485,41 @@ member_access
                }
          }
        ;
-
+       
 predefined_type
        : builtin_types
        ;
 
 invocation_expression
-       : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
+       : primary_expression OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
          {
                if ($1 == null) {
-                       Location l = lexer.Location;
+                       Location l = (Location)$4;
                        Report.Error (1, l, "THIS IS CRAZY");
                }
-               $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
+               $$ = new Invocation ((Expression) $1, (ArrayList) $3, (Location)$4);
 //             Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
-         } 
+         }
+
+// To support Mid$()
+       | primary_expression DOLAR_SIGN OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
+         {
+               if ($1 == null) {
+                       Location l = (Location)$5;
+                       Report.Error (1, l, "THIS IS CRAZY");
+               }
+               $$ = new Invocation ((Expression) $1, (ArrayList) $4, (Location)$5);
+               // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($4 != null) ? ((ArrayList) $4).Count : 0);
+         }
+       | CALL primary_expression OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
+         {
+               if ($2 == null) {
+                       Location l = (Location)$5;
+                       Report.Error (1, l, "THIS IS CRAZY");
+               }
+               $$ = new Invocation ((Expression) $2, (ArrayList) $3, (Location)$5);
+//             Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
+         }
        ;
        
 base_access
@@ -3805,16 +4594,11 @@ variable_reference
        : expression {/* note ("section 5.4"); */  $$ = $1;  }
        ;
 
-negation_expression
-       : NOT expression 
-         {
-               $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
-         }
-       ;
                
 expression
-       : conditional_expression { $$ = $1; }
-       | negation_expression
+       : conditional_xor_expression { $$ = $1; } 
+       | /*empty*/ _mark_
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        /*| assignment_expression*/
        ;
 
@@ -3836,24 +4620,19 @@ this_access
          }
        ;
 
-unary_expression
-       : primary_expression
-       /*| NOT prefixed_unary_expression
-         {
-               $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
-         }
-       | cast_expression */
-       ;
-       
 cast_expression
-        : cast_operator OPEN_PARENS expression CLOSE_PARENS
+        : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
          {
-                 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
-         }     
+               // TODO
+         } 
        | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
          {
                  $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
-         }                       
+         }     
+        | cast_operator OPEN_PARENS expression CLOSE_PARENS
+         {
+                 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
+         }     
        ;
        
 cast_operator
@@ -3868,246 +4647,316 @@ cast_operator
        | COBJ          { $$ = TypeManager.system_object_expr;          }
        | CSHORT        { $$ = TypeManager.system_int16_expr;           }
        | CSNG          { $$ = TypeManager.system_single_expr;          }
-       | CSTR          { $$ = TypeManager.system_string_expr;  }
+       | CSTR          { $$ = TypeManager.system_string_expr;          }
+       ;
+
+get_type_expression
+       : GETTYPE _mark_ OPEN_PARENS type CLOSE_PARENS
+         {
+               $$ = new TypeOf ((Expression) $4, (Location)$2);
+         }
+       | /*empty*/ _mark_
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
+       ;
+       
+exponentiation_expression
+       : primary_expression
+       | exponentiation_expression OP_EXP _mark_ primary_expression
+         {
+               $$ = new Exponentiation ((Location)$3, (Expression) $1, (Expression) $4);
+         }                             
+       | /*empty*/ _mark_
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
        
-       //
-       // The idea to split this out is from Rhys' grammar
-       // to solve the problem with casts.
-       //
 prefixed_unary_expression
-       : unary_expression
-       | PLUS prefixed_unary_expression
+       : exponentiation_expression
+       | PLUS _mark_ prefixed_unary_expression
          {
-               $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $3, (Location)$2);
          }
-       | MINUS prefixed_unary_expression
+       | MINUS _mark_ prefixed_unary_expression
          {
-               $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $3, (Location)$2);
          }
+       | /*empty*/ _mark_  
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
 
 multiplicative_expression
        : prefixed_unary_expression
-       | multiplicative_expression STAR prefixed_unary_expression
+       | multiplicative_expression _mark_ STAR prefixed_unary_expression
          {
                $$ = new Binary (Binary.Operator.Multiply,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | multiplicative_expression DIV prefixed_unary_expression
+       | multiplicative_expression _mark_ DIV prefixed_unary_expression
          {
                $$ = new Binary (Binary.Operator.Division,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | multiplicative_expression OP_IDIV prefixed_unary_expression
-         {
-               $$ = new Binary (Binary.Operator.Division,
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }       
-       | multiplicative_expression MOD prefixed_unary_expression
+       | /*empty*/ _mark_ 
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
+       ;
+
+integer_division_expression
+       : multiplicative_expression
+       | integer_division_expression _mark_ OP_IDIV multiplicative_expression
+          {
+               //FIXME: Is this right ?
+               $$ = new Binary (Binary.Operator.IntDivision,
+                          (Expression) $1, (Expression) $4, (Location)$2);
+          }
+       | /*empty*/ _mark_ 
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
+       ;
+
+mod_expression
+       : integer_division_expression
+       | mod_expression _mark_ MOD integer_division_expression
          {
-               $$ = new Binary (Binary.Operator.Modulus,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+             $$ = new Binary (Binary.Operator.Modulus,
+                              (Expression) $1, (Expression) $4, (Location)$2);
          }
+       | /*empty*/ _mark_  
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
-
+       
 additive_expression
-       : multiplicative_expression
-       | additive_expression PLUS multiplicative_expression
+       : mod_expression
+       | additive_expression _mark_ PLUS mod_expression
          {
                $$ = new Binary (Binary.Operator.Addition,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | additive_expression MINUS multiplicative_expression
+       | additive_expression _mark_ MINUS mod_expression
          {
                $$ = new Binary (Binary.Operator.Subtraction,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | additive_expression OP_CONCAT multiplicative_expression
+       | /*empty*/ _mark_  
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
+       ;
+
+concat_expression
+       : additive_expression
+       | concat_expression _mark_ OP_CONCAT additive_expression
+          {
+             // FIXME: This should only work for String expressions
+             // We probably need to use something from the runtime
+             $$ = new StringConcat((Location)$2,
+                              (Expression) $1, (Expression) $4);
+         }     
+       | /*empty*/ _mark_ 
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
+       ;
+
+
+shift_expression
+       : concat_expression
+       | shift_expression _mark_ OP_SHIFT_LEFT concat_expression
          {
-               // FIXME: This should only work for String expressions
-               // We probably need to use something from the runtime
-               $$ = new Binary (Binary.Operator.Addition,
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }       
+               $$ = new Binary(Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, (Location)$2);
+         }
+       | shift_expression _mark_ OP_SHIFT_RIGHT concat_expression
+         {
+               $$ = new Binary(Binary.Operator.RightShift, (Expression) $1, (Expression) $4, (Location)$2);
+         }
+       | /*empty*/ _mark_  
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
 
 relational_expression
-       : additive_expression
-       | relational_expression OP_LT additive_expression
+       : shift_expression
+       | relational_expression _mark_ ASSIGN shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Equality,
+                                (Expression) $1, (Expression) $4, (Location)$2);
+         }
+       | relational_expression _mark_ OP_NE shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Inequality, 
+                                (Expression) $1, (Expression) $4, (Location)$2);
+         }       
+       | relational_expression _mark_ OP_LT shift_expression
          {
                $$ = new Binary (Binary.Operator.LessThan,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | relational_expression OP_GT additive_expression
+       | relational_expression _mark_ OP_GT shift_expression
          {
                $$ = new Binary (Binary.Operator.GreaterThan,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | relational_expression OP_LE additive_expression
+       | relational_expression _mark_ OP_LE shift_expression
          {
                $$ = new Binary (Binary.Operator.LessThanOrEqual,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | relational_expression OP_GE additive_expression
+       | relational_expression _mark_ OP_GE shift_expression
          {
                $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | relational_expression IS unary_expression
+       | relational_expression _mark_ IS shift_expression
          {
-               $$ = new Binary (Binary.Operator.Equality,
-                       (Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Binary (Binary.Operator.Is,
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | relational_expression AS type_name
+       | TYPEOF _mark_ shift_expression IS type
          {
-               $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Is ((Expression) $3, (Expression) $5, (Location)$2);
          }
+       | /*empty*/ _mark_ 
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
 
-equality_expression
+negation_expression
        : relational_expression
-       | equality_expression ASSIGN relational_expression
-         {
-               $$ = new Binary (Binary.Operator.Equality,
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }
-       | equality_expression OP_NE relational_expression
-         {
-               $$ = new Binary (Binary.Operator.Inequality, 
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }       
-       ;
-
-and_expression
-       : equality_expression
-       | and_expression AND equality_expression
-         {
-               $$ = new Binary (Binary.Operator.BitwiseAnd,
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }
-       ;
-
-exclusive_or_expression
-       : and_expression
-       | exclusive_or_expression OP_XOR and_expression
+       | NOT _mark_ negation_expression 
          {
-               $$ = new Binary (Binary.Operator.ExclusiveOr,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $3, (Location)$2);
          }
+       | /*empty*/ _mark_  
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
-
+       
 conditional_and_expression
-       : exclusive_or_expression
-       | conditional_and_expression AND exclusive_or_expression
+       : negation_expression
+       | conditional_and_expression _mark_ AND negation_expression
          {
-               $$ = new Binary (Binary.Operator.LogicalAnd,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Binary (Binary.Operator.BitwiseAnd,
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | conditional_and_expression ANDALSO exclusive_or_expression
+       | conditional_and_expression _mark_ ANDALSO negation_expression
          {     // FIXME: this is likely to be broken
                $$ = new Binary (Binary.Operator.LogicalAnd,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
+       | /*empty*/ _mark_  
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
 
 conditional_or_expression
        : conditional_and_expression
-       | conditional_or_expression OR conditional_and_expression
+       | conditional_or_expression _mark_ OR conditional_and_expression
          {
-               $$ = new Binary (Binary.Operator.LogicalOr,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Binary (Binary.Operator.BitwiseOr,
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
-       | conditional_or_expression ORELSE conditional_and_expression
+       | conditional_or_expression _mark_ ORELSE conditional_and_expression
          {     // FIXME: this is likely to be broken
                $$ = new Binary (Binary.Operator.LogicalOr,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$2);
          }
+       | /*empty*/ _mark_  
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
 
-conditional_expression
+conditional_xor_expression
        : conditional_or_expression
+       | conditional_xor_expression _mark_ XOR conditional_or_expression
+       {
+             $$ = new Binary (Binary.Operator.ExclusiveOr,
+                              (Expression) $1, (Expression) $4, (Location)$2);
+       }
+       | /* empty */ _mark_
+                                            { Report.Error(30201,(Location)$1,"Expression expected"); }
        ;
 
 assignment_expression
-       : prefixed_unary_expression ASSIGN expression
+       : prefixed_unary_expression _mark_ ASSIGN expression
          { 
-               $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$2);
          }
-       | prefixed_unary_expression ASSIGN ADDRESSOF expression
-         { 
-           ArrayList args = new ArrayList();
-               Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
-               args.Add (arg);
-               
-               New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
-               n.isDelegate = true;
-               $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
+       | prefixed_unary_expression _mark_ STAR ASSIGN expression
+         {
+               Location l = (Location)$2;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Multiply, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_MULT_ASSIGN expression
+       | prefixed_unary_expression _mark_ DIV ASSIGN expression
          {
-               Location l = lexer.Location;
+               Location l = (Location)$2;
 
                $$ = new CompoundAssign (
-                       Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
+                       Binary.Operator.Division, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_DIV_ASSIGN expression
+       | prefixed_unary_expression _mark_ PLUS ASSIGN expression
          {
-               Location l = lexer.Location;
+               Location l = (Location)$2;
 
                $$ = new CompoundAssign (
-                       Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_IDIV_ASSIGN expression
+       | prefixed_unary_expression _mark_ MINUS ASSIGN expression
          {
-               Location l = lexer.Location;
+               Location l = (Location)$2;
 
                $$ = new CompoundAssign (
-                       Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
-         }       
-       | prefixed_unary_expression OP_ADD_ASSIGN expression
+                       Binary.Operator.Subtraction, (Expression) $1, (Expression) $5, l);
+         }
+       | prefixed_unary_expression _mark_ OP_SHIFT_LEFT ASSIGN expression
          {
-               Location l = lexer.Location;
+               Location l = (Location)$2;
 
                $$ = new CompoundAssign (
-                       Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
+                       Binary.Operator.LeftShift, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_SUB_ASSIGN expression
+       | prefixed_unary_expression _mark_ OP_SHIFT_RIGHT ASSIGN expression
          {
-               Location l = lexer.Location;
+               Location l = (Location)$2;
 
                $$ = new CompoundAssign (
-                       Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
+                       Binary.Operator.RightShift, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_CONCAT_ASSIGN expression
+       | prefixed_unary_expression _mark_ OP_CONCAT ASSIGN expression
          {
-               Location l = lexer.Location;
+               Location l = (Location)$2;
 
+               // FIXME should be strings only
                $$ = new CompoundAssign (
-                       Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
-         }               
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
+         }
+       | prefixed_unary_expression _mark_ OP_EXP ASSIGN expression
+         {
+               /*Location l = (Location)$2;
+
+                TODO: $$ = new CompoundAssign (
+                       Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $5, l); */
+         }
+       | prefixed_unary_expression _mark_ ASSIGN ADDRESSOF expression
+         { 
+           ArrayList args = new ArrayList();
+               Argument arg = new Argument ((Expression) $5, Argument.AType.Expression);
+               args.Add (arg);
+               
+               New n = new New ((Expression) $1, (ArrayList) args, (Location)$2);
+               n.isDelegate = true;
+               $$ = new Assign ((Expression) $1, (Expression) n, (Location)$2);
+         }
        ;
 
-/*constant_expression
+constant_expression
        : expression
        ;
-*/
 
 boolean_expression
        : expression
        ;
 
 type
-       : type_name {   /* class_type */
-               /*
-                  This does interfaces, delegates, struct_types, class_types,
-                  parent classes, and more! 4.2
-                */
+       : namespace_or_type_name 
+         {     
                $$ = DecomposeQI ((string) $1, lexer.Location); 
          }
        | builtin_types 
-       /*| array_type 
-        | pointer_type */
+       //| array_type 
        ;
 
 type_list
@@ -4127,46 +4976,50 @@ type_list
          }
        ;
 
-type_name
-       : namespace_or_type_name
-       ;
-       
 namespace_or_type_name
        : qualified_identifier
        ;
 
-/* Built-in / Integral types */
 builtin_types
        : OBJECT        { $$ = TypeManager.system_object_expr; }
-       | STRING        { $$ = TypeManager.system_string_expr; }
+       | primitive_type
+       ;
+
+primitive_type
+       : numeric_type
        | BOOLEAN       { $$ = TypeManager.system_boolean_expr; }
-       | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
-       | SINGLE        { $$ = TypeManager.system_single_expr; }
-       | DOUBLE        { $$ = TypeManager.system_double_expr; }
        | DATE          { $$ = TypeManager.system_date_expr; }
-       | integral_type
+       | CHAR          { $$ = TypeManager.system_char_expr; }
+       | STRING        { $$ = TypeManager.system_string_expr; }
+       ;
+       
+
+numeric_type
+       : integral_type
+       | floating_point_type
+       | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
        ;
 
 integral_type
        :
        | BYTE          { $$ = TypeManager.system_byte_expr; }
        | SHORT         { $$ = TypeManager.system_int16_expr; }
-       | LONG          { $$ = TypeManager.system_int64_expr; }
        | INTEGER       { $$ = TypeManager.system_int32_expr; }
-       | CHAR          { $$ = TypeManager.system_char_expr; }
-       ;
-
-interface_type
-       : type_name
+       | LONG          { $$ = TypeManager.system_int64_expr; }
        ;
        
+floating_point_type
+       : SINGLE        { $$ = TypeManager.system_single_expr; }
+       | DOUBLE        { $$ = TypeManager.system_double_expr; }
+       ;
+
 pp_directive
-       : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
+       : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS _mark_ EOL
          { 
                if(tokenizerController.IsAcceptingTokens)
                {
                        if(in_external_source) 
-                               Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
+                               Report.Error (30580, (Location)$8, "#ExternalSource directives may not be nested");
                        else {
                                in_external_source = true;
                        
@@ -4175,27 +5028,25 @@ pp_directive
                        }
                }
          }
-       | HASH IDENTIFIER LITERAL_STRING EOL
+       | HASH IDENTIFIER LITERAL_STRING _mark_ EOL
          {
                if(tokenizerController.IsAcceptingTokens) 
                {
-                       string id = ($2 as string);
-               
                        if(!($2 as string).ToLower().Equals("region"))
-                               Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
+                               Report.Error (30205, (Location)$4, "Invalid Pre-processor directive");
                        else
                        {
                                ++in_marked_region;
                        }
                }
          }
-       | HASH END IDENTIFIER EOL
+       | HASH END IDENTIFIER _mark_ EOL
          {
                if(tokenizerController.IsAcceptingTokens)
                {
                        if( ($3 as string).ToLower().Equals("externalsource")) {
                                if(!in_external_source)
-                                       Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
+                                       Report.Error (30578, (Location)$4, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
                                else {
                                        in_external_source = false;
                                        lexer.EffectiveSource = lexer.Source;
@@ -4206,21 +5057,22 @@ pp_directive
                                if(in_marked_region > 0)
                                        --in_marked_region;
                                else
-                                       Report.Error (30205, lexer.Location, "'#End Region' must be preceded  by a matching '#Region'");
+                                       Report.Error (30205, (Location)$4, "'#End Region' must be preceded  by a matching '#Region'");
                        }
                        else {
-                               Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
+                               Report.Error (29999, (Location)$4, "Unrecognized Pre-Processor statement");
                        }       
                }
          }
-       | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
+       | HASH CONST IDENTIFIER ASSIGN boolean_literal _mark_ EOL
          {
                if(tokenizerController.IsAcceptingTokens)
                {
                        //TODO;
+                       //FIXME;
                }
          }
-       | HASH IF 
+       | HASH IF _mark_   
          {
                IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
 
@@ -4228,65 +5080,130 @@ pp_directive
                        ifElseStateMachine.HandleToken(tok);
                }
                catch(ApplicationException) {
-                       throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                       throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
                }
          }
           boolean_literal opt_then  EOL 
          {
-               HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
+               HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$5);
          }
-       | HASH ELSEIF 
+       | HASH opt_elseif _mark_ 
          {
                      IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
                      try {
                              ifElseStateMachine.HandleToken(tok);
                      }
                      catch(ApplicationException) {
-                             throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                             throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
                      }
          }
           boolean_literal opt_then  EOL 
          { 
-                 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
+                 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$5);
          }
-       | HASH ELSE  
+       | HASH ELSE _mark_ 
          {
                    IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
                    try {
                            ifElseStateMachine.HandleToken(tok);
                    }
                    catch(ApplicationException) {
-                           throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                           throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
                    }
          }
          EOL 
          { 
                HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
          }
-       | HASH END IF  
+       | HASH END IF _mark_ 
          {
+               /*FIXME: IF without ENDIF not working properly. Error line is not diplayed properly*/
+       
                  IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
                  try {
                          ifElseStateMachine.HandleToken(tok);
                  }
                  catch(ApplicationException) {
-                         throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                         throw new MBASException(ifElseStateMachine.Error, (Location)$4, ifElseStateMachine.ErrString);
                  }
          }
          EOL 
          { 
                HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
          }
-       | HASH error EOL          
+       | HASH error _mark_ EOL   
        {
                if(tokenizerController.IsAcceptingTokens)
-                       Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
+                       Report.Error(29999, (Location)$3, "Unrecognized Pre-Processor statement");
                else
-                       Report.Warning (9999, lexer.Location,   "Unrecognized Pre-Processor statement");
+                       Report.Warning (29999, (Location)$3,"Unrecognized Pre-Processor statement");
        }
          
        ;               
 
+// Utility rule to save location information
+_mark_
+        : /* empty */
+        { $$ = lexer.Location; if (yyToken == Token.EOL) { $$ = new Location (lexer.Location.Row - 1, lexer.Location.Col); } }
+       ;
+
+// Changed to accept "Else If" also along with "ElseIf" 
+opt_elseif
+        : ELSEIF
+        | ELSE IF
+       ;
+
+// Changed so as to check if every block is closed or not... 
+opt_end_block
+       : END opt_block_types 
+         {
+               $$ = 2 + (int)$2 ;
+         }
+       | NEXT
+         {$$ = 1;}
+       | LOOP
+         {$$ = 2;}
+       | /* empty */ 
+         {$$ = 0;} 
+       ;
+
+opt_block_types
+       : IF
+         {$$ = 1;}
+       | SUB
+         {$$ = 2;}
+       | MODULE
+         {$$ = 3;}
+       | NAMESPACE
+         {$$ = 4;}
+       | CLASS
+         {$$ = 5;}
+       | FUNCTION 
+         {$$ = 6;}
+       | STRUCTURE 
+         {$$ = 7;}
+       | ENUM
+         {$$ = 8;}
+       | INTERFACE 
+         {$$ = 9;}
+       | PROPERTY 
+         {$$ = 10;}
+       | WITH 
+         {$$ = 11;}
+       | SYNCLOCK
+         {$$ = 12;}
+       | TRY 
+         {$$ = 13;}
+       | WHILE 
+         {$$ = 14;}
+       | SELECT 
+         {$$ = 15;}
+       | SET 
+         {$$ = 16;}
+       | GET 
+         {$$ = 17;}
+       ;
+
 %%
 
 
@@ -4346,7 +5263,7 @@ Block declare_local_variables (Expression dummy_type, ArrayList variable_declara
 
        foreach (VariableDeclaration decl in variable_declarators){
                Expression type = decl.type;
-               if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
+               if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, loc) != null) {
                        if (decl.expression_or_array_initializer != null){
                                if (inits == null)
                                        inits = new ArrayList ();
@@ -4538,23 +5455,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;
        }       
@@ -4589,7 +5526,6 @@ public class VariableDeclaration {
                
        public static void FixupArrayTypes (ArrayList vars)
        {
-               int varcount =  vars.Count;
                string dims;
                
                foreach (VariableDeclaration var in vars) {
@@ -4660,9 +5596,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)
@@ -4679,13 +5615,14 @@ 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);
+       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)
@@ -4697,13 +5634,14 @@ 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)
 {
        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>
@@ -4723,9 +5661,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)
@@ -4783,6 +5721,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;
@@ -4793,9 +5736,8 @@ protected override int parse ()
        ifElseStateMachine = new IfElseStateMachine();
        tokenizerController = new TokenizerController(lexer);
        
-       StringBuilder value = new StringBuilder ();
        try {
-               if (yacc_verbose_flag)
+               if (yacc_verbose_flag > 0)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
                else {
                        yyparse (lexer);
@@ -4806,7 +5748,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();