Switch to compiler-tester
[mono.git] / mcs / mbas / mb-parser.jay
index 52ce3aa0e51e106142a801df891f6d140a65bcc0..dd573f538a89f1306f0d0e0627c9316089d66847 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;
@@ -21,6 +23,18 @@ namespace Mono.MonoBASIC
        using Mono.Languages;
        using Mono.MonoBASIC;
 
+       public class MBASException : ApplicationException
+       {
+               public int code;
+               public Location loc;
+
+               public MBASException(int code, Location loc, string text) : base(text)
+               {
+                       this.code = code;
+                       this.loc = loc;
+               }
+       }
+
        /// <summary>
        ///    The MonoBASIC Parser
        /// </summary>
@@ -29,6 +43,7 @@ namespace Mono.MonoBASIC
        {
        
 
+
                /// <summary>
                ///   Current block is used to add statements as we find
                ///   them.  
@@ -110,14 +125,111 @@ 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 proceeding further
+               // if it comes acorss error.
+
+               // Used to store
+               //      1) The value for corresponding blocks with which it will be accessed...
+               // In case of any more addition to end of blocks... add it at the end   
+               
+               public enum Start_block {
+                               NOTHING,
+                               FOR,
+                               DO,
+                               IF,
+                               SUB,
+                               MODULE,
+                               NAMESPACE,
+                               CLASS,
+                               FUNCTION,
+                               STRUCTURE,
+                               ENUM,
+                               INTERFACE,
+                               PROPERTY,
+                               WITH,
+                               SYNCLOCK,
+                               TRY,
+                               WHILE,
+                               SELECT,
+                               SET,
+                               GET
+               }
+
+               // Used to store
+               //      1) Start of block
+               //      2) End of Block
+               // In case of any more addition to end of blocks... add it at the end   
+
+               public string[,] end_blocks = {
+                        { "empty"     , "empty"             },
+                        { "For"       , "Next"           },
+                        { "Do"        , "Loop"           },
+                        { "If"        , "End If"         },
+                        { "Sub"       , "End Sub"        },
+                        { "Module"    , "End Module"     },
+                        { "NameSpace" , "End NameSpace"  },
+                        { "Class"     , "End Class"      },
+                        { "Function"  , "End Function"   },
+                        { "Structure" , "End Structure"  },
+                        { "Enum"      , "End Enum"       },
+                        { "Interface" , "End Interface"  },
+                        { "Property"  , "End Property"   },
+                        { "With"      , "End With"       },
+                        { "SyncLock"  , "End SyncLock"   },
+                        { "Try"       , "End Try"        },
+                        { "While"     , "End While"      },
+                        { "Select"    , "End Select"     },
+                        { "Set"       , "End Set"        },
+                        { "Get"       , "End Get"        }
+                       };
+                       
+               
+               // Used to store
+               //      1) Error number for End of block missing 
+               //      2) Extra End of Block  
+               //      3) Priority for the end 0f blocks
+               // In case of any more addition to end of blocks... add it at the end   
+
+               public int[,] error_end_blocks = {
+                        { 29999 , 29999 , 0 },
+                        { 30084 , 30092 , 1 },
+                        { 30083 , 30091 , 1 },
+                        { 30081 , 30087 , 1 },
+                        { 30289 , 30429 , 3 },
+                        { 30625 , 30622 , 5 },
+                        { 30626 , 30623 , 6 },
+                        { 30481 , 30460 , 4 },
+                        { 30027 , 30430 , 3 },
+                        { 30624 , 30621 , 4 },
+                        { 30185 , 30184 , 1 },
+                        { 30253 , 30252 , 3 },
+                        { 30025 , 30431 , 3 },
+                        { 30085 , 30093 , 1 },
+                        { 30675 , 30674 , 1 },
+                        { 30384 , 30383 , 1 },
+                        { 30082 , 30090 , 1 },
+                        { 30095 , 30088 , 1 },
+                        { 30633 , 30632 , 2 },
+                        { 30631 , 30630 , 2 }
+                       };
+
+               Stack end_of_block;
+               Stack temp_block;
+               Stack loc_end_of_block;
+               Stack loc_temp_block;
+
+               Location try_top;
+
                DoOptions do_type;
                //
                // Switch stack.
@@ -128,12 +240,16 @@ namespace Mono.MonoBASIC
                Stack expr_stack; 
                
                Stack tmp_blocks;
-           Stack statement_stack;
+               Stack statement_stack;
 
                // A stack for With expressions.
                //
                Stack with_stack;
-       
+               
+               //      
+               // Hash table for const preprocessing directive
+               //
+               public static Hashtable constPreDir = new Hashtable();
                
                static public bool InitialOptionExplicit = false;
                static public bool InitialOptionStrict = false;
@@ -154,6 +270,211 @@ namespace Mono.MonoBASIC
                        return list;
                }
 
+               bool in_external_source = false;
+               int in_marked_region = 0;
+
+               TokenizerController tokenizerController;
+               IfElseStateMachine ifElseStateMachine;
+
+               
+               public class IfElseStateMachine {
+                       
+                       public enum State {
+                       START,
+                       IF_SEEN,
+                       ELSEIF_SEEN,
+                       ELSE_SEEN,
+                       ENDIF_SEEN,
+                       MAX
+                       }
+               
+                       public enum Token {
+                       START,
+                       IF,
+                       ELSEIF,
+                       ELSE,
+                       ENDIF,
+                       EOF,
+                       MAX
+                       }
+
+                       State state;
+                       Stack stateStack;
+
+                       public static Hashtable errStrings = new Hashtable();
+
+                       int err=0;
+                       static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
+               
+                       static IfElseStateMachine()
+                       {
+                               // FIXME: Fix both the error nos and the error strings. 
+                               // Currently the error numbers and the error strings are 
+                               // just placeholders for getting the state-machine going.
+
+                               errStrings.Add(0, "");
+                               errStrings.Add(30012, "#If must end with a matching #End If");
+                               errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
+                               errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
+                               errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
+                               errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
+
+                               errTable[(int)State.START, (int)Token.IF] = 0;
+                               errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
+                               errTable[(int)State.START, (int)Token.ELSE] = 30028;
+                               errTable[(int)State.START, (int)Token.ENDIF] = 30013;
+                               errTable[(int)State.START, (int)Token.EOF] = 0;
+
+                               errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
+                       }
+
+                       public IfElseStateMachine()
+                       {
+                               state = State.START;
+
+                               stateStack = new Stack();
+                               stateStack.Push(state);
+                       }
+
+                       // The parameter here need not be qualified with IfElseStateMachine
+                       // But it hits a bug in mcs. So temporarily scoping it so that builds
+                       // are not broken.
+
+                       public void HandleToken(IfElseStateMachine.Token tok)
+                       {       
+                               err = (int) errTable[(int)state, (int)tok];
+
+                               if(err != 0)
+                                       throw new ApplicationException("Unexpected pre-processor directive #"+tok); 
+                               
+                               if(tok == Token.IF) {
+                                       stateStack.Push(state);
+                                       state = (State) tok;
+                               }
+                               else if(tok == Token.ENDIF) {
+                                       state = (State)stateStack.Pop();
+                               }
+                               else
+                                       state = (State)tok;
+                       }
+
+                       public int Error {
+                               get {
+                                       return err;
+                               }
+                       }
+
+                       public string ErrString {
+                               get {
+                                       return (string) errStrings[err];
+                               }
+                       }
+               }
+
+               
+               public class TokenizerController {
+                       
+                       struct State
+                       {
+                               public bool CanAcceptTokens;
+                               public bool CanSelectBlock;
+                       }
+
+                       State currentState;
+                       Stack stateStack;
+                       Tokenizer lexer;
+
+                       public TokenizerController(Tokenizer lexer)
+                       {
+                               this.lexer = lexer;
+                               stateStack = new Stack();
+
+                               currentState.CanAcceptTokens = true;
+                               currentState.CanSelectBlock = true;
+
+                               stateStack.Push(currentState);
+                       }
+
+                       State parentState {
+                               get {
+                                       return (State)stateStack.Peek();
+                               }
+                       }
+
+                       public bool IsAcceptingTokens {
+                               get {
+                                       return currentState.CanAcceptTokens;
+                               }
+                       }
+
+                       public void PositionCursorAtNextPreProcessorDirective()
+                       {
+                               lexer.PositionCursorAtNextPreProcessorDirective();
+                       }
+
+                       public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
+                       {
+                               if(tok == IfElseStateMachine.Token.ENDIF) {
+                                       currentState = (State)stateStack.Pop();
+
+                                       if(currentState.CanAcceptTokens)
+                                               return;
+                                       else {
+                                               PositionCursorAtNextPreProcessorDirective();
+                                               return;
+                                       }
+                               }
+                               
+                               if(tok == IfElseStateMachine.Token.IF) {
+                                       stateStack.Push(currentState);
+                                       
+                                       currentState.CanAcceptTokens = parentState.CanAcceptTokens;
+                                       currentState.CanSelectBlock = true;
+                               }
+                       
+                               if(parentState.CanAcceptTokens && 
+                                   currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
+                                   
+                                   currentState.CanAcceptTokens = true;
+                                   currentState.CanSelectBlock = false; 
+                                   return;
+                               }
+                               else {
+                                       currentState.CanAcceptTokens = false;
+                                       PositionCursorAtNextPreProcessorDirective();
+                                       return;
+                               }
+                       }
+               }
+
+               bool allow_global_attribs = true;
+
+               bool expecting_global_attribs = false;
+               bool expecting_local_attribs = false;
+
+               bool local_attrib_section_added = false;
 %}
 
 %token EOF
@@ -204,12 +525,15 @@ namespace Mono.MonoBASIC
 %token DEFAULT 
 %token DELEGATE        
 %token DIM
+%token DIRECTCAST
 %token DO      
 %token DOUBLE  
 %token EACH    
 %token ELSE
 %token ELSEIF
-%token END     
+%token END
+%token END_EOL
+%token ENDIF
 %token ENUM    
 %token EOL
 %token ERASE
@@ -223,7 +547,8 @@ namespace Mono.MonoBASIC
 %token FRIEND
 %token FUNCTION
 %token GET
-//%token GETTYPE
+%token GETTYPE
+%token GOSUB
 %token GOTO    
 %token HANDLES
 %token IF      
@@ -301,6 +626,7 @@ namespace Mono.MonoBASIC
 %token UNICODE
 %token UNTIL
 %token VARIANT 
+%token WEND
 %token WHEN    
 %token WHILE   
 %token WITH
@@ -309,6 +635,8 @@ namespace Mono.MonoBASIC
 %token XOR
 %token YIELD // MonoBASIC extension
 
+%token HASH
+
 /* MonoBASIC single character operators/punctuation. */
 
 %token OPEN_BRACKET  "["
@@ -330,7 +658,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    "!"
 
@@ -349,13 +677,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             "<<"
@@ -395,14 +716,33 @@ namespace Mono.MonoBASIC
 %start compilation_unit
 %%
 
+end_of_stmt
+       : logical_end_of_line
+       | COLON
+       ;       
+
+logical_end_of_line
+       :
+         EOL 
+       | logical_end_of_line pp_directive 
+       ;
+
 compilation_unit
-       : opt_option_directives
+       : 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
          {
-               $$ = $4;
+               /* ????? */ ;
          }
        ;
          
@@ -420,6 +760,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
@@ -449,32 +797,32 @@ text_or_binary
        ;
          
 option_explicit_directive
-       : OPTION EXPLICIT on_off EOL
+       : 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 EOL
+       : 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");
          }
        ;
          
 option_compare_directive
-       : OPTION COMPARE text_or_binary EOL
+       : OPTION COMPARE text_or_binary logical_end_of_line
          {
                OptionCompareBinary = (bool)$3;
          }
@@ -483,7 +831,7 @@ option_compare_directive
 opt_declarations
        : /* empty */
        | declarations
-       ;
+       ;               
 
 declarations
        : declaration
@@ -491,24 +839,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 (
+                               31089, (Location)$2, 
+                               "Namespace elements cannot be explicitly " +
+                               "declared private in '" + name + "'");
+                       }
+               else if ((mod_flags & (Modifiers.PROTECTED)) != 0){
                        Report.Error (
-                               1527, lexer.Location
+                               31047, (Location)$2
                                "Namespace elements cannot be explicitly " +
-                               "declared private or protected in '" + name + "'");
+                               "declared protected in '" + name + "'");
                }
          }
        ;
@@ -538,9 +903,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 ()); 
          }
        ;
@@ -556,148 +921,252 @@ imports_directives
        ;
 
 imports_directive
-       : IMPORTS imports_terms EOL
+       : IMPORTS imports_terms logical_end_of_line
        ;
 
 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 _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 error
+          {
+                Report.Error(30198,(Location)$2, "'(' is not having a matching ')'");
+                $$ = $3;
+          }
+        | error _mark_ opt_formal_parameter_list CLOSE_PARENS
+          {
+                Report.Error(30205,(Location)$2, "')' is not having a matching '('");
+                $$ = $3;
+          }
+        ;
+
 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 _mark_ attribute_list OP_GT opt_end_of_stmt
+         {
+               $$ = null;
+               if ($3 != null) {
+                       if (expecting_global_attribs && !(bool) $5) {
+                               Report.Error (30205, (Location)$2, "End of statement expected");
+                               break;
+                       }
+                       
+                       if (expecting_local_attribs)  {
+                               if ((bool) $5) {
+                                       Report.Error (32035, (Location)$2, "Use a line continuation after the attribute specifier to apply it to the following statement.");
+                                       break;
+                               }
+                       }
+
+                       $$ = $3;
+               }
+         }
+       ; 
+
+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
          {
@@ -717,21 +1186,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));
@@ -758,7 +1221,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, 
@@ -767,34 +1230,30 @@ named_argument
        ;
                                
 namespace_declaration
-       : opt_attributes NAMESPACE qualified_identifier EOL
+       : 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);
-               }
-                         
+               push_into_stack((int)Start_block.NAMESPACE, (Location)$2);
                current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
+               
          } 
-         opt_imports_directives
          opt_declarations
-         END NAMESPACE EOL
+         opt_end_block
+         {
+               pop_out_of_stack((int)$7, lexer.Location);      
+         }
+         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
@@ -807,11 +1266,13 @@ type_spec_declaration
        ;
 
 class_declaration
-       : CLASS identifier EOL 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
                // instead of triggering an error.
+               push_into_stack((int)Start_block.CLASS, (Location)$3);
+               
                if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
                        current_modifiers = (current_modifiers & ~Modifiers.STATIC);
          
@@ -820,17 +1281,31 @@ 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 EOL
+         opt_end_block
+         {
+               pop_out_of_stack((int)$9, lexer.Location);
+         }
+         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);
@@ -841,12 +1316,12 @@ class_declaration
 
 opt_inherits
        : /* empty */                           { $$ = null; }
-       | INHERITS type_list EOL        { $$ = $2; }
+       | INHERITS type_list end_of_stmt        { $$ = $2; }
        ;
 
 opt_implements
        : /* empty */                           { $$ = null; }
-       | IMPLEMENTS type_list EOL      { $$ = $2; }
+       | IMPLEMENTS type_list end_of_stmt              { $$ = $2; }
        ;
 
 opt_modifiers
@@ -888,22 +1363,27 @@ modifier
        ;
 
 module_declaration
-       : MODULE identifier EOL
+       : MODULE _mark_ identifier logical_end_of_line
          { 
+               push_into_stack((int)Start_block.MODULE, (Location)$2); 
                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 EOL
+         opt_end_block
+         {
+               pop_out_of_stack((int)$7, lexer.Location);      
+         }
+         logical_end_of_line
          {
                Module new_module = (Module)current_container;
 
@@ -958,7 +1438,7 @@ module_member_declarator
        ;
        
 constant_declaration
-       : CONST constant_declarators EOL
+       : 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
@@ -1041,79 +1521,86 @@ must_override_declaration
        ;
        
 must_override_sub_declaration
-       : MUSTOVERRIDE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
+       : 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) $5, 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!");         
                        
-               // FIXME ASAP: This will crash the compiler at resolution time                  
                $$ = method;                        
          }
        ;
 
        
 must_override_func_declaration
-       : MUSTOVERRIDE FUNCTION identifier opt_type_character OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks EOL
+       : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
          {     
-               Expression ftype = ($8 == null) ? (($4 == null) ? TypeManager.  
-                       system_object_expr : (Expression) $4 ) : (Expression) $8;
+               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) $6, 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 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler opt_implement_clause EOL
+       : SUB identifier _mark_ opt_params opt_evt_handler opt_implement_clause logical_end_of_line
          { 
+               push_into_stack((int)Start_block.SUB, (Location)$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 EOL
+         opt_end_block 
+         {
+               pop_out_of_stack((int)$10, lexer.Location);
+         }
+         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) $7, member_location);
+                                           (ArrayList) $6, (Location)$3);
        
                method.Block = (Block) end_block();
                $$ = method;
 
-               if ($6 != 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;
@@ -1121,11 +1608,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) $6
+                                               Statement addhnd = (Statement) new AddHandler ((Expression) $5
                                                                                        DecomposeQI((string) $2, loc), 
-                                                                                       DecomposeQI(evt_target, loc), loc);
+                                                                                       loc);
 
                                                current_container.AddEventHandler (addhnd);
                                                found = true;
@@ -1133,24 +1620,32 @@ 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
-         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks opt_implement_clause EOL
+         opt_params _mark_ opt_type_with_ranks opt_implement_clause logical_end_of_line
          { 
-               current_local_parameters = (Parameters) $5;
-               member_location = lexer.Location;
+               push_into_stack((int)Start_block.FUNCTION, (Location)$5);
+               current_local_parameters = (Parameters) $4;
                start_block(); 
                                
-               Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
+               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))
@@ -1158,28 +1653,33 @@ 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 EOL
+         opt_end_block 
+         {
+               pop_out_of_stack((int)$11, lexer.Location);
+         }
+         logical_end_of_line
          {
-               Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
+               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) $8, member_location);
+                                           (ArrayList) $7, (Location)$5);
                method.Block = end_block();
                $$ = method;
          }       
        ;               
 
 struct_declaration
-       : STRUCTURE identifier EOL
+       : STRUCTURE _mark_ identifier end_of_stmt
          opt_implement_clause
          {
+               push_into_stack((int)Start_block.STRUCTURE, (Location)$2);
                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
@@ -1189,7 +1689,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);
@@ -1198,14 +1698,18 @@ 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 EOL
+         opt_end_block 
+         {
+               pop_out_of_stack((int)$9, lexer.Location);
+         }
+         logical_end_of_line
        ;
        
 opt_struct_member_declarations
@@ -1244,52 +1748,69 @@ struct_member_declarator
        ;
        
 event_declaration
-       : EVENT identifier AS type EOL
+       : 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_event_params EOL
+       | 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);
          }
        ;
        
-opt_event_params
-       : /* empty */   { $$ = Parameters.EmptyReadOnlyParameters; }
-       | OPEN_PARENS CLOSE_PARENS      { $$ = Parameters.EmptyReadOnlyParameters; }
-       | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS    { $$ = $2; }
-       ;
-       
 enum_declaration
-       : ENUM identifier opt_type_spec EOL
-         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;
+               push_into_stack((int)Start_block.ENUM, (Location)$2);
+               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
@@ -1315,7 +1836,11 @@ enum_declaration
                RootContext.Tree.RecordDecl (full_name, e);
 
          }
-         END ENUM EOL
+         opt_end_block 
+         {
+               pop_out_of_stack((int)$8,lexer.Location);
+         }
+         logical_end_of_line
        ;
 
 opt_enum_member_declarations
@@ -1342,31 +1867,31 @@ enum_member_declarations
        ;
 
 enum_member_declaration
-       : opt_attributes identifier EOL
+       : 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
          {
                  $$ = lexer.Location;
          }
-          ASSIGN expression EOL
+          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 EOL
+       : INTERFACE _mark_ identifier logical_end_of_line
          {
+               push_into_stack((int)Start_block.INTERFACE, (Location)$2);
                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;
@@ -1377,42 +1902,40 @@ 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 EOL
+         opt_end_block 
+         {
+               pop_out_of_stack((int)$9, lexer.Location);
+        }
+         logical_end_of_line
        ;
 
 opt_interface_base
        : /* empty */                     { $$ = null; }
-       | interface_base
-       ;
-
-interface_base
-       : INHERITS interface_type_list    { $$ = $2; }
+       | interface_bases
        ;
 
-interface_type_list
-       : interface_type
-         {
-               ArrayList interfaces = new ArrayList ();
-
-               interfaces.Add ($1);
-               $$ = interfaces;
-         }
-       | interface_type_list COMMA interface_type
+interface_bases
+       : interface_base
+       | interface_bases interface_base
          {
-               ArrayList interfaces = (ArrayList) $1;
-               interfaces.Add ($3);
-               $$ = interfaces;
+               ArrayList bases = (ArrayList) $1;
+               bases.AddRange ((ArrayList) $2);
+               $$ = bases;
          }
        ;
 
+interface_base
+       : INHERITS type_list logical_end_of_line  { $$ = $2; }
+       ;
+
 interface_body
        : opt_interface_member_declarations
        ;
@@ -1428,94 +1951,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 EOL
+       : 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 EOL
+       : 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 EOL
+       : EVENT identifier AS _mark_ type logical_end_of_line
+         {
+               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
          {
-               $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
-                                        lexer.Location);
+               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 EOL
+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;
                
@@ -1523,6 +2096,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
                {
@@ -1544,7 +2122,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);
                
@@ -1557,9 +2135,26 @@ abstruct_propery_declaration
        ;
        
        
- non_abstruct_propery_declaration
-         : PROPERTY identifier opt_type_character opt_property_parameters AS type opt_implement_clause EOL
-         {
+ non_abstract_propery_declaration
+         : PROPERTY identifier 
+           opt_type_character  
+           opt_property_parameters 
+           _mark_
+           opt_type_with_ranks
+           opt_implement_clause 
+         {
+               push_into_stack((int)Start_block.PROPERTY, (Location)$5);
+               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;
@@ -1567,20 +2162,25 @@ 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 EOL
+         opt_end_block 
+         {
+               pop_out_of_stack((int)$11,lexer.Location);
+        }
+          logical_end_of_line
          {
                lexer.PropertyParsing = false;
 
@@ -1598,16 +2198,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;
@@ -1634,10 +2234,26 @@ opt_implement_clause
          {
                $$ = null;
          }
-       | IMPLEMENTS qualified_identifier
+       | IMPLEMENTS implement_clause_list
+         {
+               $$ = $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
          {
-               $$ = DecomposeQI ((string)$2, lexer.Location);
+               ArrayList impl_list = (ArrayList) $1;
+               impl_list.Add (DecomposeQI ((string)$3, lexer.Location));
+               $$ = impl_list;
          }     
+         
        ;
        
 accessor_declarations
@@ -1662,10 +2278,11 @@ opt_set_accessor_declaration
        ;
 
 get_accessor_declaration
-       : opt_attributes GET EOL
+       : opt_attributes GET _mark_ logical_end_of_line
          {
+               push_into_stack((int)Start_block.GET, (Location)$3);
                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;
                
@@ -1675,11 +2292,15 @@ 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 EOL
+          opt_end_block
+          {
+               pop_out_of_stack((int)$7,lexer.Location);
+          }
+         logical_end_of_line
          {
                $$ = new Accessor ((Block) end_block(), (Attributes) $1);
                current_local_parameters = null;
@@ -1688,10 +2309,13 @@ get_accessor_declaration
        ;
 
 set_accessor_declaration
-       : opt_attributes SET opt_set_parameter EOL
+       : 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");
+               push_into_stack((int)Start_block.SET, (Location)$4);
+               if ((current_modifiers & Modifiers.READONLY) != 0)
+                       Report.Error (30022,
+                                     (Location)$4,
+                                     "'ReadOnly' properties cannot have a 'Set' accessor");
                        
                Parameter implicit_value_parameter = new Parameter (
                        set_implicit_value_parameter_type, 
@@ -1705,7 +2329,12 @@ set_accessor_declaration
                lexer.PropertyParsing = false;
          }
          opt_statement_list
-         END SET EOL
+          opt_end_block
+          {
+               pop_out_of_stack((int)$8,lexer.Location);
+          }
+
+          logical_end_of_line
          {
                $$ = new Accessor ((Block) end_block(), (Attributes) $1);
                current_local_parameters = null;
@@ -1724,7 +2353,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)
@@ -1734,11 +2363,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
@@ -1748,10 +2377,9 @@ opt_set_parameter
                        
 field_declaration
        : opt_dim_stmt 
-         variable_declarators EOL
+         variable_declarators end_of_stmt
          {               
                int mod = (int) current_modifiers;
-               
 
                VariableDeclaration.FixupTypes ((ArrayList) $2);
                VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
@@ -1778,7 +2406,7 @@ field_declaration
        ;
        
 withevents_declaration
-       : opt_dim_stmt WITHEVENTS variable_declarators EOL
+       : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
          {
                // 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
@@ -1821,13 +2449,13 @@ opt_dim_stmt
        ; 
                
 delegate_declaration
-       : DELEGATE SUB  
+       : DELEGATE SUB _mark_  
          identifier OPEN_PARENS 
          opt_formal_parameter_list
          CLOSE_PARENS 
-         EOL
+         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.
@@ -1837,18 +2465,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 EOL
+         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
@@ -1856,12 +2484,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);
@@ -1869,39 +2497,48 @@ delegate_declaration
        ;
        
 opt_evt_handler
-       : /* empty */
-         {     $$ = null; }
-       | HANDLES qualified_identifier
+       : /* empty */           {       $$ = null; }
+         | HANDLES evt_handler         {       $$ = $2; }
+    ;
+
+evt_handler
+       : qualified_identifier _mark_ 
+         {
+               $$ = (Expression) DecomposeQI ((string)$1, (Location)$2);       
+         }
+       | base_access
+         {
+               $$ = $1;
+         }
+       | ME DOT qualified_identifier _mark_
          {
-               $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);     
+               $$ = (Expression) DecomposeQI ((string)$3, (Location)$4);       
          }
-       | 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 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
+       : SUB _mark_ NEW opt_params logical_end_of_line
          {
+               push_into_stack((int)Start_block.SUB, (Location)$2);
                current_local_parameters = (Parameters) $4;
                start_block();
-               oob_stack.Push (lexer.Location);
-
-               Location l = (Location) oob_stack.Pop ();
-               $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
+               $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, (Location)$2);
                $1 = $$;
          }
          opt_statement_list
          { 
                Constructor c = (Constructor) $1;
                c.Block = (Block) end_block();
+
+//To support "Sub New()" add default modifier "public"
+
+               if(current_modifiers ==0)
+                       current_modifiers = Modifiers.PUBLIC;
                c.ModFlags = (int) current_modifiers;
                c.OptAttributes = current_attributes;
                
@@ -1910,7 +2547,11 @@ constructor_declaration
                CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
                current_local_parameters = null;
          }
-         END SUB EOL
+         opt_end_block 
+         {
+               pop_out_of_stack((int)$9, lexer.Location);
+        }
+          logical_end_of_line
        ;
        
 opt_formal_parameter_list
@@ -1926,38 +2567,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;
 
@@ -1966,58 +2609,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 (999, "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;                      }
@@ -2032,6 +2664,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
@@ -2041,11 +2674,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);
@@ -2054,18 +2688,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
            {
@@ -2075,12 +2707,15 @@ statement :
          /* | empty_statement */
          | with_statement 
            {
-                 Statement s = (Statement) $1;
-
              current_block.AddStatement ((Statement) $1);
            }     
          ;     
          
+opt_end_stmt
+       : END_EOL {$$ = new End (lexer.Location);}
+       ;
+
+       
 opt_raise_event_args 
        : /* empty */   { $$ = null; }
        | OPEN_PARENS opt_argument_list CLOSE_PARENS
@@ -2089,8 +2724,26 @@ opt_raise_event_args
          }
        ;
 
+label_name
+       : identifier
+       | LITERAL_INTEGER
+       {
+               $$ = $1.ToString();
+       }
+       ;
+
 labeled_statement
-       : identifier COLON end_of_stmt 
+       : 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);
 
@@ -2108,6 +2761,7 @@ embedded_statement
        | selection_statement
        | iteration_statement
        | try_statement
+       | synclock_statement
        | jump_statement
        | array_handling_statement 
        ;
@@ -2121,16 +2775,18 @@ 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);
+               push_into_stack((int)Start_block.WITH, (Location)$2);
+               Expression e = (Expression) $3;
                with_stack.Push(e);
                start_block();
          }
          opt_statement_list
-         END WITH
+         opt_end_block 
          {
+               pop_out_of_stack((int)$7,lexer.Location);
                Block b = end_block();
                with_stack.Pop();
                $$ = b;
@@ -2225,19 +2881,20 @@ jump_statement
        | throw_statement       
        | exit_statement
        | yield_statement
+       | opt_end_stmt
        ;
                
 goto_statement
-       : GOTO identifier  
+       : GOTO label_name  
          {
                $$ = new Goto (current_block, (string) $2, lexer.Location);
          }
        ;
        
 throw_statement
-       : THROW opt_expression
+       : THROW _mark_ opt_expression
          {
-               $$ = new Throw ((Expression) $2, lexer.Location);
+               $$ = new Throw ((Expression) $3, (Location)$2);
          }
        ;       
                        
@@ -2273,48 +2930,91 @@ 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;              
+               push_into_stack((int)Start_block.FOR, l);
                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
-         {
-               Block foreach_block = current_block;
+         opt_end_block
+          {
+               pop_out_of_stack((int)$11,lexer.Location);
+          }
+          _mark_ opt_identifier
+         {
+                       string s = $3.ToString();
+                       string s1 = "";
+                       if ($14 != null)
+                               s1 = $14.ToString();            
+                       if (s1 != "" && s != s1)
+                               {               
+                                       Report.Error(30070, (Location)$13, "Next Control Variable '"+s1+"' does not match with For Loop control variable '"+s+"'");    
+                               }
                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)
                {
@@ -2323,14 +3023,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)
                {
@@ -2339,16 +3039,28 @@ 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 _mark_ expression end_of_stmt
+         {   
+               push_into_stack((int)Start_block.SYNCLOCK, (Location)$2);
+               start_block();  
+         }
+         opt_statement_list 
+         opt_end_block 
+         {
+               pop_out_of_stack((int)$7,lexer.Location);
+               $$ = new Lock ((Expression) $3, (Statement) (Block) end_block(), (Location)$2);
+         }
+       ;
 
 try_statement
        : try_catch
@@ -2356,21 +3068,26 @@ try_statement
        ;
                                
 try_header
-       : TRY end_of_stmt
+       : TRY _mark_ end_of_stmt
          {   
+               push_into_stack((int)Start_block.TRY, (Location)$2);
+               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 
+         {
+               pop_out_of_stack((int)$3,lexer.Location);
                Catch g = null;
                ArrayList s = new ArrayList ();
 
@@ -2385,7 +3102,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);
          }       
        ;       
          
@@ -2399,8 +3116,9 @@ try_catch_finally
                start_block(); 
          }       
          opt_statement_list 
-         END TRY
+         _mark_ opt_end_block 
          {
+               pop_out_of_stack((int)$8,lexer.Location);
                Catch g = null;
                ArrayList s = new ArrayList ();
                ArrayList catch_list = (ArrayList) tmp_catch_clauses;
@@ -2414,7 +3132,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);
        
          }     
          ;             
@@ -2446,8 +3164,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;
@@ -2459,18 +3185,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;
@@ -2490,10 +3214,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; }
@@ -2501,28 +3224,42 @@ opt_catch_args
        ;         
 
 catch_args 
-        : identifier AS type
+        : identifier AS _mark_ type
         {
-                $$ = new DictionaryEntry ($3, $1); 
+                $$ = new DictionaryEntry ($4, $1); 
+       }
+       | error _mark_ AS type
+       {
+               Report.Error(30203, (Location)$2, "Identifier Expected");
+               $$ = null;
+       }
+       | identifier AS _mark_ error 
+       {
+               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
          {
+               push_into_stack((int)Start_block.DO, (Location)$2);
                start_block();
-               oob_stack.Push (lexer.Location);
          }     
          opt_statement_list
-         LOOP opt_do_construct
+         opt_end_block
+          {
+               pop_out_of_stack((int)$7,lexer.Location);
+         }
+         _mark_ opt_do_construct
          {
-               Expression t_before = (Expression) $2;
-               Expression t_after = (Expression) $7;
+               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);
@@ -2533,9 +3270,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);
          }
          ;
 
@@ -2556,43 +3293,67 @@ while_or_until
 while_statement
        : WHILE
        {
+               push_into_stack((int)Start_block.WHILE, lexer.Location);
                start_block();
                oob_stack.Push (lexer.Location);
        }
        boolean_expression end_of_stmt
        opt_statement_list
-       END WHILE
-       {
+       opt_end_block
+          {
                Location l = (Location) oob_stack.Pop ();
+               pop_out_of_stack((int)$6,lexer.Location);
                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();
+               push_into_stack((int)Start_block.FOR, (Location)$2);
+               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 
-         {
-               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);            
-         }       
+         opt_end_block
+          {
+               pop_out_of_stack((int)$13,lexer.Location);
+         }
+          _mark_ opt_identifier 
+         {
+               string s = $3.ToString();
+               string s1 = "";
+               if ($16 != null)
+                       s1 = $16.ToString();            
+               if (s1 != "" && s != s1) {              
+                       Report.Error(30070, (Location)$15, "Next Control Variable '"+s1+"' does not match with For Loop control variable '"+s+"'");    
+               }
+
+               Block inner_statement = end_block();
+               Location l = (Location)$2;
+               Expression for_var = (Expression) DecomposeQI ((string)$3, l);
+                       
+               For f = new For (for_var, (Expression) $6, (Expression) $8, (Expression) $9, inner_statement, l);
+               if ($4 != null)
+               {
+                       current_block.AddStatement (f);
+                       $$ = end_block();
+               }
+               else
+                       $$ = f;
+       }
        ;
 
 opt_step
@@ -2606,34 +3367,81 @@ selection_statement
        ;
 
 if_statement
-       : if_statement_open opt_then if_statement_rest
+       : if_statement_open opt_then end_of_stmt opt_statement_list 
+          {
+               push_into_stack((int)Start_block.IF, (Location)$1);
+          }    
+          if_statement_rest
+          {
+               $$ = $6;
+          }
+       | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement
          {
-               $$ = $3;
+               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 pre_embedded_statement
+       | if_statement_open THEN else_pre_embedded_statement
          {
-               Location l = (Location) oob_stack.Pop ();
-               tmp_expr = (Expression)expr_stack.Pop(); 
-               $$ = new If ((Expression) tmp_expr, end_block(), l);
+                       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 _mark_
          {
                oob_stack.Push (lexer.Location);
+         }
+               boolean_expression 
+         {
                start_block();
-               tmp_expr = (Expression) $2;
+               tmp_expr = (Expression) $4;
                expr_stack.Push(tmp_expr);
+               $$ = (Location)$2;
          }
         ;
 
@@ -2643,41 +3451,41 @@ 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(); 
+               pop_out_of_stack((int)$1,lexer.Location);
+                       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 ();
+               pop_out_of_stack((int)$5,lexer.Location);
                 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();  
@@ -2689,18 +3497,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();
@@ -2708,25 +3505,26 @@ else_if_statement_rest
                start_block();
          }
          opt_statement_list
-         END IF        
+         opt_end_block 
          {
                Location l = (Location) oob_stack.Pop ();
+               pop_out_of_stack((int)$5,lexer.Location);
                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);
@@ -2736,19 +3534,33 @@ 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 ();
+               pop_out_of_stack((int)$1,lexer.Location);
+               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
          { 
+               push_into_stack((int)Start_block.SELECT, (Location)$2);
                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
+          {
+               pop_out_of_stack((int)$8,lexer.Location);
                current_block = (Block) switch_stack.Pop ();
+               $$ = new Switch ((Expression) $4, (ArrayList) $7, (Location) oob_stack.Pop ());
          }       
        ;
 
@@ -2797,7 +3609,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.) 
@@ -2818,7 +3630,7 @@ case_section
                topmost.statements.Add (new Break (lexer.Location));
                
                ArrayList a = new ArrayList();
-               a.Add (new SwitchLabel (null, lexer.Location));                 
+               a.Add (new SwitchLabel (null, SwitchLabel.LabelType.Else, Binary.Operator.TOP, lexer.Location));                        
                $$ = new SwitchSection ((ArrayList) a, topmost);                
          }
        ;         
@@ -2827,14 +3639,13 @@ case_clauses
        : case_clause
          {
                ArrayList labels = new ArrayList ();
-
                labels.Add ($1);
                $$ = labels;
          }     
        | case_clauses COMMA case_clause
          {
                ArrayList labels = (ArrayList) ($1);
-               labels.Add ($2);
+               labels.Add ($3);
 
                $$ = labels;
          }     
@@ -2842,10 +3653,19 @@ case_clauses
        
 case_clause
        : opt_is comparison_operator expression
+         {
+               $$ = new SwitchLabel ((Expression) $3, SwitchLabel.LabelType.Operator, (Binary.Operator) $2, lexer.Location);
+         }
        | expression
          {
-               $$ = new SwitchLabel ((Expression) $1, lexer.Location);
+               $$ = new SwitchLabel ((Expression) $1, SwitchLabel.LabelType.Label, Binary.Operator.TOP, lexer.Location);
          }
+       | expression TO expression
+        {
+               $$ = new SwitchLabel ((Expression) $1, (Expression) $3, SwitchLabel.LabelType.Range,
+                                        Binary.Operator.TOP, lexer.Location);
+        }
+
        ;
        
 opt_is 
@@ -2854,11 +3674,30 @@ opt_is
        ;
 
 comparison_operator
-       : OP_LT
+       : OP_LT 
+         {
+               $$ = Binary.Operator.LessThan;
+         }
        | OP_GT
+         {
+               $$ = Binary.Operator.GreaterThan;
+         }
+       | OP_GE
+         {
+               $$ = Binary.Operator.GreaterThanOrEqual;
+         }
        | OP_LE
+         {
+               $$ = Binary.Operator.LessThanOrEqual;
+         }
        | OP_NE
-       /*| OP_EQ */
+         {
+               $$ = Binary.Operator.Inequality;
+         }
+       | ASSIGN
+         {
+               $$ = Binary.Operator.Equality;
+         }
        ;
 
 opt_case
@@ -2881,18 +3720,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 _mark_ array_initializer 
          {
                New n = (New) $1;
                ArrayList dims = new ArrayList();
@@ -2905,53 +3744,43 @@ array_creation_expression
                        
                Expression atype = n.RequestedType;
 
-               ArrayList init = (ArrayList) $2;
+               if ($2 != null)
+                       atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, (Location)$3), (Location)$3);
+
+               ArrayList init = (ArrayList) $4;
                if (init.Count == 0)
                        init = null;
        
                if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
                        VariableDeclaration.VBFixIndexList (ref dims);
-                       $$ = new ArrayCreation (atype, dims, "", init, lexer.Location); 
+                       $$ = new ArrayCreation (atype, dims, "", init, (Location)$3); 
                }
                else
                {
                        string rank = VariableDeclaration.BuildRank (dims);
-                       $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location); 
+                       $$ = new ArrayCreation (atype, rank, (ArrayList) $4, (Location)$3); 
                }
                //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);
@@ -2960,9 +3789,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);               
          }
        ;
 
@@ -2997,33 +3826,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);
          }
        ;               
 
@@ -3043,17 +3871,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" );
 
@@ -3063,43 +3891,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."); 
+                                       Report.Error (30638, (Location)$1,"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
@@ -3113,7 +3932,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;
@@ -3134,14 +3953,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
@@ -3150,7 +3969,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;
          } 
@@ -3191,21 +4010,17 @@ opt_type_spec
                
 opt_type_with_ranks
        : opt_type_spec 
-       | AS type rank_specifiers
+       | AS type _mark_ rank_specifiers
          {
-               $$ = TypeManager.system_object_expr; 
+               $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$4, true, (Location)$3), (Location)$3);
          }
        ;
        
 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);
@@ -3216,7 +4031,7 @@ opt_type_decl
                New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
                $$ = (Expression) n;
          }
-       | AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS 
+       /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS 
          {
            ArrayList args = new ArrayList();
                Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
@@ -3224,7 +4039,7 @@ opt_type_decl
                
                New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
                $$ = (Expression) n;
-         }
+         }*/
        ;
                
 opt_array_name_modifier
@@ -3244,7 +4059,9 @@ opt_variable_initializer
 variable_initializer
        : expression
          {
-               $$ = $1;
+               Expression etmp = (Expression) $1;
+               etmp = SetValueRequiredFlag (etmp);
+               $$ = etmp;
          }
        | array_initializer
          {
@@ -3308,82 +4125,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
          }
-
-       | qualified_identifier
+       | parenthesized_expression
+       | this_access
+       | base_access
+       | qualified_identifier opt_type_character _mark_
          {
                string name = (string) $1;
-
-               $$ = DecomposeQI (name, lexer.Location);
+               $$ = DecomposeQI (name, (Location)$3);
          }
-       | parenthesized_expression
+       | get_type_expression
        | member_access
        | invocation_expression
        //| element_access
-       | this_access
-       | base_access
        | new_expression
        | cast_expression
+       | error _mark_ 
+            { Report.Error(30201,(Location)$2,"Expression expected"); $$ = (Expression)null;}
        ;
 
 literal
@@ -3413,7 +4208,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");
                        
          }
        ;
@@ -3429,19 +4224,19 @@ parenthesized_expression
        ;
 
 member_access
-       : primary_expression DOT identifier
+       : primary_expression DOT _mark_ identifier
          {
                if ($1 != null) {
-                       string id_name = (string)$3;
+                       string id_name = (string)$4;
                        if (id_name.ToUpper() == "NEW")
                                id_name = ".ctor";
-                       $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
+                       $$ = new MemberAccess ((Expression) $1, id_name, (Location)$3);
                }
                else
                {
                        if (with_stack.Count > 0) {
                                Expression e = (Expression) with_stack.Peek();
-                               $$ = new MemberAccess (e, (string) $3, lexer.Location);
+                               $$ = new MemberAccess (e, (string) $4, (Location)$3);
                        }
                        else
                        {
@@ -3449,19 +4244,19 @@ member_access
                        }
                }
          }
-/*     | primary_expression DOT NEW
+/*     | primary_expression DOT _mark_ NEW
          {
-               $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
+               $$ = new MemberAccess ((Expression) $1, (string) ".ctor", (Location)$3);
          }       */
-       | predefined_type DOT identifier
+       | predefined_type DOT _mark_ identifier
          {
                if ($1 != null)
-                       $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+                       $$ = new MemberAccess ((Expression) $1, (string) $4, (Location)$3);
                else
                {
                        if (with_stack.Count > 0) {
                                Expression e = (Expression) with_stack.Peek();
-                               $$ = new MemberAccess (e, (string) $3, lexer.Location);
+                               $$ = new MemberAccess (e, (string) $4, (Location)$3);
                        }
                        else
                        {
@@ -3470,23 +4265,51 @@ member_access
                }
          }
        ;
-
+       
 predefined_type
        : builtin_types
        ;
 
 invocation_expression
-       : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
+// To support Mid$()
+       : primary_expression opt_dolar_sign OPEN_PARENS opt_argument_list _mark_ CLOSE_PARENS
          {
                if ($1 == null) {
-                       Location l = lexer.Location;
+                       Location l = (Location)$5;
                        Report.Error (1, l, "THIS IS CRAZY");
                }
-               $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
-//             Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
-         } 
+               $$ = 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);
+         }
+       | primary_expression EXCLAMATION _mark_ identifier // FIXME : This should be identifier-or-keyword
+         {
+               if ($1 == null) {
+                       Location l = (Location)$3;
+                       Report.Error (1, l, "THIS IS CRAZY");
+               }
+               
+               ArrayList args = new ArrayList ();
+               Expression etmp = new StringLiteral ((string)$4);
+               
+               args.Add (new Argument (etmp, Argument.AType.Expression));
+               $$ = new Invocation ((Expression) $1, args, (Location)$3);
+         }
        ;
-       
+
+opt_dolar_sign
+       : DOLAR_SIGN
+       | /*empty*/
+       ;       
+
 base_access
        : MYBASE DOT IDENTIFIER
          {
@@ -3549,26 +4372,23 @@ argument
          {
                $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
          }
-       /*| ADDRESSOF expression
+       | ADDRESSOF expression
          {
                $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
-         }*/
+         }
+       | identifier ATTR_ASSIGN expression 
+         {
+               $$ = new Argument ((string) $1, (Expression) $3, Argument.AType.Expression);
+         }
        ;
 
 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; } 
        /*| assignment_expression*/
        ;
 
@@ -3584,30 +4404,23 @@ this_access
          }
        | MYCLASS
          {
-               // FIXME: This is actually somewhat different from Me
-               // because it is for accessing static (classifier) methods/properties/fields
-               $$ = new This (current_block, lexer.Location);
+               $$ = new This (This.TypeOfAccess.MyClass, current_block, lexer.Location);
          }
        ;
 
-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
@@ -3622,246 +4435,292 @@ 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 OPEN_PARENS _mark_ type CLOSE_PARENS
+         {
+               $$ = new TypeOf ((Expression) $4, (Location)$3);
+         }
+       ;
+       
+exponentiation_expression
+       : prefixed_unary_expression
+       | exponentiation_expression OP_EXP _mark_ primary_expression
+         {
+               $$ = new Binary (Binary.Operator.Exponentiation,
+                                (Expression) $1, (Expression) $4, (Location)$3);
+         }                             
        ;
        
-       //
-       // 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
+       : primary_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);
          }
        ;
 
 multiplicative_expression
-       : prefixed_unary_expression
-       | multiplicative_expression STAR prefixed_unary_expression
+       : exponentiation_expression
+       | multiplicative_expression STAR _mark_ prefixed_unary_expression
          {
                $$ = new Binary (Binary.Operator.Multiply,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | multiplicative_expression DIV prefixed_unary_expression
+       | multiplicative_expression DIV _mark_ prefixed_unary_expression
          {
                $$ = new Binary (Binary.Operator.Division,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | multiplicative_expression OP_IDIV prefixed_unary_expression
-         {
-               $$ = new Binary (Binary.Operator.Division,
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }       
-       | multiplicative_expression MOD prefixed_unary_expression
+       ;
+
+integer_division_expression
+       : multiplicative_expression
+       | integer_division_expression OP_IDIV _mark_ multiplicative_expression
+          {
+               //FIXME: Is this right ?
+               $$ = new Binary (Binary.Operator.IntDivision,
+                          (Expression) $1, (Expression) $4, (Location)$3);
+          }
+       ;
+
+mod_expression
+       : integer_division_expression
+       | mod_expression MOD _mark_ integer_division_expression
          {
-               $$ = new Binary (Binary.Operator.Modulus,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+             $$ = new Binary (Binary.Operator.Modulus,
+                              (Expression) $1, (Expression) $4, (Location)$3);
          }
        ;
-
+       
 additive_expression
-       : multiplicative_expression
-       | additive_expression PLUS multiplicative_expression
+       : mod_expression
+       | additive_expression PLUS _mark_ mod_expression
          {
                $$ = new Binary (Binary.Operator.Addition,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | additive_expression MINUS multiplicative_expression
+       | additive_expression MINUS _mark_ mod_expression
          {
                $$ = new Binary (Binary.Operator.Subtraction,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | additive_expression OP_CONCAT multiplicative_expression
+       ;
+
+concat_expression
+       : additive_expression
+       | concat_expression OP_CONCAT _mark_ additive_expression
+          {
+             // FIXME: This should only work for String expressions
+             // We probably need to use something from the runtime
+             $$ = new StringConcat((Location)$3,
+                              (Expression) $1, (Expression) $4);
+         }     
+       ;
+
+
+shift_expression
+       : concat_expression
+       | shift_expression OP_SHIFT_LEFT _mark_ 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)$3);
+         }
+       | shift_expression OP_SHIFT_RIGHT _mark_ concat_expression
+         {
+               $$ = new Binary(Binary.Operator.RightShift, (Expression) $1, (Expression) $4, (Location)$3);
+         }
        ;
 
 relational_expression
-       : additive_expression
-       | relational_expression OP_LT additive_expression
+       : shift_expression
+       | relational_expression LIKE _mark_ shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Like,
+                                (Expression) $1, (Expression) $4, (Location)$3);
+         }
+       | relational_expression ASSIGN _mark_ shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Equality,
+                                (Expression) $1, (Expression) $4, (Location)$3);
+         }
+       | relational_expression OP_NE _mark_ shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Inequality, 
+                                (Expression) $1, (Expression) $4, (Location)$3);
+         }       
+       | relational_expression OP_LT _mark_ shift_expression
          {
                $$ = new Binary (Binary.Operator.LessThan,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | relational_expression OP_GT additive_expression
+       | relational_expression OP_GT _mark_ shift_expression
          {
                $$ = new Binary (Binary.Operator.GreaterThan,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | relational_expression OP_LE additive_expression
+       | relational_expression OP_LE _mark_ shift_expression
          {
                $$ = new Binary (Binary.Operator.LessThanOrEqual,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | relational_expression OP_GE additive_expression
+       | relational_expression OP_GE _mark_ shift_expression
          {
                $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | relational_expression IS unary_expression
+       | relational_expression IS _mark_ shift_expression
          {
-               $$ = new Binary (Binary.Operator.Equality,
-                       (Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Binary (Binary.Operator.Is,
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | relational_expression AS type_name
+       | TYPEOF shift_expression _mark_ IS type
          {
-               $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Is ((Expression) $2, (Expression) $5, (Location)$3);
          }
        ;
 
-equality_expression
+negation_expression
        : relational_expression
-       | equality_expression ASSIGN relational_expression
+       | NOT _mark_ negation_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);
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $3, (Location)$2);
          }
        ;
-
-exclusive_or_expression
-       : and_expression
-       | exclusive_or_expression OP_XOR and_expression
-         {
-               $$ = new Binary (Binary.Operator.ExclusiveOr,
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }
-       ;
-
+       
 conditional_and_expression
-       : exclusive_or_expression
-       | conditional_and_expression AND exclusive_or_expression
+       : negation_expression
+       | conditional_and_expression AND _mark_ negation_expression
          {
-               $$ = new Binary (Binary.Operator.LogicalAnd,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Binary (Binary.Operator.BitwiseAnd,
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | conditional_and_expression ANDALSO exclusive_or_expression
+       | conditional_and_expression ANDALSO _mark_ 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)$3);
          }
        ;
 
 conditional_or_expression
        : conditional_and_expression
-       | conditional_or_expression OR conditional_and_expression
+       | conditional_or_expression OR _mark_ conditional_and_expression
          {
-               $$ = new Binary (Binary.Operator.LogicalOr,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Binary (Binary.Operator.BitwiseOr,
+                                (Expression) $1, (Expression) $4, (Location)$3);
          }
-       | conditional_or_expression ORELSE conditional_and_expression
+       | conditional_or_expression ORELSE _mark_ 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)$3);
          }
        ;
 
-conditional_expression
+conditional_xor_expression
        : conditional_or_expression
+       | conditional_xor_expression XOR _mark_ conditional_or_expression
+       {
+             $$ = new Binary (Binary.Operator.ExclusiveOr,
+                              (Expression) $1, (Expression) $4, (Location)$3);
+       }
        ;
 
 assignment_expression
-       : prefixed_unary_expression ASSIGN expression
+       : prefixed_unary_expression ASSIGN _mark_ expression
          { 
-               $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
+               $$ = new Assign ((Expression) $1, (Expression) $4, (Location)$3);
          }
-       | 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 OP_EXP ASSIGN _mark_ expression
+         {
+               Location l = (Location)$4;
+               $$ = new CompoundAssign (
+                       Binary.Operator.Exponentiation, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_MULT_ASSIGN expression
+       | prefixed_unary_expression STAR ASSIGN _mark_ expression
          {
-               Location l = lexer.Location;
-
+               Location l = (Location)$4;
                $$ = new CompoundAssign (
-                       Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
+                       Binary.Operator.Multiply, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_DIV_ASSIGN expression
+       | prefixed_unary_expression DIV ASSIGN _mark_ expression
          {
-               Location l = lexer.Location;
-
+               Location l = (Location)$4;
                $$ = new CompoundAssign (
-                       Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
+                       Binary.Operator.Division, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_IDIV_ASSIGN expression
+       | prefixed_unary_expression PLUS ASSIGN _mark_ expression
          {
-               Location l = lexer.Location;
-
+               Location l = (Location)$4;
                $$ = new CompoundAssign (
-                       Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
-         }       
-       | prefixed_unary_expression OP_ADD_ASSIGN expression
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $5, l);
+         }
+       | prefixed_unary_expression MINUS ASSIGN _mark_ expression
          {
-               Location l = lexer.Location;
-
+               Location l = (Location)$4;
                $$ = new CompoundAssign (
-                       Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
+                       Binary.Operator.Subtraction, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_SUB_ASSIGN expression
+       | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN _mark_ expression
          {
-               Location l = lexer.Location;
-
+               Location l = (Location)$4;
                $$ = new CompoundAssign (
-                       Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
+                       Binary.Operator.LeftShift, (Expression) $1, (Expression) $5, l);
          }
-       | prefixed_unary_expression OP_CONCAT_ASSIGN expression
+       | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN _mark_ expression
          {
-               Location l = lexer.Location;
+               Location l = (Location)$4;
+               $$ = new CompoundAssign (
+                       Binary.Operator.RightShift, (Expression) $1, (Expression) $5, l);
+         }
+       | prefixed_unary_expression OP_CONCAT ASSIGN _mark_ expression
+         {
+               Location l = (Location)$4;
 
+               // 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 ASSIGN ADDRESSOF _mark_ 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)$4);
+               n.isDelegate = true;
+               $$ = new Assign ((Expression) $1, (Expression) n, (Location)$4);
+         }
        ;
 
-/*constant_expression
+constant_expression
        : expression
        ;
-*/
 
 boolean_expression
-       : expression
+       : expression 
+        {
+               Expression expr = (Expression) $1;
+               expr = SetValueRequiredFlag (expr);
+               $$ = expr;
+        }
        ;
 
 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
@@ -3881,43 +4740,264 @@ 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; }
        ;
        
-end_of_stmt
-       : EOL
-       | COLON
+floating_point_type
+       : SINGLE        { $$ = TypeManager.system_single_expr; }
+       | DOUBLE        { $$ = TypeManager.system_double_expr; }
+       ;
+
+directive_exp 
+       : boolean_literal
+       | constant_expression _mark_  //FIXME: Fix for binary expression
+        {
+               Expression exp = (Expression) $1;
+               if(exp is SimpleName) {
+                       string key = ((SimpleName)exp).Name;    
+                       if(constPreDir.Contains(key)) {
+                               $$ = new BoolLiteral ((bool)constPreDir [key]);
+                       }
+               }
+               else {
+                       object o = ((Constant) exp).GetValue ();
+                       bool temp = Convert.ToBoolean(o);
+                       $$ = new BoolLiteral ((bool)temp);
+                       // Report.Error (30580, (Location)$2, "value of Const used is not set");
+                   }
+        }
        ;       
+               
+pp_directive
+       : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS _mark_ EOL
+         { 
+               if(tokenizerController.IsAcceptingTokens)
+               {
+                       if(in_external_source) 
+                               Report.Error (30580, (Location)$8, "#ExternalSource directives may not be nested");
+                       else {
+                               in_external_source = true;
+                       
+                               lexer.EffectiveSource = (string) $4;
+                               lexer.EffectiveLine = (int) $6;
+                       }
+               }
+         }
+       | HASH IDENTIFIER LITERAL_STRING _mark_ EOL
+         {
+               if(tokenizerController.IsAcceptingTokens) 
+               {
+                       if(!($2 as string).ToLower().Equals("region"))
+                               Report.Error (30205, (Location)$4, "Invalid Pre-processor directive");
+                       else
+                       {
+                               ++in_marked_region;
+                       }
+               }
+         }
+       | HASH END IDENTIFIER _mark_ EOL
+         {
+               if(tokenizerController.IsAcceptingTokens)
+               {
+                       if( ($3 as string).ToLower().Equals("externalsource")) {
+                               if(!in_external_source)
+                                       Report.Error (30578, (Location)$4, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
+                               else {
+                                       in_external_source = false;
+                                       lexer.EffectiveSource = lexer.Source;
+                                       lexer.EffectiveLine = lexer.Line;
+                               }
+                       }
+                       else if(($3 as string).ToLower().Equals("region")) {
+                               if(in_marked_region > 0)
+                                       --in_marked_region;
+                               else
+                                       Report.Error (30205, (Location)$4, "'#End Region' must be preceded  by a matching '#Region'");
+                       }
+                       else {
+                               Report.Error (29999, (Location)$4, "Unrecognized Pre-Processor statement");
+                       }       
+               }
+         }
+       | HASH CONST IDENTIFIER ASSIGN constant_expression _mark_ EOL
+         {
+               {
+                       Expression express = (Expression) $5;
+                       if (express is Binary) {
+                               // FIXME
+                               // TODO
+                       }       
+                       object o = ((Constant) express).GetValue ();
+                       bool temp = Convert.ToBoolean(o);
+                       constPreDir.Add($3,temp);
+               }
+         }
+       | HASH IF _mark_   
+         {
+               IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
+
+               try {
+                       ifElseStateMachine.HandleToken(tok);
+               }
+               catch(ApplicationException) {
+                       throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
+               }
+         }
+         directive_exp opt_then  EOL 
+         {
+               //FIXME: Fix for constant expression
+
+               HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$5);
+         }
+       | HASH opt_elseif _mark_ 
+         {
+                     IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
+                     try {
+                             ifElseStateMachine.HandleToken(tok);
+                     }
+                     catch(ApplicationException) {
+                             throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
+                     }
+         }
+         directive_exp opt_then  EOL 
+         {
+                 //FIXME: Fix for constant expression
+                 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$5);
+         }
+       | HASH ELSE _mark_ 
+         {
+                   IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
+                   try {
+                           ifElseStateMachine.HandleToken(tok);
+                   }
+                   catch(ApplicationException) {
+                           throw new MBASException(ifElseStateMachine.Error, (Location)$3, ifElseStateMachine.ErrString);
+                   }
+         }
+         EOL 
+         { 
+               HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
+         }
+       | 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, (Location)$4, ifElseStateMachine.ErrString);
+                 }
+         }
+         EOL 
+         { 
+               HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
+         }
+       | HASH error _mark_ EOL   
+       {
+               if(tokenizerController.IsAcceptingTokens)
+                       Report.Error(29999, (Location)$3, "Unrecognized Pre-Processor statement");
+               else
+                       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
+       : opt_block_types 
+         {
+               $$ = 2 + (int)$1 ;
+         }
+       | NEXT
+         {$$ = 1;}
+       | LOOP
+         {$$ = 2;}
+       | EOF
+         {$$ = Token.EOF;}     
+       ;
+
+opt_block_types
+       : END IF
+         {$$ = 1;}
+       | END SUB
+         {$$ = 2;}
+       | END MODULE
+         {$$ = 3;}
+       | END NAMESPACE
+         {$$ = 4;}
+       | END CLASS
+         {$$ = 5;}
+       | END FUNCTION 
+         {$$ = 6;}
+       | END STRUCTURE 
+         {$$ = 7;}
+       | END ENUM
+         {$$ = 8;}
+       | END INTERFACE 
+         {$$ = 9;}
+       | END PROPERTY 
+         {$$ = 10;}
+       | END WITH 
+         {$$ = 11;}
+       | END SYNCLOCK
+         {$$ = 12;}
+       | END TRY 
+         {$$ = 13;}
+       | END WHILE 
+         {$$ = 14;}
+       | END SELECT 
+         {$$ = 15;}
+       | END SET 
+         {$$ = 16;}
+       | END GET 
+         {$$ = 17;}
+       /*In case of any new end block please add it here.. after END_GET as single token... and please continue the numbering from 17...*/
+       ;
+
 %%
 
 
@@ -3977,7 +5057,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 ();
@@ -4169,23 +5249,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;
        }       
@@ -4220,7 +5320,6 @@ public class VariableDeclaration {
                
        public static void FixupArrayTypes (ArrayList vars)
        {
-               int varcount =  vars.Count;
                string dims;
                
                foreach (VariableDeclaration var in vars) {
@@ -4291,11 +5390,90 @@ Block end_block ()
        return (res);
 }
 
-private void AddHandler (Expression evt_definition, string handler_name)
+void push_into_stack(int BlockStart, Location l)
+{
+       end_of_block.Push(BlockStart);  
+       loc_end_of_block.Push(l);
+}
+
+void pop_out_of_stack(int BlockEnd, Location l)
+{
+       if(BlockEnd != Token.EOF) {
+               int current = (int)end_of_block.Pop();
+               Location current_loc = (Location)loc_end_of_block.Pop();
+               if(BlockEnd != current) {
+                       // Block end is missing
+                       // eg: For 'Sub' BlockEnd should be 'End Sub'   
+                       
+                       if(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2]) {
+                               while(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2])
+                               {
+                                       if(error_end_blocks[BlockEnd,2] > error_end_blocks[current,2])
+                                               Report.Error(error_end_blocks[current,0],current_loc,"'"+end_blocks[current,0]+"' is not having matching '"+end_blocks[current,1]+"'");
+                                       current = (int)end_of_block.Pop();
+                                       current_loc = (Location)loc_end_of_block.Pop();
+                               }
+                       }
+                       
+                       // Extra end is present, but works for lesser priority 
+                       // (for priority see opt_end_block opt_block_types return values 
+                       // eg: 'EndIf' without 'If' inside 'Sub'
+                       // Also certain other errors like 'Sub' having a 'End Module' etc 
+                       // can be handled here
+
+                       if(error_end_blocks[BlockEnd,2] < error_end_blocks[current,2]) {
+                               Report.Error(error_end_blocks[BlockEnd,1],l,"'"+end_blocks[BlockEnd,1]+"' is not having  a corresponding '"+end_blocks[BlockEnd,0]+"'");
+                               end_of_block.Push(current);     
+                               loc_end_of_block.Push(current_loc);
+                       }       
+                       // Extra end is present but with equal priorty
+
+                       if((error_end_blocks[BlockEnd,2] == error_end_blocks[current,2]) && BlockEnd != current) {
+                               while((error_end_blocks[BlockEnd,2] == error_end_blocks[current,2]) && BlockEnd != current) {
+                                       temp_block.Push(current);
+                                       loc_temp_block.Push(current_loc);
+                                       current = (int)end_of_block.Pop();
+                                       current_loc = (Location)loc_end_of_block.Pop();
+                               }
+                       
+                               if(BlockEnd == current) {
+                                       while(temp_block.Count !=0)
+                                       {
+                                               int lapse = (int) temp_block.Pop();
+                                               Location lapse_location = (Location)loc_temp_block.Pop();
+                                               Report.Error(error_end_blocks[lapse,0],lapse_location,"'"+end_blocks[lapse,0]+"' is not having matching '"+end_blocks[lapse,1]+"'");
+                                       }
+                               }
+                               
+                               else {
+                                       Report.Error(error_end_blocks[BlockEnd,1],l,"'"+end_blocks[BlockEnd,1]+"' is not having  a corresponding '"+end_blocks[BlockEnd,0]+"'");
+                                       end_of_block.Push(current);     
+                                       loc_end_of_block.Push(current_loc);
+                                       while(temp_block.Count !=0) {
+                                               int lapse = (int) temp_block.Pop();
+                                               Location lapse_location = (Location)loc_temp_block.Pop();
+                                               end_of_block.Push(lapse);       
+                                               loc_end_of_block.Push(lapse_location);
+                                       }
+                               }
+                       }
+               }
+       }       
+       else {
+               while(end_of_block.Count !=0) {
+                       int lapse = (int) end_of_block.Pop();
+                        Location lapse_location = (Location)loc_end_of_block.Pop();
+                       Report.Error(error_end_blocks[lapse,0],lapse_location,"'"+end_blocks[lapse,0]+"' is not having matching '"+end_blocks[lapse,1]+"'");
+                }
+       }               
+}
+
+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)
 {
        switch (a) {
@@ -4309,14 +5487,16 @@ void CheckAttributeTarget (string a)
                break;
        }
 }
+*/
 
-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)
@@ -4328,13 +5508,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>
@@ -4354,9 +5535,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)
@@ -4383,6 +5564,7 @@ private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
        return ci;
 }
 
+/*
 void Error_ExpectingTypeName (Location l, Expression expr)
 {
        if (expr is Invocation){
@@ -4391,10 +5573,48 @@ void Error_ExpectingTypeName (Location l, Expression expr)
                Report.Error (-1, l, "Invalid Type definition");
        }
 }
+*/
+
+public static Expression SetLeftHandFlag (Expression expr) {
+       if (expr is Invocation) {
+               Invocation e = (Invocation) expr;
+               e.IsLeftHand = true;
+               return e;
+       } else if (expr is MemberAccess) {
+               MemberAccess e = (MemberAccess) expr;
+               e.IsLeftHand = true;
+               return e;
+       }
+
+       return expr;
+}
+
+public static Expression SetValueRequiredFlag (Expression expr) {
+       if (expr is Invocation) {
+               Invocation e = (Invocation) expr;
+               e.IsRetvalRequired = true;
+               expr = e;
+               return expr;
+       }
+       if (expr is Binary) {
+               Binary binary = (Binary) expr;
+               binary.Left  = SetValueRequiredFlag (binary.Left);
+               binary.Right  = SetValueRequiredFlag (binary.Right);
+               return binary;  
+       }
+       if (expr is Unary) {
+               Unary unary = (Unary) expr;
+               unary.Expr = SetValueRequiredFlag (unary.Expr);
+               return unary;
+       }
+       return expr;
+}
 
+/*
 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
        return true;
 }
+*/
 
 private void ReportError9998()
 {
@@ -4413,6 +5633,15 @@ protected override int parse ()
        tmp_blocks = new Stack(); 
        with_stack = new Stack();
        statement_stack = new Stack();  
+       end_of_block = new Stack ();
+       loc_end_of_block = new Stack ();
+       temp_block = new Stack();
+       loc_temp_block = 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;
@@ -4420,14 +5649,25 @@ protected override int parse ()
        OptionCompareBinary = InitialOptionCompareBinary;
 
        lexer = new Tokenizer (input, name, defines);
-       StringBuilder value = new StringBuilder ();
+       
+       ifElseStateMachine = new IfElseStateMachine();
+       tokenizerController = new TokenizerController(lexer);
+       
        try {
-               if (yacc_verbose_flag)
+               if (yacc_verbose_flag > 0)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
-               else
+               else {
                        yyparse (lexer);
-       } catch (Exception e) {
-               Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.ref_name + "\n" + e.ToString());
+                       cleanup();
+               }
+       } 
+       catch(MBASException e) {
+               Report.Error(e.code, e.loc, e.Message);
+       }
+       catch (Exception e) {
+               if (Report.Stacktrace)
+                       Console.WriteLine(e);
+               Report.Error (29999, lexer.Location, "Parsing error");
        }
 
        RootContext.VerifyImports();
@@ -4435,5 +5675,36 @@ protected override int parse ()
        return Report.Errors;
 }
 
+void cleanup()
+{
+       try {
+               ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
+       }
+       catch(ApplicationException) {
+               throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+       }
+
+       if(in_external_source) 
+               Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
+
+       if(in_marked_region > 0)
+               Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
+}
+
+void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
+{
+       try {
+               tokenizerController.PositionTokenizerCursor(tok, expr);
+       }
+       catch(ApplicationException) {
+               tok = IfElseStateMachine.Token.EOF;
+               try {
+                       ifElseStateMachine.HandleToken(tok);
+               }
+               catch(ApplicationException) {
+                       throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+               }
+       }
+}
 /* end end end */
 }