Anirban Bhattacharjee <banirban@novell.com>
[mono.git] / mcs / mbas / mb-parser.jay
index 4c6aebb3e573b88e891f73c4ce0d9e98f2911121..8463b685797863637342a9f23ce8bf603fd2871b 100644 (file)
@@ -3,13 +3,12 @@
 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
 //
 // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+//                Anirban Bhattacharjee (banirban@novell.com)
 //
 // Licensed under the terms of the GNU GPL
 //
 // Copyright (C) 2001 A Rafael D Teixeira
 //
-// TODO:
-//     Nearly everything
 //
 
 namespace Mono.MonoBASIC
@@ -19,11 +18,24 @@ namespace Mono.MonoBASIC
        using System.Reflection;
        using System.Collections;
        using Mono.Languages;
-       using Mono.CSharp;
+       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>
+       [DefaultParser]
        public class Parser : GenericParser
        {
        
@@ -74,7 +86,7 @@ namespace Mono.MonoBASIC
                ///   to be passed to sub/constructor  
                /// </summary>
                int current_modifiers;          
-               
+                       
                /// <summary>
                ///   This is used by the sub_header parser to store attributes
                ///   to be passed to sub/constructor  
@@ -109,9 +121,13 @@ 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;
 
                DoOptions do_type;
                //
@@ -119,22 +135,235 @@ namespace Mono.MonoBASIC
                //
                Stack switch_stack;
                
+               // Expression stack for nested ifs
+               Stack expr_stack; 
+               
+               Stack tmp_blocks;
+               Stack statement_stack;
+
+               // A stack for With expressions.
+               //
+               Stack with_stack;
+       
+               
                static public bool InitialOptionExplicit = false;
                static public bool InitialOptionStrict = false;
                static public bool InitialOptionCompareBinary = true;
+               static public ArrayList ImportsList = null;
 
                bool OptionExplicit;
                bool OptionStrict;
                bool OptionCompareBinary;
 
-               bool UseExtendedSyntax; // for ".mbs" files
+               static public bool UseExtendedSyntax; // for ".mbs" files
 
+               bool implicit_modifiers;
+               
                public override string[] extensions()
                {
                        string [] list = { ".vb", ".mbs" };
                        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;
+                               }
+                       }
+               }
 %}
 
 %token EOF
@@ -184,14 +413,15 @@ namespace Mono.MonoBASIC
 %token DECLARE
 %token DEFAULT 
 %token DELEGATE        
-%token DESCRIPTION // MonoBASIC extension
 %token DIM
+%token DIRECTCAST
 %token DO      
 %token DOUBLE  
 %token EACH    
 %token ELSE
 %token ELSEIF
-%token END     
+%token END
+%token ENDIF
 %token ENUM    
 %token EOL
 %token ERASE
@@ -205,7 +435,8 @@ namespace Mono.MonoBASIC
 %token FRIEND
 %token FUNCTION
 %token GET
-//%token GETTYPE
+%token GETTYPE
+%token GOSUB
 %token GOTO    
 %token HANDLES
 %token IF      
@@ -245,7 +476,6 @@ namespace Mono.MonoBASIC
 %token OVERLOADS
 %token OVERRIDABLE     
 %token OVERRIDES       
-%token PARAMETER // MonoBASIC extension
 %token PARAM_ARRAY
 %token PRESERVE
 %token PRIVATE 
@@ -270,10 +500,9 @@ namespace Mono.MonoBASIC
 %token STEP
 %token STOP
 %token STRICT  
-%token STRING  
+%token STRING
 %token STRUCTURE
 %token SUB
-%token SUMMARY // MonoBASIC extension
 %token SYNCLOCK
 %token TEXT
 %token THEN
@@ -285,12 +514,16 @@ namespace Mono.MonoBASIC
 %token UNICODE
 %token UNTIL
 %token VARIANT 
+%token WEND
 %token WHEN    
 %token WHILE   
 %token WITH
 %token WITHEVENTS
 %token WRITEONLY
 %token XOR
+%token YIELD // MonoBASIC extension
+
+%token HASH
 
 /* MonoBASIC single character operators/punctuation. */
 
@@ -310,23 +543,28 @@ namespace Mono.MonoBASIC
 %token OP_LT          "<"
 %token OP_GT          ">"
 %token STAR           "*"
-%token PERCENT        "%"
 %token DIV            "/"
 %token OP_EXP         "^"
 %token INTERR         "?"
-%token OP_IDIV        "\\"
+%token OP_IDIV        "\\" //FIXME: This should be "\"
 %token OP_CONCAT      "&"
-%token ATTR_ASSIGN ":="
+%token EXCLAMATION    "!"
+
+%token PERCENT        "%"
+%token LONGTYPECHAR   "&"
+%token AT_SIGN           "@"
+%token SINGLETYPECHAR "!"
+%token NUMBER_SIGN    "#"
+%token DOLAR_SIGN     "$"
+
+%token ATTR_ASSIGN       ":="
 
 /* MonoBASIC multi-character operators. */
 %token OP_LE                  "<="
 %token OP_GE                  ">="
-//%token OP_EQ                  "=="
 %token OP_NE                  "<>"
-%token OP_AND                 //"and"
-%token OP_OR                  //"or"
-%token OP_XOR                 //"xor"
-%token OP_MODULUS             //"mod"
+%token OP_XOR                 "xor"
+//%token OP_MODULUS             //"mod"
 %token OP_MULT_ASSIGN         "*="
 %token OP_DIV_ASSIGN          "/="
 %token OP_IDIV_ASSIGN         "\\="
@@ -335,6 +573,10 @@ namespace Mono.MonoBASIC
 %token OP_CONCAT_ASSIGN       "&="
 %token OP_EXP_ASSIGN          "^="
 
+/* VB.NET 2003 new bit-shift operators */
+%token OP_SHIFT_LEFT             "<<"
+%token OP_SHIFT_RIGHT         ">>"
+
 /* Numbers */
 %token LITERAL_INTEGER           "int literal"
 %token LITERAL_SINGLE            "float literal"
@@ -342,6 +584,7 @@ namespace Mono.MonoBASIC
 %token LITERAL_DECIMAL           "decimal literal"
 %token LITERAL_CHARACTER         "character literal"
 %token LITERAL_STRING            "string literal"
+%token LITERAL_DATE              "datetime literal"
 
 %token IDENTIFIER
 
@@ -362,22 +605,35 @@ namespace Mono.MonoBASIC
 %left OPEN_PARENS
 %left OPEN_BRACKET OPEN_BRACE
 %left DOT
+%right NOT
 %nonassoc HIGHPREC
 
 %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
+         opt_option_directives
          opt_imports_directives 
          opt_attributes
          opt_declarations 
          EOF
          {
-               $$ = $4;
+               $$=$5;
          }
-       ;
        
+       ;
+         
 opt_option_directives
        : /* empty */
        | option_directives
@@ -421,7 +677,7 @@ text_or_binary
        ;
          
 option_explicit_directive
-       : OPTION EXPLICIT on_off EOL
+       : OPTION EXPLICIT on_off logical_end_of_line
          {
                if (!UseExtendedSyntax)
                        OptionExplicit = (bool)$3;
@@ -434,7 +690,7 @@ option_explicit_directive
          
                        
 option_strict_directive
-       : OPTION STRICT on_off EOL
+       : OPTION STRICT on_off logical_end_of_line
          {
                if (!UseExtendedSyntax)
                        OptionStrict = (bool)$3;
@@ -446,7 +702,7 @@ option_strict_directive
        ;
          
 option_compare_directive
-       : OPTION COMPARE text_or_binary EOL
+       : OPTION COMPARE text_or_binary logical_end_of_line
          {
                OptionCompareBinary = (bool)$3;
          }
@@ -469,18 +725,10 @@ declaration
                string name = "";
                int mod_flags;
 
-               if ($1 is Class){
-                       Class c = (Class) $1;
+               if ($1 is Class || $1 is Struct || $1 is Module ){
+                       TypeContainer c = (TypeContainer) $1;
                        mod_flags = c.ModFlags;
                        name = c.Name;
-               } else if ($1 is Struct){
-                       Struct s = (Struct) $1;
-                       mod_flags = s.ModFlags;
-                       name = s.Name;
-               } else if ($1 is Module){
-                       Module m = (Module) $1;
-                       mod_flags = m.ModFlags;
-                       name = m.Name;                  
                } else
                        break;
 
@@ -501,14 +749,30 @@ identifier
        | EXPLICIT
        | OFF
        ;
-         
+
+type_character
+       : PERCENT                       { $$ = TypeManager.system_int32_expr; }
+       | LONGTYPECHAR                  { $$ = TypeManager.system_int64_expr; }
+       | AT_SIGN                       { $$ = TypeManager.system_decimal_expr; }
+       | SINGLETYPECHAR                { $$ = TypeManager.system_single_expr; }
+       | NUMBER_SIGN                   { $$ = TypeManager.system_double_expr; }
+       | DOLAR_SIGN                    { $$ = TypeManager.system_string_expr; }
+       ;       
+       
+opt_type_character
+       : /* empty */                   { $$ = null; }
+       | type_character                { $$ = $1; }
+       ;
+       
+
 qualified_identifier
        : identifier
-       | qualified_identifier DOT identifier 
+       | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
          { 
            $$ = (($1).ToString ()) + "." + ($3.ToString ()); 
          }
        ;
+       
 opt_imports_directives
        : /* empty */
        | imports_directives
@@ -520,148 +784,123 @@ 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 
          {
-               current_namespace.Using ((string) $1, lexer.Location);
+               RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
          }
-       | qualified_identifier ASSIGN qualified_identifier
+       | identifier ASSIGN namespace_or_type_name 
          {
-               current_namespace.UsingAlias ((string) $1, (string) $3, lexer.Location);
+               RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
          }
        ;
 
-opt_attributes
-       : /* empty */           
-       | attribute_sections    { $$ = $1; }
+opt_params
+       : /* empty */   { $$ = Parameters.EmptyReadOnlyParameters; }
+       | OPEN_PARENS CLOSE_PARENS      { $$ = Parameters.EmptyReadOnlyParameters; }
+       | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS    { $$ = $2; }
        ;
 
-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;
+global_attribute_list
+       : global_attribute
+       | global_attribute_list COMMA global_attribute
+       ;
 
-               if (sect.Target == "assembly")
-                       RootContext.AddGlobalAttributeSection (current_container, sect);
+global_attribute
+       : attribute_modifier COLON attribute
 
-               if ($1 != null) {
-                       attrs = (Attributes) $1;
-                       attrs.AddAttributeSection (sect);
-               }
-               
-               $$ = attrs;
-         }     
+attribute_modifier
+       : ASSEMBLY 
+       | MODULE
+       | identifier 
+          { 
+               Report.Error (658, lexer.Location, "`" + (string)$1 + "' is an invalid attribute target");
+          }
        ;
-       
-attribute_section
-       : OP_LT attribute_target_specifier attribute_list OP_GT
-         { 
-               string target = null;
-               
-               if ($2 != null)
-                       target = (string) $2;
-               
-               $$ = new AttributeSection (target, (ArrayList) $3);
-         }     
-       | OP_LT attribute_list OP_GT
-         {
-               $$ = new AttributeSection (null, (ArrayList) $2);
-         }     
-       ; 
 
-attribute_target_specifier
-       : attribute_target COLON
-         {
-               $$ = $1;
-         }
+opt_attributes
+       : /* empty */
+       | attributes    { $$ = $1; }
+       ;
+
+attr_begin
+       : OP_LT
        ;
 
-attribute_target
-       : identifier
-         {
-               CheckAttributeTarget ((string) $1);
-               $$ = $1;
-         }
-        | EVENT  { $$ = "event"; }       
-        | RETURN { $$ = "return"; }
+attr_end
+       : OP_GT
        ;
-       
+
+attributes
+       : attr_begin attribute_list attr_end
+         {
+               AttributeSection sect = new AttributeSection (null, (ArrayList) $2);
+               $$ = new Attributes (sect, lexer.Location);
+         }
+       | attr_begin global_attribute_list attr_end logical_end_of_line
+       ; 
+
 attribute_list
-       : attribute 
-         {
-               ArrayList attrs = new ArrayList ();
-               attrs.Add ($1);
+       : attribute 
+         {
+               ArrayList attrs = new ArrayList ();
+               attrs.Add ($1);
 
-               $$ = attrs;
+               $$ = attrs;
               
-         }     
-       | attribute_list COMMA attribute
-         {
-               ArrayList attrs = (ArrayList) $1;
-               attrs.Add ($3);
+         }     
+       | attribute_list COMMA attribute
+         {
+               ArrayList attrs = (ArrayList) $1;
+               attrs.Add ($3);
+
+               $$ = attrs;
+         }     
+       ;
 
-               $$ = attrs;
-         }     
-       ;
-       
 attribute 
-       : attribute_name
-         {
-               $$ = lexer.Location;
-         }
-         opt_attribute_arguments
-         {
-               $$ = new Mono.CSharp.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
-         }       
-       ;
-       
+       : attribute_name
+         {
+               $$ = lexer.Location;
+         }
+         opt_attribute_arguments
+         {
+               $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+         }       
+       ;
+
 attribute_name
-       : type_name 
+       : namespace_or_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
          {
@@ -681,21 +920,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));
@@ -722,7 +955,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, 
@@ -731,21 +964,12 @@ named_argument
        ;
                                
 namespace_declaration
-       : opt_attributes NAMESPACE qualified_identifier EOL
+       : NAMESPACE qualified_identifier logical_end_of_line
          {
-               Attributes attrs = (Attributes) $1;
-
-               if (attrs != null) {
-                       foreach (AttributeSection asec in attrs.AttributeSections)
-                               if (asec.Target == "assembly")
-                                       RootContext.AddGlobalAttributeSection (current_container, asec);
-               }
-                         
-               current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
+               current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2);
          } 
-         opt_imports_directives
          opt_declarations
-         END NAMESPACE EOL
+         END NAMESPACE logical_end_of_line
          { 
                current_namespace = current_namespace.Parent;
          }
@@ -771,13 +995,18 @@ type_spec_declaration
        ;
 
 class_declaration
-       : CLASS identifier EOL opt_class_base
+       : CLASS identifier logical_end_of_line 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.
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+         
                Class new_class;
                string name;
                
                name = MakeName ((string) $2);
-
                new_class = new Class (current_container, name, current_modifiers, 
                                       (Attributes) current_attributes, lexer.Location);
 
@@ -786,10 +1015,20 @@ class_declaration
                RootContext.Tree.RecordDecl (name, new_class);
          }
          opt_class_member_declarations
-         END CLASS EOL
+         END CLASS logical_end_of_line
          {
                Class new_class = (Class) current_container;
-               new_class.Bases = (ArrayList) $4;       
+               
+               ArrayList bases = (ArrayList) $4;
+
+               ArrayList ifaces = (ArrayList) $5;
+               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);
@@ -798,20 +1037,16 @@ class_declaration
          }
        ;
 
-opt_class_base
-       : /* empty */           { $$ = null; }
-       | class_base            { $$ = $1; }
+opt_inherits
+       : /* empty */                           { $$ = null; }
+       | INHERITS type_list logical_end_of_line        { $$ = $2; }
        ;
 
-class_base
-       : inherits_or_implements type_list EOL { $$ = $2; }
+opt_implements
+       : /* empty */                           { $$ = null; }
+       | IMPLEMENTS type_list logical_end_of_line      { $$ = $2; }
        ;
 
-inherits_or_implements
-       : INHERITS
-       | IMPLEMENTS
-       ;
-       
 opt_modifiers
        : /* empty */           { $$ = (int) 0; current_modifiers = 0; }
        | modifiers             { $$ = $1; current_modifiers = (int) $1; }
@@ -833,35 +1068,47 @@ modifiers
         ;
 
 modifier
-       : PUBLIC                { $$ = Modifiers.PUBLIC; }
-       | PROTECTED             { $$ = Modifiers.PROTECTED; }
-       | PRIVATE               { $$ = Modifiers.PRIVATE; }
-       | SHARED                { $$ = Modifiers.STATIC; }
-       | FRIEND                { $$ = Modifiers.INTERNAL; }
+       : PUBLIC                        { $$ = Modifiers.PUBLIC; }
+       | PROTECTED                     { $$ = Modifiers.PROTECTED; }
+       | PRIVATE                       { $$ = Modifiers.PRIVATE; }
+       | SHARED                        { $$ = Modifiers.STATIC; }
+       | FRIEND                        { $$ = Modifiers.INTERNAL; }
+       | NOTINHERITABLE                { $$ = Modifiers.SEALED; } 
+       | OVERRIDABLE                   { $$ = Modifiers.VIRTUAL; }
+       | NOTOVERRIDABLE                { $$ = Modifiers.NONVIRTUAL; }
+       | OVERRIDES                     { $$ = Modifiers.OVERRIDE; }
+       | OVERLOADS                     { $$ = Modifiers.NEW; }
+       | SHADOWS                       { $$ = Modifiers.SHADOWS; }
+       | MUSTINHERIT                   { $$ = Modifiers.ABSTRACT; }
+       | READONLY                      { $$ = Modifiers.READONLY; }
+       | DEFAULT                       { $$ = Modifiers.DEFAULT; }
+       | WRITEONLY                     { $$ = Modifiers.WRITEONLY; }
        ;
 
 module_declaration
-       : MODULE identifier EOL
+       : MODULE identifier logical_end_of_line
          { 
                Module new_module;
                string name;
                name = MakeName((string) $2);
                new_module = new Module(current_container, 
-                                                               name, 
-                                                               current_modifiers, // already checks then
-                                                               (Attributes) current_attributes,
-                                                               lexer.Location);
+                                       name, 
+                                       current_modifiers, // already checks then
+                                       (Attributes) current_attributes,
+                                       lexer.Location);
                current_container = new_module;
                current_container.Namespace = current_namespace;
                RootContext.Tree.RecordDecl(name, new_module);
          }
-         opt_class_member_declarations
-         END MODULE EOL
+         opt_module_member_declarations
+         END MODULE logical_end_of_line
          {
                Module new_module = (Module)current_container;
 
                current_container = current_container.Parent;
                CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
+               
+               TypeManager.AddStandardModule(new_module);
 
                $$ = new_module;
          }
@@ -882,16 +1129,19 @@ module_member_declaration
           opt_modifiers
           { 
                current_attributes = (Attributes) $1;
-               current_modifiers = (int) $2 | (int)Modifiers.STATIC; // FIXME: for type_declaration it can result in trouble
+               current_modifiers = ((int)$2) | Modifiers.STATIC; 
+               bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
+               implicit_modifiers = (!explicit_static);
           }
           module_member_declarator
           {
+               implicit_modifiers = false;
                $$ = $3;
           }
        ;
 
 module_member_declarator
-       :  static_constructor_declaration
+       :  constructor_declaration
        |  method_declaration
           { 
                Method method = (Method) $1;
@@ -902,12 +1152,40 @@ module_member_declarator
        |  constant_declaration
        |  property_declaration                 
        |  event_declaration    
-       |  type_declaration                     
+       |  type_spec_declaration                        
        ;
        
-constant_declaration // TODO: implement truly the logic
-       : CONST identifier ASSIGN constant_expression
-       | CONST identifier AS qualified_identifier ASSIGN constant_expression
+constant_declaration
+       : CONST constant_declarators logical_end_of_line
+       {
+               // 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
+               // instead of triggering an error.
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+               
+               int mod = (int) current_modifiers;
+               
+               // Structure members are Public by default                      
+               if ((current_container is Struct) && (mod == 0))
+                       mod = Modifiers.PUBLIC;                 
+
+               ArrayList consts = (ArrayList) $2;
+               if(consts.Count > 0) 
+               {
+                       VariableDeclaration.FixupTypes ((ArrayList) $2);
+                       VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
+
+                       foreach (VariableDeclaration var in (ArrayList) $2){
+                               Location l = var.Location;
+                               Const vconstant = new Const ((Expression)var.type, (String)var.identifier, 
+                                                       (Expression)var.expression_or_array_initializer, 
+                                                       mod, (Attributes) null, l);
+
+                               CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
+                       }
+               }
+       }
        ;
           
 opt_class_member_declarations
@@ -925,7 +1203,7 @@ class_member_declaration
           opt_modifiers
           { 
                current_attributes = (Attributes) $1;
-               current_modifiers = (int) $2; 
+               current_modifiers = (int) $2;
           }
           class_member_declarator
           {
@@ -945,119 +1223,167 @@ class_member_declarator
        |  property_declaration                 
        |  event_declaration    
        |  withevents_declaration       /* This is a field but must be treated specially, see below */
-       |  type_declaration                     
+       |  type_spec_declaration
        ;
        
        
 method_declaration
        : sub_declaration
        | func_declaration 
+       | must_override_declaration
+       ;
+       
+must_override_declaration
+       : must_override_sub_declaration
+       | must_override_func_declaration        
+       ;
+       
+must_override_sub_declaration
+       : MUSTOVERRIDE SUB identifier opt_params logical_end_of_line
+         {     
+               if (current_container is Module)
+                       Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
+                       
+               if (current_container is Struct)
+                       Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+               
+               current_modifiers |= Modifiers.ABSTRACT;
+                                       
+               Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
+                                           (Parameters) $4, null, null, lexer.Location);
+                                           
+               if (!(current_container is Class))
+                       Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");               
+                       
+               $$ = method;                        
+         }
+       ;
+
+       
+must_override_func_declaration
+       : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
+         {     
+               Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.  
+                       system_object_expr : (Expression) $4 ) : (Expression) $6;
+
+               if (current_container is Module)
+                       Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
+                       
+               if (current_container is Struct)
+                       Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+                               
+               current_modifiers |= Modifiers.ABSTRACT;
+                                                       
+               Method method = new Method ((Expression) ftype, (int) current_modifiers, 
+                                               (string) $3,(Parameters) $5, null, null, 
+                                               lexer.Location);
+                                           
+               if (!(current_container is Class))
+                       Report.Error (9999, "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 opt_params opt_evt_handler opt_implement_clause logical_end_of_line
          { 
-               
-               current_local_parameters = (Parameters) $4;
+               current_local_parameters = (Parameters) $3;
                start_block(); 
 
-               /* This is WEIRD: declaring a method (sub) in a module as static will
-                  trigger a syntax error, but the same methods MUST be static in order
-                  to be properly called
-               */
-               if (current_container is Module) {
-                       if (current_modifiers == Modifiers.STATIC) {
-                               Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
-                       }
-                       else
-                       {
-                               current_modifiers = Modifiers.STATIC;
-                       }
-               }
-               
                // Structure members are Public by default                      
                if ((current_container is Struct) && (current_modifiers == 0))
-                       current_modifiers = Modifiers.PUBLIC;                   
+                       current_modifiers = Modifiers.PUBLIC;           
+
+               member_location = lexer.Location;
          }
          opt_statement_list 
-         END SUB EOL
+         END SUB logical_end_of_line
          {
                Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
-                                           (Parameters) current_local_parameters, null, (Expression) $7
-                                           lexer.Location);
+                                           (Parameters) current_local_parameters, (Attributes) current_attributes
+                                           (ArrayList) $5, member_location);
        
                method.Block = (Block) end_block();
                $$ = method;
 
-               if ($6 != null) { /* we have an event handler to take care of */
-                       // This wouldn't work: AddHandler ((Expression)$6, (string) $2);
+               if ($4 != null) { 
+                       // we have an event handler to take care of 
+
                        string evt_def = ((MemberAccess)$6).ToString();
                        int pos = evt_def.LastIndexOf (".");
-                       string evt_target = ((string) $2).Substring (0, pos);
+                       string evt_target = evt_def.Substring (0, pos);
+                       bool found = false;
+               
+                       if (current_container.Properties != null) {
+                               foreach (Property p in current_container.Properties) {
+                                       if (p.Name == evt_target) {
+                                               Location loc = lexer.Location;
+
+                                               Statement addhnd = (Statement) new AddHandler ((Expression) $4, 
+                                                                                       DecomposeQI((string) $2, loc), 
+                                                                                       DecomposeQI(evt_target, loc), loc);
+
+                                               current_container.AddEventHandler (addhnd);
+                                               found = true;
+                                               break;
+                                       }
+                               }               
+                       }
 
-                       foreach (Property p in current_container.Properties) {
-                               if (p.Name == evt_target) {
-                                       // FIXME: See below 
-                                       // RemoveHandler (p.Set.Block, (Expression)$6, (string) $2);
-                                       AddHandler (p.Set.Block, (Expression)$6, (string) $2);
-                                       break;
-                               }
-                       }                               
+                       if (!found){
+                               Report.Error(30506, lexer.Location,
+                                               evt_target + " is not declared with WithEvents");
+                       }
                }       
          }       
        ;
        
 func_declaration
-       : FUNCTION identifier 
-         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type opt_implement_clause EOL
+       : FUNCTION identifier opt_type_character
+         opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
          { 
-               
                current_local_parameters = (Parameters) $4;
+               member_location = lexer.Location;
                start_block(); 
-       
-               /* This is WEIRD: declaring a method (sub) in a module as static will
-                  trigger a syntax error, but the same methods MUST be static in order
-                  to be properly called
-               */
-               if (current_container is Module) {
-                       if (current_modifiers == Modifiers.STATIC) {
-                               Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
-                       }
-                       else
-                       {
-                               current_modifiers = Modifiers.STATIC;
-                       }                       
-               }
-               
+                               
+               Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+
                // Structure members are Public by default                      
                if ((current_container is Struct) && (current_modifiers == 0))
                        current_modifiers = Modifiers.PUBLIC;                           
                // Add local var declaration
                // for return value
                ArrayList retval = new ArrayList ();
-               retval.Add (new VariableDeclaration ((string) $2, (Expression) $7, lexer.Location));
-               declare_local_variables ((Expression) $7, retval, lexer.Location);
+               retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
+               declare_local_variables ((Expression) ftype, retval, lexer.Location);
          }       
          opt_statement_list
-         END FUNCTION EOL
+         END FUNCTION logical_end_of_line
          {
-               Method method = new Method ((Expression) $7, (int) current_modifiers, (string) $2,
-                                           (Parameters) current_local_parameters, null, 
-                                           (Expression) $7, lexer.Location);
-       
+               Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+
+               Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
+                                           (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes,  */
+                                           (ArrayList) $6, member_location);
                method.Block = end_block();
                $$ = method;
-
          }       
        ;               
 
 struct_declaration
-       : STRUCTURE identifier EOL
+       : STRUCTURE identifier logical_end_of_line
          opt_implement_clause
          {
                Struct new_struct;
                string full_struct_name = MakeName ((string) $2);
-
+               
+               // 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
+               // instead of triggering an error.
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+                       
                new_struct = new Struct (current_container, full_struct_name, 
                                         (int) current_modifiers,
                                         (Attributes) current_attributes, lexer.Location);
@@ -1076,7 +1402,7 @@ struct_declaration
                CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
                $$ = new_struct;
          }
-         END STRUCTURE EOL
+         END STRUCTURE logical_end_of_line
        ;
        
 opt_struct_member_declarations
@@ -1093,14 +1419,19 @@ struct_member_declaration
        : opt_modifiers
          struct_member_declarator
        ;
+       
 struct_member_declarator       
        : field_declaration
-       //| constant_declaration
+       | constant_declaration
+       | constructor_declaration
        | method_declaration
+         { 
+               Method method = (Method) $1;
+               CheckDef (current_container.AddMethod (method), method.Name, method.Location);
+         }     
        | property_declaration
        | event_declaration
-       | constructor_declaration
-       | type_declaration
+       | type_spec_declaration
 
        /*
         * This is only included so we can flag error 575:
@@ -1110,34 +1441,76 @@ struct_member_declarator
        ;
        
 event_declaration
-       : EVENT identifier AS type EOL
+       : EVENT identifier AS type opt_implement_clause logical_end_of_line
          {
                VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
 
                Event e = new Event ((Expression) $4, var.identifier, 
                                     null, current_modifiers, null, null, 
-                                    current_attributes, lexer.Location);
+                                    current_attributes, (ArrayList) $5,
+                                    lexer.Location);
 
                CheckDef (current_container.AddEvent (e), e.Name, e.Location);
-
          }
-//     | EVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
-//       {
-//             throw new NotSupportedException();
-//       }
-       ;       
-
-enum_declaration
-       : ENUM identifier opt_type_spec EOL
-         opt_enum_member_declarations
-         { 
-               Location enum_location = lexer.Location;
+       | EVENT identifier opt_params opt_implement_clause logical_end_of_line
+         {
+               string delName = null;
 
-               string full_name = MakeName ((string) $2);
-               Mono.CSharp.Enum e = new Mono.CSharp.Enum (current_container, (Expression) $3, (int) current_modifiers, full_name, 
-                                  (Attributes) current_attributes, enum_location);
+               if ($4 == 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) $3, 
+                                                       (Attributes) current_attributes, lexer.Location);
+                                                         
+                       del.Namespace = current_namespace;
+                       CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
+               } else {
+                       ArrayList impls = (ArrayList) $4;
+                       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, lexer.Location, expstr);
+                       }                       
+                       Expression impl = (Expression) impls[0];  
+                       delName = impl.ToString();
+                       delName = delName.Substring (delName.LastIndexOf(".") + 1);
+                       delName = delName + "EventHandler";
+               }
+               
+               Event e = new Event (DecomposeQI (delName, lexer.Location),
+                                        (string) $2, 
+                                    null, current_modifiers, null, null, 
+                                    current_attributes, (ArrayList) $4, 
+                                    lexer.Location);
+
+               CheckDef (current_container.AddEvent (e), e.Name, e.Location);
+         }
+       ;
+       
+enum_declaration
+       : ENUM identifier opt_type_spec logical_end_of_line
+         opt_enum_member_declarations // FIXME: BC30280: Enum must contain atleast one member
+         { 
+               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;
+               
+               // Module members are static by default, but enums *can't* be declared static
+               // so we must fix it if mbas was the one actually responsible for this
+               // instead of triggering an error.
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+                       
+               Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type, 
+                                       (int) current_modifiers, full_name, 
+                                       (Attributes) current_attributes, enum_location);
                
-               foreach (VariableDeclaration ev in (ArrayList) $5) {
+               foreach (VariableDeclaration ev in enum_members) {
                        Location loc = (Location) ev.Location;
 
                        CheckDef (e.AddEnumMember (ev.identifier, 
@@ -1151,7 +1524,7 @@ enum_declaration
                RootContext.Tree.RecordDecl (full_name, e);
 
          }
-         END ENUM EOL
+         END ENUM logical_end_of_line
        ;
 
 opt_enum_member_declarations
@@ -1178,7 +1551,7 @@ enum_member_declarations
        ;
 
 enum_member_declaration
-       : opt_attributes identifier EOL
+       : opt_attributes identifier logical_end_of_line
          {
                $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
          }
@@ -1186,14 +1559,14 @@ enum_member_declaration
          {
                  $$ = lexer.Location;
          }
-          ASSIGN expression EOL
+          ASSIGN expression logical_end_of_line
          { 
                $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
          }
        ;
                
 interface_declaration
-       : INTERFACE identifier EOL
+       : INTERFACE identifier logical_end_of_line
          {
                Interface new_interface;
                string full_interface_name = MakeName ((string) $2);
@@ -1221,7 +1594,7 @@ interface_declaration
                          new_interface.Name, new_interface.Location);
 
          }
-         END INTERFACE EOL
+         END INTERFACE logical_end_of_line
        ;
 
 opt_interface_base
@@ -1264,75 +1637,199 @@ 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 logical_end_of_line
          {
-               $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
-                                         (Parameters) $4, current_attributes, lexer.Location);
+               Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
+                                           (Parameters) $3, current_attributes, null, lexer.Location);
+               
+               $$ = method;
          }
-       | FUNCTION identifier
-         OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
+       | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
          {
-               $$ = new InterfaceMethod (
-                                         (Expression) $7, (string) $2, false, (Parameters) $4,
-                                         current_attributes, lexer.Location);
+               Expression ftype = ($5 == null) ? (($3 == null) ? TypeManager.  
+                       system_object_expr : (Expression) $3 ) : (Expression) $5;
+               
+               Method method = new Method ((Expression) ftype, (int) current_modifiers, 
+                                               (string) $2,(Parameters) $4, current_attributes, null, 
+                                               lexer.Location);
+               
+               $$ = method;
          }
        ;
 
 interface_property_declaration
-       : PROPERTY identifier
-         OPEN_PARENS
-         opt_formal_parameter_list
-         CLOSE_PARENS opt_type_spec EOL
+       : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec 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 = ($5 == null) ? (($3 == null) ? 
+                               TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+
+               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);
+                       
+                       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 ,lexer.Location); 
+                       
+                       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, lexer.Location,
+                                        null, get_parameters, set_parameters, null);
+    
+               CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
+               
+               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 type logical_end_of_line
+         {
+               VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
+
+               Event e = new Event ((Expression) $4, var.identifier, 
+                                    null, current_modifiers, null, null, 
+                                    current_attributes, lexer.Location);
+
+               CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
+
+         }
+       | EVENT identifier opt_params 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, lexer.Location);
+                                                 
+               del.Namespace = current_namespace;
+               CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
+         
+               Event e = new Event (DecomposeQI (delName, lexer.Location),
+                                        (string) $2, 
+                                    null, current_modifiers, null, null, 
+                                    current_attributes, lexer.Location);
+
+               CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
          }
        ;
 
 property_declaration
-         : PROPERTY identifier opt_property_parameters AS type opt_implement_clause EOL
+       : abstract_propery_declaration
+       | non_abstract_propery_declaration 
+       ;
+       
+abstract_propery_declaration
+       : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec logical_end_of_line
+         {     
+               Expression ftype = ($6 == null) ? (($4 == null) ? 
+                               TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
+
+               if (current_container is Module)
+                       Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
+                       
+               if (current_container is Struct)
+                       Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+                               
+               current_modifiers |= Modifiers.ABSTRACT;
+               
+               current_local_parameters = (Parameters) $5;
+               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
+               {
+                       get_parameters = Parameters.EmptyReadOnlyParameters;
+                       set_parameters = new Parameters (null, null ,lexer.Location); 
+                       
+                       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) $3, current_modifiers, 
+                                        get_block, set_block, current_attributes, lexer.Location,
+                                        null, get_parameters, set_parameters, null);
+    
+               if (!(current_container is Class))
+                       Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
+                       
+               CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
+               
+               get_implicit_value_parameter_type = null;
+               set_implicit_value_parameter_type = null;
+               get_parameters = null;
+               set_parameters = null;
+               current_local_parameters = null;                                
+         }     
+       ;
+       
+       
+ non_abstract_propery_declaration
+         : PROPERTY identifier opt_type_character opt_property_parameters opt_type_spec opt_implement_clause logical_end_of_line
          {
-               get_implicit_value_parameter_type = (Expression) $5;
+               get_implicit_value_parameter_type  = 
+                       ($5 == null) ? (($3 == null) ? 
+                               TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
                get_implicit_value_parameter_name = (string) $2;
                
-               current_local_parameters = (Parameters) $3;
+               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);
@@ -1347,24 +1844,34 @@ property_declaration
                $$ = lexer.Location;
          }
          accessor_declarations 
-         END PROPERTY EOL
+         END PROPERTY logical_end_of_line
          {
                lexer.PropertyParsing = false;
 
                Property prop;
                Pair pair = (Pair) $9;
-               Accessor get_block = (Accessor) pair.First;
-               Accessor set_block = (Accessor) pair.Second;
-
+               
+               Accessor get_block = null;
+               Accessor set_block = null;
+               
+               if (pair.First != null){
+                       get_block = (Accessor) pair.First;
+               }
+               
+               if (pair.Second != null) {
+                       set_block = (Accessor) pair.Second;
+               }
+               
                Location loc = lexer.Location;
                
                // Structure members are Public by default                      
                if ((current_container is Struct) && (current_modifiers == 0))
                        current_modifiers = Modifiers.PUBLIC;                           
                        
-               prop = new Property ((Expression) $5, (string) $2, current_modifiers, get_block, set_block,
+               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) $6);
+                                    get_parameters, set_parameters, (ArrayList) $6);
                
                CheckDef (current_container.AddProperty (prop), prop.Name, loc);
                get_implicit_value_parameter_type = null;
@@ -1391,10 +1898,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
@@ -1419,8 +1942,11 @@ opt_set_accessor_declaration
        ;
 
 get_accessor_declaration
-       : opt_attributes GET EOL
+       : opt_attributes GET logical_end_of_line
          {
+               if ((current_modifiers & Modifiers.WRITEONLY) != 0)
+                       Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
+         
                current_local_parameters = get_parameters;
                
                lexer.PropertyParsing = false;
@@ -1431,10 +1957,9 @@ get_accessor_declaration
                ArrayList retval = new ArrayList ();
                retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
                declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);    
-               
          }
-          opt_statement_list
-          END GET EOL
+         opt_statement_list
+         END GET logical_end_of_line
          {
                $$ = new Accessor ((Block) end_block(), (Attributes) $1);
                current_local_parameters = null;
@@ -1443,8 +1968,11 @@ get_accessor_declaration
        ;
 
 set_accessor_declaration
-       : opt_attributes SET opt_set_parameter EOL
+       : opt_attributes SET opt_set_parameter logical_end_of_line
          {
+        if ((current_modifiers & Modifiers.READONLY) != 0)
+                       Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
+                       
                Parameter implicit_value_parameter = new Parameter (
                        set_implicit_value_parameter_type, 
                        set_implicit_value_parameter_name, 
@@ -1457,7 +1985,7 @@ set_accessor_declaration
                lexer.PropertyParsing = false;
          }
          opt_statement_list
-         END SET EOL
+         END SET logical_end_of_line
          {
                $$ = new Accessor ((Block) end_block(), (Attributes) $1);
                current_local_parameters = null;
@@ -1468,17 +1996,31 @@ set_accessor_declaration
 opt_set_parameter
        : /* empty */
        {
-               set_implicit_value_parameter_type = (Expression) TypeManager.system_object_expr;
+               set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
                set_implicit_value_parameter_name = "Value";
        }       
-       | OPEN_PARENS opt_identifier opt_type_spec CLOSE_PARENS
+       |OPEN_PARENS CLOSE_PARENS
        {
-               /* FIXME: possible syntax error which must be caught
-                  Set ( As <type>) is currently (and wrongly so) legal
-               */
-               set_implicit_value_parameter_type = (Expression) $3;
+               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
+       {
+               Parameter.Modifier pm = (Parameter.Modifier)$2;
+               if ((pm | Parameter.Modifier.VAL) != 0)
+                       Report.Error (31065, 
+                               lexer.Location, 
+                               "Set cannot have a paremeter modifier other than 'ByVal'");
+                               
+               set_implicit_value_parameter_type = (Expression) $4;
+               
+               if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
+                       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) $2;
+                       set_implicit_value_parameter_name = (string) $3;
                else
                        set_implicit_value_parameter_name = "Value";
        }
@@ -1486,10 +2028,9 @@ opt_set_parameter
                        
 field_declaration
        : opt_dim_stmt 
-         variable_declarators EOL
+         variable_declarators logical_end_of_line
          {               
                int mod = (int) current_modifiers;
-               
 
                VariableDeclaration.FixupTypes ((ArrayList) $2);
                VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
@@ -1500,10 +2041,12 @@ field_declaration
                // Structure members are Public by default                      
                if ((current_container is Struct) && (mod == 0))
                        mod = Modifiers.PUBLIC;                 
+               
+               if ((mod & Modifiers.Accessibility) == 0)
+                       mod |= Modifiers.PRIVATE;
                                        
                foreach (VariableDeclaration var in (ArrayList) $2){
                        Location l = var.Location;
-
                        Field field = new Field (var.type, mod, var.identifier, 
                                                 var.expression_or_array_initializer, 
                                                 (Attributes) null, l);
@@ -1514,14 +2057,20 @@ field_declaration
        ;
        
 withevents_declaration
-       : 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
+               // instead of triggering an error.
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+         
                /* WithEvents Fields must be resolved into properties
                   with a bit of magic behind the scenes */
                  
-               VariableDeclaration.FixupTypes ((ArrayList) $2);
+               VariableDeclaration.FixupTypes ((ArrayList) $3);
                
-               foreach (VariableDeclaration var in (ArrayList) $2) {
+               foreach (VariableDeclaration var in (ArrayList) $3) {
                        // 1 - We create a private field
                        Location l = var.Location;
                        Property prop;
@@ -1531,7 +2080,7 @@ withevents_declaration
                        Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier, 
                                                 var.expression_or_array_initializer, 
                                                 (Attributes) null, l);
-
+                                                
                        CheckDef (current_container.AddField (field), field.Name, l);   
                        
                        // 2 - Public property
@@ -1555,12 +2104,19 @@ delegate_declaration
          identifier OPEN_PARENS 
          opt_formal_parameter_list
          CLOSE_PARENS 
-         EOL
+         logical_end_of_line
          {
                Location l = lexer.Location;
-               Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (current_container, TypeManager.system_void_expr, 
+               // 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.
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+                                       
+               Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container, 
+                                                TypeManager.system_void_expr, 
                                             (int) current_modifiers, 
-                                            MakeName ((string) $3), (Parameters) $5, 
+                                MakeName ((string) $3), (Parameters) $5, 
                                             (Attributes) current_attributes, l);
                                                  
                del.Namespace = current_namespace;
@@ -1569,12 +2125,21 @@ delegate_declaration
        | DELEGATE FUNCTION       
          identifier OPEN_PARENS 
          opt_formal_parameter_list
-         CLOSE_PARENS AS type
+         CLOSE_PARENS opt_type_spec logical_end_of_line
          {
                Location l = lexer.Location;
-               Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (
+               
+               // 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.
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+                       
+               Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
+                       
+               Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
                        current_container,
-                       (Expression) $8, (int) current_modifiers, MakeName ((string) $3), 
+                       ftype, (int) current_modifiers, MakeName ((string) $3), 
                        (Parameters) $5, (Attributes) current_attributes, l);
 
                del.Namespace = current_namespace;
@@ -1584,49 +2149,28 @@ delegate_declaration
        
 opt_evt_handler
        : /* empty */
-       {       $$ = null; }
+         {     $$ = null; }
        | HANDLES qualified_identifier
-       {
-               $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);     
-       }
-       ;       
-
-opt_empty_parens
-       : /* empty */
-       | OPEN_PARENS CLOSE_PARENS
-       ;       
-       
-static_constructor_declaration
-       : SHARED SUB NEW opt_empty_parens EOL
          {
-               current_local_parameters = Parameters.EmptyReadOnlyParameters;
-               start_block();
-               oob_stack.Push (lexer.Location);
-
-               Location l = (Location) oob_stack.Pop ();
-               $$ = new Constructor ((string) "New", Parameters.EmptyReadOnlyParameters, (ConstructorInitializer) null, l);
+               $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);     
          }
-         opt_statement_list
-         { 
-               Constructor c = (Constructor) $1;
-               c.Block = (Block) end_block();
-               c.ModFlags = (int) current_modifiers;
-               c.OptAttributes = current_attributes;
-               
-               CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
-               current_local_parameters = null;
+       | HANDLES MYBASE DOT qualified_identifier
+         {
+               // FIXME: this is blatantly wrong and crash-prone
+               $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
          }
-         END SUB EOL
-       
+       ;       
+
 constructor_declaration
-       : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
+       : SUB NEW opt_params logical_end_of_line
          {
-               current_local_parameters = (Parameters) $4;
+               current_local_parameters = (Parameters) $3;
                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) $3, (ConstructorInitializer) null, l);
+               $1 = $$;
          }
          opt_statement_list
          { 
@@ -1635,10 +2179,12 @@ constructor_declaration
                c.ModFlags = (int) current_modifiers;
                c.OptAttributes = current_attributes;
                
+               c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
+
                CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
                current_local_parameters = null;
          }
-         END SUB EOL
+         END SUB logical_end_of_line
        ;
        
 opt_formal_parameter_list
@@ -1697,36 +2243,53 @@ fixed_parameters
 fixed_parameter
        : opt_attributes
          opt_parameter_modifier
-         identifier opt_type_spec opt_variable_initializer
+         identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
          {
                Parameter.Modifier pm = (Parameter.Modifier)$2;
                bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
+               Expression ptype;
                
-               if (opt_parm && ($5 == null))
-                       Report.Error (999, "Optional parameters must have a default value");
+               if (opt_parm && ($7 == null))
+                       Report.Error (30812, "Optional parameters must have a default value");
                
                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
-               }                       
-               $$ = new Parameter ((Expression) $4, (string) $3, 
-                                       pm, (Attributes) $1, (Expression) $5, opt_parm);
+               }       
+               
+               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);
+               }                       
+               $$ = new Parameter (ptype, (string) $3, pm,
+                                       (Attributes) $1, (Expression) $7, opt_parm);
          }
        ;
        
 parameter_array
        : PARAM_ARRAY identifier opt_parens AS type 
          { 
-               $$ = new Parameter ((Expression) $5, (string) $2, Parameter.Modifier.PARAMS, null);
+               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
@@ -1747,41 +2310,79 @@ parameter_modifier
 
 opt_statement_list
        : /* empty */
-       | statement_list EOL
+       | statement_list end_of_stmt
        ;
 
 statement_list
        : statement 
-       | statement_list EOL statement
+       | statement_list end_of_stmt statement
        ;
        
 statement : 
            declaration_statement
            {
-               if ($1 != null && (Block) $1 != current_block){
+                 if ($1 != null && (Block) $1 != current_block){
                        current_block.AddStatement ((Statement) $1);
                        current_block = (Block) $1;
-               }
+                 }
            }
-         | embedded_statement 
+         | embedded_statement
            {
-               Statement s = (Statement) $1;
+                 Statement s = (Statement) $1;
 
-               current_block.AddStatement ((Statement) $1);
+                 current_block.AddStatement ((Statement) $1);
            } 
          | labeled_statement 
          | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
-          {
-               AddHandler ((Expression) $2, (string) $5);
-          }
-         | RAISEEVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
            {
-               RaiseEvent ((string) $2, (ArrayList) $4);
+                 AddHandler ((Expression) $2, (string) $5);
            }
+         | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
+               {
+                 RemoveHandler ((Expression) $2, (string) $5);
+           }
+         | RAISEEVENT identifier opt_raise_event_args  //OPEN_PARENS opt_argument_list CLOSE_PARENS
+           {
+             RaiseEvent ((string) $2, (ArrayList) $3);
+           }
+         /* | array_handling_statement */
+         /* | empty_statement */
+         | with_statement 
+           {
+                 Statement s = (Statement) $1;
+
+             current_block.AddStatement ((Statement) $1);
+           }     
          ;     
+         
+opt_raise_event_args 
+       : /* empty */   { $$ = null; }
+       | OPEN_PARENS opt_argument_list CLOSE_PARENS
+         {
+               $$ = $2;
+         }
+       ;
+
+label_name
+       : identifier
+       | LITERAL_INTEGER
+       {
+               $$ = $1.ToString();
+       }
+       ;
 
 labeled_statement
-       : identifier COLON 
+       : 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);
 
@@ -1799,27 +2400,149 @@ embedded_statement
        | selection_statement
        | iteration_statement
        | try_statement
-       | jump_statement 
+       | synclock_statement
+       | jump_statement
+       | array_handling_statement 
        ;
-        
+/*        
+empty_statement
+       : end_of_stmt
+         {
+                 $$ = new EmptyStatement ();
+         }
+       ;        
+*/
+
+with_statement
+       : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
+         {
+               // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
+               Expression e = (Expression) $2;
+               with_stack.Push(e);
+               start_block();
+         }
+         opt_statement_list
+         END WITH
+         {
+               Block b = end_block();
+               with_stack.Pop();
+               $$ = b;
+         }
+       ;
+       
+       
+array_handling_statement
+       : redim_statement
+       | erase_statement
+       ;
+       
+redim_statement
+       : REDIM opt_preserve redim_clauses
+         {
+               ArrayList list = (ArrayList) $3;
+               ReDim r = new ReDim (list, (bool) $2, lexer.Location);
+               $$ = r;
+
+         }
+       ;
+       
+opt_preserve
+       : /* empty */   { $$ = false; }
+       | PRESERVE      { $$ = true;  }
+       ;
+       
+redim_clauses
+       : redim_clause
+         {
+               ArrayList clauses = new ArrayList ();
+
+               clauses.Add ($1);
+               $$ = clauses;
+         }
+       | redim_clauses COMMA redim_clause
+         {
+               ArrayList clauses = (ArrayList) ($1);
+               clauses.Add ($2);
+
+               $$ = clauses;
+         }
+       ;
+
+redim_clause
+       : invocation_expression
+         {
+               Invocation i = (Invocation) $1;
+               RedimClause rc = new RedimClause (i.expr, i.Arguments);
+               $$ = rc;
+         }
+       ;
+
+erase_statement
+       : ERASE erase_clauses
+       {
+               ArrayList list = (ArrayList) $2;
+               foreach(Expression e in list)
+               {
+                       Erase r = new Erase (e, lexer.Location);
+                       $$ = r;
+               }
+       }
+       ;
+
+erase_clauses
+       : erase_clause
+         {
+               ArrayList clauses = new ArrayList ();
+
+               clauses.Add ($1);
+               $$ = clauses;
+         }
+       | erase_clauses COMMA erase_clause
+         {
+               ArrayList clauses = (ArrayList) ($1);
+               clauses.Add ($2);
+
+               $$ = clauses;
+         }
+       ;
+
+erase_clause
+       : primary_expression
+       ;       
+                       
 jump_statement
        : /*break_statement
        | continue_statement
-       | goto_statement
-       | throw_statement
        | */return_statement
+       | goto_statement        
+       | throw_statement       
        | exit_statement
+       | yield_statement
        ;
                
-exit_statement
-       : EXIT exit_type
+goto_statement
+       : GOTO label_name  
          {
-               $$ = new Exit ((ExitType)$2, lexer.Location);           
+               $$ = new Goto (current_block, (string) $2, lexer.Location);
          }
        ;
        
-exit_type
-       : DO            { $$ = ExitType.DO;             }
+throw_statement
+       : THROW opt_expression
+         {
+               $$ = new Throw ((Expression) $2, lexer.Location);
+         }
+       ;       
+                       
+exit_statement
+       : EXIT exit_type
+         {
+               $$ = new Exit ((ExitType)$2, lexer.Location);           
+         }
+       ;
+       
+exit_type
+       : DO            { $$ = ExitType.DO;             }
        | FOR           { $$ = ExitType.FOR;            }
        | WHILE         { $$ = ExitType.WHILE;          }
        | SELECT        { $$ = ExitType.SELECT;         }
@@ -1839,7 +2562,95 @@ iteration_statement
        : while_statement
        | do_statement
        | for_statement
-       /*| foreach_statement*/
+       | foreach_statement
+       ;
+
+foreach_statement
+       : FOR EACH identifier IN 
+         {
+               oob_stack.Push (lexer.Location);
+         }       
+         expression end_of_stmt
+         {
+               
+               start_block();
+               Block foreach_block = current_block;
+               Location l = lexer.Location;            
+               LocalVariableReference v = null;
+               VariableInfo vi;
+
+               vi = foreach_block.GetVariableInfo ((string) $3);
+               if (vi != null) {
+                       // Get a reference to this variable.
+                       v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
+               }
+               else
+                       Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
+       
+               oob_stack.Push (v);
+         }       
+         opt_statement_list
+         NEXT opt_identifier
+         {
+               Block foreach_block = current_block;
+               LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
+               Block prev_block = end_block();
+               Location l = (Location) oob_stack.Pop ();
+
+               Foreach f = null;
+               if (v != null) {
+                       f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
+               }
+               
+               $$ = f;
+         }       
+       ;
+
+yield_statement 
+       : YIELD expression
+         {
+               if (!UseExtendedSyntax)
+               {
+                       ReportError9998();
+                       $$ = null;
+               }
+/*             else
+                       if (iterator_container == null){
+                               Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+                               $$ = null;
+                       } else {
+                               iterator_container.SetYields ();
+                               $$ = new Yield ((Expression) $2, lexer.Location);
+                       } */
+         }
+       | YIELD STOP
+         {
+               if (!UseExtendedSyntax)
+               {
+                       ReportError9998();
+                       $$ = null;
+               }
+/*             else
+                       if (iterator_container == null){
+                               Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+                               $$ = null;
+                       } else {
+                               iterator_container.SetYields ();
+                               $$ = new YieldBreak (lexer.Location);
+                       } */
+         }
+       ;
+
+synclock_statement
+       : SYNCLOCK expression end_of_stmt
+         {   
+               start_block();  
+         }
+         opt_statement_list 
+         END SYNCLOCK
+         {
+               $$ = new Lock ((Expression) $2, (Statement) (Block) end_block(), lexer.Location);
+         }
        ;
 
 try_statement
@@ -1847,6 +2658,18 @@ try_statement
        | try_catch_finally
        ;
                                
+try_header
+       : TRY end_of_stmt
+         {   
+               start_block();  
+         }
+         opt_statement_list 
+         opt_catch_clauses
+         {
+               tmp_catch_clauses = (ArrayList) $5;
+         }
+       ;
+                                       
 try_catch
        : try_header 
          END TRY
@@ -1874,7 +2697,7 @@ try_catch_finally
          { 
                tmp_block = end_block(); 
          }     
-         FINALLY EOL
+         FINALLY end_of_stmt
          { 
                start_block(); 
          }       
@@ -1897,19 +2720,7 @@ try_catch_finally
                $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
        
          }     
-         ;       
-       
-try_header
-       : TRY EOL
-         {   
-               start_block();  
-         }
-         opt_statement_list 
-         opt_catch_clauses
-         {
-               tmp_catch_clauses = (ArrayList) $5;
-         }
-       ;       
+         ;             
 
 opt_catch_clauses
        : /* empty */  {  $$ = null;  }
@@ -1939,7 +2750,7 @@ opt_identifier
        ;
 
 catch_clause 
-       : CATCH opt_catch_args EOL
+       : CATCH opt_catch_args end_of_stmt
        {
                Expression type = null;
                string id = null;
@@ -1953,7 +2764,7 @@ catch_clause
                                ArrayList one = new ArrayList ();
                                Location loc = lexer.Location;
 
-                               one.Add (new VariableDeclaration (id, null, loc));
+                               one.Add (new VariableDeclaration (id, type, loc));
 
 
                                $1 = current_block;
@@ -2001,7 +2812,7 @@ catch_args
         
         
 do_statement
-       : DO opt_do_construct EOL
+       : DO opt_do_construct end_of_stmt
          {
                start_block();
                oob_stack.Push (lexer.Location);
@@ -2051,7 +2862,7 @@ while_statement
                start_block();
                oob_stack.Push (lexer.Location);
        }
-       boolean_expression EOL
+       boolean_expression end_of_stmt
        opt_statement_list
        END WHILE
        {
@@ -2064,12 +2875,12 @@ while_statement
        
                
 for_statement
-       : FOR qualified_identifier ASSIGN expression TO expression opt_step EOL
+       : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
          {
                start_block();
          }
          opt_statement_list
-         NEXT opt_next_identifier 
+         NEXT opt_identifier 
          {
                Block statement = end_block();
                Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
@@ -2092,60 +2903,146 @@ opt_step
        | STEP expression       { $$ = $2; }
        ;
 
-opt_next_identifier
-       : /* empty */
-       | qualified_identifier
-       ;
-
 selection_statement
        : if_statement
        | select_statement
        ;
 
 if_statement
-       : if_statement_open if_statement_rest
+       : if_statement_open opt_then if_statement_rest
          {
-               $$ = $2;
+               $$ = $3;
+         }
+       | if_statement_open THEN pre_embedded_statement
+         {
+               Location l = (Location) oob_stack.Pop ();
+               tmp_expr = (Expression)expr_stack.Pop(); 
+               $$ = new If ((Expression) tmp_expr, end_block(), l);
          }
        ;
+
+pre_embedded_statement
+       : embedded_statement 
+         {
+               Statement s = (Statement) $1;
+
+               current_block.AddStatement ((Statement) $1);
+         } 
+       ;       
        
 if_statement_open
-       : IF boolean_expression THEN EOL 
+       : IF boolean_expression 
          {
                oob_stack.Push (lexer.Location);
                start_block();
                tmp_expr = (Expression) $2;
+               expr_stack.Push(tmp_expr);
          }
         ;
 
+opt_then
+       : /* empty */
+       | THEN
+       ;
+       
 if_statement_rest
-       :         
+       : end_of_stmt
          opt_statement_list
          END IF
          { 
                Location l = (Location) oob_stack.Pop ();
-
-               $$ = new If ((Expression) tmp_expr, (Statement) end_block(), l);
-
+                Expression expr = (Expression)expr_stack.Pop(); 
+               $$ = new If ((Expression) expr, (Statement) end_block(), l);
          }       
-       |
+       | end_of_stmt
          opt_statement_list
-         ELSE EOL 
+         ELSE end_of_stmt 
          { 
-               tmp_block = end_block();
+               Block bl = end_block(); 
+               tmp_blocks.Push(bl); 
                start_block();
          }
          opt_statement_list
          END IF        
          {
                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, (Statement) end_block(), l);
-         }        
+         }     
+       | end_of_stmt
+         opt_statement_list 
+         ELSEIF boolean_expression opt_then 
+         { 
+               tmp_expr = (Expression) $4;                                                  
+                expr_stack.Push(tmp_expr);                                                 
+               tmp_block = end_block();
+                tmp_blocks.Push(tmp_block);
+               start_block();
+         }
+         else_if_statement_rest 
+         {
+               Statement stmt = (Statement) statement_stack.Pop();
+                Block bl = (Block) tmp_blocks.Pop();  
+               Expression expr =  (Expression)expr_stack.Pop();  
+               Location l = (Location) oob_stack.Pop ();
+                $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l); 
+         }
+       ;
+       
+       
+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();
+                tmp_blocks.Push(bl);
+               start_block();
+         }
+         opt_statement_list
+         END IF        
+         {
+               Location l = (Location) oob_stack.Pop ();
+               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 
+         { 
+                expr_stack.Push((Expression) $4);                                                 
+               Block bl = end_block();
+                tmp_blocks.Push(bl);
+               start_block();
+         }
+         else_if_statement_rest 
+         {
+               Location l = (Location) oob_stack.Pop ();
+               oob_stack.Push (l);
+               Statement tmp_stmt = (Statement)statement_stack.Pop();
+                Block bl = (Block) tmp_blocks.Pop();  
+               Expression expr =  (Expression)expr_stack.Pop();  
+               Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
+                statement_stack.Push(stmt);
+         }          
        ;
        
 select_statement
-       : SELECT opt_case expression EOL
+       : SELECT opt_case expression end_of_stmt
          { 
                oob_stack.Push (lexer.Location);
                switch_stack.Push (current_block);
@@ -2180,15 +3077,22 @@ case_sections
          }
        ;
 
+ends 
+       : end_of_stmt
+       | ends end_of_stmt
+       ;
+       
+
 case_section
-       : CASE case_clauses EOL
+       : CASE case_clauses ends
          { 
                start_block();
          }
          opt_statement_list
          {
-               Block topmost = current_block;
-
+               //Block topmost = current_block;
+               Block topmost = end_block();
+               
                while (topmost.Implicit)
                        topmost = topmost.Parent;
                        
@@ -2196,7 +3100,7 @@ case_section
                topmost.statements.Add (new Break (lexer.Location));
                $$ = new SwitchSection ((ArrayList) $2, topmost);
          }
-         | CASE ELSE EOL
+         | CASE ELSE ends
            /* FIXME: we should somehow flag an error 
               (BC30321 'Case' cannot follow a 'Case Else' 
               in the same 'Select' statement.) 
@@ -2207,7 +3111,8 @@ case_section
          }     
          opt_statement_list
          { 
-               Block topmost = current_block;
+               //Block topmost = current_block;
+               Block topmost = end_block();
 
                while (topmost.Implicit)
                        topmost = topmost.Parent;
@@ -2271,6 +3176,7 @@ expression_statement
          }
        ;
 
+
 statement_expression
        : invocation_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
        | object_creation_expression    { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
@@ -2282,11 +3188,46 @@ object_creation_expression
          {
                $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
          }
+       | NEW type
+         {
+               $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
+         }
        ;
+       
+array_creation_expression
+       : object_creation_expression array_initializer
+         {
+               New n = (New) $1;
+               ArrayList dims = new ArrayList();
+               
+               if (n.Arguments != null) {
+                       foreach (Argument a in n.Arguments) {
+                               dims.Add (a.Expr);
+                       }
+               }
+                       
+               Expression atype = n.RequestedType;
+
+               ArrayList init = (ArrayList) $2;
+               if (init.Count == 0)
+                       init = null;
+       
+               if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
+                       VariableDeclaration.VBFixIndexList (ref dims);
+                       $$ = new ArrayCreation (atype, dims, "", init, lexer.Location); 
+               }
+               else
+               {
+                       string rank = VariableDeclaration.BuildRank (dims);
+                       $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location); 
+               }
+               //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
+         }
+       ;       
 
 new_expression
        : object_creation_expression
-       /* | array_creation_expression */
+       | array_creation_expression
        ;
 
 declaration_statement
@@ -2298,13 +3239,12 @@ declaration_statement
                        $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
                }
          }
-
        | local_constant_declaration 
          {
                if ($1 != null){
                        DictionaryEntry de = (DictionaryEntry) $1;
 
-                       $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
+                       $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
                }
          }
        ;        
@@ -2314,35 +3254,66 @@ local_variable_declaration
          {
                $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);             
          }
-       /*| DIM variable_declarators 
-         {
-               $$ = new DictionaryEntry (TypeManager.system_object_expr, $2);
-         }
-       | DIM variable_declarators AS object_creation_expression
-         {
-               if ($4 != null)
-                       $$ = new DictionaryEntry ($4, $2);
-               else
-                       $$ = null;
-                                               
-         } */
        ;
 
        
 local_constant_declaration
-       : CONST constant_declarator
+       : CONST constant_declarators
          {
                if ($2 != null)
-                       $$ = new DictionaryEntry ($1, $2);
+                       $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
                else
                        $$ = null;
          }
        ;        
        
+constant_declarators
+       : constant_declarator 
+         {
+               ArrayList decl = new ArrayList ();
+               if ($1 != null) 
+                       decl.Add ($1);
+                       
+               $$ = decl;
+         }
+       | constant_declarators COMMA constant_declarator
+         {
+               ArrayList decls = (ArrayList) $1;
+               if ($3 != null)
+                       decls.Add ($3);
+
+               $$ = $1;
+         }
+       ;
+
 constant_declarator
-       : identifier ASSIGN constant_expression
+       : variable_name opt_type_decl opt_variable_initializer
          {
-               $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
+               VarName vname = (VarName) $1;
+               string varname = (string) vname.Name;
+               current_rank_specifiers = (ArrayList) vname.Rank;
+               object varinit = $3;
+               ArrayList a_dims = null;
+
+               if (varinit == null)
+                       Report.Error (
+                               30438, lexer.Location, "Constant should have a value"
+                               );
+
+               if (vname.Type != null && $2 != null)
+                       Report.Error (
+                               30302, lexer.Location, 
+                               "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;
+
+               if (current_rank_specifiers != null) 
+               {
+                       Report.Error (30424, lexer.Location, "Constant doesn't support array");
+                       $$ = null;
+               }
+               else
+                       $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
          }
        ;               
 
@@ -2350,77 +3321,180 @@ variable_declarators
        : variable_declarator 
          {
                ArrayList decl = new ArrayList ();
-               decl.Add ($1);
+               decl.AddRange ((ArrayList) $1);
                $$ = decl;
          }
        | variable_declarators COMMA variable_declarator
          {
                ArrayList decls = (ArrayList) $1;
-               decls.Add ($3);
+               decls.AddRange ((ArrayList) $3);
                $$ = $1;
          }
        ;
 
 variable_declarator
-       : variable_identifier opt_type_decl opt_variable_initializer
+       : variable_names opt_type_decl opt_variable_initializer
          {
-               string varname = (string)$1;
-               string dims = "";
-               object varinit = $3;
-               Expression vartype = (Expression) $2;
-               
-               /*
-                  Check for a declaration like Dim a(2) or Dim a(2,3)
-                  If this is the case, we must generate an ArrayCreationExpression
-                  and, in case, add the initializer after the array has been created.
-               */
-               if (VariableDeclaration.IsArrayDecl (varname)) {
-                       if (VariableDeclaration.DimsSpecified(varname)) { 
-                               varname = VariableDeclaration.StripDims (varname, ref dims);
-                               ArrayList a_dims = VariableDeclaration.ParseDimList(dims);
-                               varinit = new ArrayCreation (vartype, a_dims,"", (ArrayList) varinit, lexer.Location);
-                       }
-                       vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.GetRank (dims), lexer.Location);
-               }
+           ArrayList names = (ArrayList) $1;
+               object varinit = $3;
+               ArrayList VarDeclarations = new ArrayList();
+               Expression vartype;
+               ArrayList a_dims = null;
 
-               if (vartype is New) {
-                       if (varinit != null) {
-                               Report.Error (30205, lexer.Location, "End of statement expected");
-                               $$ = null;
-                       }
-                       else
+               if ((names.Count > 1) && (varinit != null)) 
+                       Report.Error (
+                               30671, lexer.Location, 
+                               "Multiple variables with single type can not have " +
+                               "a explicit initialization" );
+
+                               
+               foreach (VarName vname in names)
+               {
+                       string varname = (string) vname.Name;
+                       current_rank_specifiers = (ArrayList) vname.Rank;
+                       a_dims = null;
+                       varinit = $3;
+
+                       if(vname.Type != null && $2 != null)
+                               Report.Error (
+                                       30302, lexer.Location, 
+                                       "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 != null && $3 is ArrayList)
+                                       Report.Error (205, "End of statement expected.");*/
+                                       
+                               ArrayList args = (ArrayList) ((Pair) $2).Second;
+                               if (current_rank_specifiers != null)
+                                       Report.Error (31087, lexer.Location,
+                                                "Array types specified in too many places");   
+                               
+                               if (VariableDeclaration.IndexesSpecifiedInRank (args))            
+                                       Report.Error (30638, "Array bounds cannot appear in type specifiers."); 
+                               
+                               current_rank_specifiers = new ArrayList ();
+                               current_rank_specifiers.Add (args);
+                               
+                               /*string s_vartype = vartype.ToString();                                
+                               s_vartype += "[";
+                               if (args != null)
+                                       for (int x = 0; x < args.Count; x++)
+                                               s_vartype += ",";
+                                       
+                               s_vartype += "]";       
+                               vartype = DecomposeQI(s_vartype, Location.Null);        */
+                       }
+                       else
+                               vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
+
+                       // if the variable is an array with explicit bound
+                       // and having explicit initialization throw exception
+                       if (current_rank_specifiers != null && varinit != null) 
                        {
-                               varinit = vartype;
-                               vartype = ((New)vartype).RequestedType;
+                               bool broken = false;
+                               foreach (ArrayList exprs in current_rank_specifiers)
+                               {
+                                       foreach (Expression expr in exprs)
+                                       {
+                                               if (!((Expression)expr is EmptyExpression ))
+                                               {
+                                                       Report.Error (
+                                                               30672, lexer.Location, 
+                                                               "Array declared with explicit bound " +
+                                                               " can not have explicit initialization");
+                                                       broken = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (broken)
+                                               break;
+                               }
+                       }
+                       
+                       /*
+                       Check for a declaration like Dim a(2) or Dim a(2,3)
+                       If this is the case, we must generate an ArrayCreationExpression
+                       and, in case, add the initializer after the array has been created.
+                       */
+                       if (VariableDeclaration.IsArrayDecl (this)) {   
+                               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);
+                               }
+                               vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
                        }
-               }
-               $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
-         }
+
+                       if (vartype is New) {
+                               if (varinit != null) {
+                                       Report.Error (30205, lexer.Location, "End of statement expected");
+                                       $$ = null;
+                               }
+                               else
+                               {
+                                       varinit = vartype;
+                                       vartype = ((New)vartype).RequestedType;
+                               }
+                       }
+                       VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
+           }// end of for
+           $$ = VarDeclarations;
+         } 
        ;
 
-variable_identifier
-       : identifier opt_array_name_modifier 
+variable_names
+       : variable_name
          {
-               $$ = $1; 
-               if ($2 != null)
-                       $$ = (string)$$ + (string)$2;
+               ArrayList list = new ArrayList ();
+               list.Add ($1);
+               $$ = list;
          }
-       ;               
-               
+       | variable_names COMMA variable_name
+         {
+               ArrayList list = (ArrayList) $1;
+               list.Add ($3);
+               $$ = list;
+         }
+       ;
+       
+variable_name
+       : identifier opt_type_character opt_array_name_modifier
+         {
+               $$ = new VarName ($1, $2, $3);
+         }
+       ;
+
 opt_type_spec
-       : /* empty */   { $$ = null;            }
-       | AS type       { $$ = (Expression) $2; };
+       : /* empty */   
+         { 
+               $$ = null;              
+         }
+       | AS type       
+         { 
+               $$ = (Expression) $2;
+         }
        ;
-                       
+               
+opt_type_with_ranks
+       : opt_type_spec 
+       | AS type rank_specifiers
+         {
+               $$ = TypeManager.system_object_expr; 
+         }
+       ;
+       
 opt_type_decl
        : opt_type_spec
          {
                $$ = $1;
          }
-       | AS type OPEN_PARENS opt_argument_list CLOSE_PARENS 
+       | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
          {
-               Report.Error (30638, "Array bounds cannot appear in type specifiers");
-               $$ = null;
+               $$ = new Pair ($2, $4);
          }
        | AS NEW type
          {
@@ -2432,15 +3506,24 @@ opt_type_decl
                New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
                $$ = (Expression) n;
          }
-       ;
+       /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS 
+         {
+           ArrayList args = new ArrayList();
+               Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
+               args.Add (arg);
+               
+               New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
+               $$ = (Expression) n;
+         }*/
+       ;
                
 opt_array_name_modifier
        : /* empty */                           { $$ = null; }
-       | array_type_modifier                   { $$ = $1;   } 
+       | array_type_modifier                   { $$ = $1;   }
        ;
        
 array_type_modifier
-       : rank_specifiers  { $$ = $1; }
+       : rank_specifiers               { $$ = $1; }
        ;
        
 opt_variable_initializer
@@ -2485,94 +3568,54 @@ variable_initializer_list
                list.Add ($3);
                $$ = list;
          }
-       ;       
-               
-/* 
- * The following is from Rhys' grammar:
- * > Types in local variable declarations must be recognized as 
- * > expressions to prevent reduce/reduce errors in the grammar.
- * > The expressions are converted into types during semantic analysis.
- */
-local_variable_type
-       : primary_expression opt_rank_specifier
-         { 
-               // FIXME: Do something smart here regarding the composition of the type.
-
-               // Ok, the above "primary_expression" is there to get rid of
-               // both reduce/reduce and shift/reduces in the grammar, it should
-               // really just be "type_name".  If you use type_name, a reduce/reduce
-               // creeps up.  If you use qualified_identifier (which is all we need
-               // really) two shift/reduces appear.
-               // 
-
-               // So the super-trick is that primary_expression
-               // can only be either a SimpleName or a MemberAccess. 
-               // The MemberAccess case arises when you have a fully qualified type-name like :
-               // Foo.Bar.Blah i;
-               // SimpleName is when you have
-               // Blah i;
-                 
-               Expression expr = (Expression) $1;  
-               if (!(expr is SimpleName || expr is MemberAccess)) {
-                       Error_ExpectingTypeName (lexer.Location, expr);
-                       $$ = null;
-               } else {
-                       //
-                       // So we extract the string corresponding to the SimpleName
-                       // or MemberAccess
-                       // 
-                       if ((string) $2 == "")
-                               $$ = $1;
-                       else
-                               $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
-               }
+       ;
+
+opt_rank_specifiers
+       : /* empty */
+         {
+                 // $$ = "";
+                 $$ = null;
          }
-       | builtin_types opt_rank_specifier
+       | rank_specifiers
          {
-               if ((string) $2 == "")
                        $$ = $1;
-               else
-                       $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
          }
-        ;
-               
+       ;      
+       
 rank_specifiers
        : rank_specifier
          {
-                 $$ = $1;
+                 ArrayList rs = new ArrayList();
+                 rs.Add ($1);
+                 $$ = rs;
          }
        | rank_specifiers rank_specifier
          {
-                 $$ = (string) $2 + (string) $1;
+                 ArrayList rs = (ArrayList) $1;
+                 rs.Add ($2);
+                 $$ = rs;
          }             
-        ;
-
+        ;              
+       
 rank_specifier
        : OPEN_PARENS opt_dim_separators CLOSE_PARENS
          {
-               $$ = "[" + (string) $2 + "]";
+               $$ = $2;
          }
        ;
-                       
-opt_rank_specifier
-       : /* empty */
-         {
-                 $$ = "";
-         }
-       | rank_specifiers
-         {
-                       $$ = $1;
-         }
-       ;               
-       
+               
 opt_dim_separators
        : /* empty */
          {
-               $$ = "";
+               ArrayList ds = new ArrayList();
+               ds.Add (new EmptyExpression());
+               $$ = ds;                
          }
        | dim_separators
          {
-               $$ = $1;
+               ArrayList ds = (ArrayList) $1;
+               ds.Add (new EmptyExpression());
+               $$ = ds;        
          }     
        | dim_specifiers
          {
@@ -2583,48 +3626,66 @@ opt_dim_separators
 dim_separators
        : COMMA
          {
-               $$ = ",";
+               ArrayList ds = new ArrayList();
+               ds.Add (new EmptyExpression());
+               $$ = ds;
          }
        | dim_separators COMMA
          {
-               $$ = (string) $1 + ",";
+               ArrayList ds = (ArrayList) $1;
+               ds.Add (new EmptyExpression());
+               $$ = ds;                
          }
        ;
-       
+
 dim_specifiers
-       : integer_literal                       { $$ = ((IntLiteral)$1).AsString(); }
-       | dim_specifiers COMMA integer_literal  { $$ = $1 + "," + ((IntLiteral)$3).AsString(); }
+       : expression
+         {
+               ArrayList ds = new ArrayList();
+               ds.Add ((Expression) $1);
+               $$ = ds;
+         }     
+       | dim_specifiers COMMA expression
+         {
+               ArrayList ds = (ArrayList) $1;
+               ds.Add ((Expression) $3);
+               $$ = ds;                
+         }     
        ;
-               
-/* Expressions */
+       
 primary_expression
        : literal
          {
-               // 7.5.1: Literals
+               //TODO
          }
-
+       | parenthesized_expression
+       | this_access
+       | base_access
        | qualified_identifier
          {
                string name = (string) $1;
-
                $$ = DecomposeQI (name, lexer.Location);
          }
-       | parenthesized_expression
+       //FIXME: address_of_expression is apparently missing here
+       | get_type_expression
+         {
+               // TODO
+         }
        | member_access
        | invocation_expression
-       | element_access
-       | this_access
-       //| base_access
+       //| element_access
        | new_expression
+       | cast_expression
        ;
 
 literal
        : boolean_literal
        | integer_literal
        | real_literal
+       | LITERAL_DATE                  { $$ = new DateLiteral ((DateTime)lexer.Value); }
        | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value); }
        | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value); }
-       | NOTHING                       { $$ = NullLiteral.Null; }
+       | NOTHING                               { $$ = NullLiteral.Null; }
        ;
 
 real_literal
@@ -2638,13 +3699,11 @@ integer_literal
                object v = lexer.Value;
 
                if (v is int)
-                       $$ = new IntLiteral ((Int32) v); 
-               else if (v is uint)
-                       $$ = new UIntLiteral ((UInt32) v);
+                       $$ = new IntLiteral ((Int32)v); 
+               else if (v is short)
+                       $$ = new ShortLiteral ((Int16)v);
                else if (v is long)
-                       $$ = new LongLiteral ((Int64) v);
-               else if (v is ulong)
-                       $$ = new ULongLiteral ((UInt64) v);
+                       $$ = new LongLiteral ((Int64)v);
                else
                        Console.WriteLine ("OOPS.  Unexpected result from scanner");
                        
@@ -2664,11 +3723,43 @@ parenthesized_expression
 member_access
        : primary_expression DOT identifier
          {
-               $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+               if ($1 != null) {
+                       string id_name = (string)$3;
+                       if (id_name.ToUpper() == "NEW")
+                               id_name = ".ctor";
+                       $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
+               }
+               else
+               {
+                       if (with_stack.Count > 0) {
+                               Expression e = (Expression) with_stack.Peek();
+                               $$ = new MemberAccess (e, (string) $3, lexer.Location);
+                       }
+                       else
+                       {
+                               // OOps
+                       }
+               }
          }
+/*     | primary_expression DOT NEW
+         {
+               $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
+         }       */
        | predefined_type DOT identifier
          {
-               $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+               if ($1 != null)
+                       $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+               else
+               {
+                       if (with_stack.Count > 0) {
+                               Expression e = (Expression) with_stack.Peek();
+                               $$ = new MemberAccess (e, (string) $3, lexer.Location);
+                       }
+                       else
+                       {
+                               // OOps
+                       }
+               }
          }
        ;
 
@@ -2684,18 +3775,23 @@ invocation_expression
                        Report.Error (1, l, "THIS IS CRAZY");
                }
                $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
-         }
-       | MYBASE DOT identifier OPEN_PARENS opt_expression_list CLOSE_PARENS
+//             Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
+         } 
+       ;
+       
+base_access
+       : MYBASE DOT IDENTIFIER
          {
-               BaseAccess ba = new BaseAccess ((string) $3, lexer.Location);
-               $$ = new Invocation ((Expression) ba, (ArrayList) $5, lexer.Location);
-         }  
-       | MYBASE DOT NEW OPEN_PARENS opt_expression_list CLOSE_PARENS
+               string id_name = (string) $3;
+               if (id_name.ToUpper() == "NEW")
+                       id_name = "New";
+               $$ = new BaseAccess (id_name, lexer.Location);
+         }
+/*     | MYBASE DOT NEW
          {
-               BaseAccess ba = new BaseAccess ("New", lexer.Location);
-               $$ = new Invocation ((Expression) ba, (ArrayList) $5, lexer.Location);
-         }       
-       ;
+               $$ = new BaseAccess ("New", lexer.Location);
+         }*/
+       ;       
 
 opt_argument_list
        : argument_list
@@ -2745,103 +3841,60 @@ argument
          {
                $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
          }
+       | ADDRESSOF expression
+         {
+               $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
+         }
        ;
 
 variable_reference
        : expression {/* note ("section 5.4"); */  $$ = $1;  }
        ;
 
-element_access
-       : primary_expression OPEN_PARENS expression_list CLOSE_PARENS
-         {
-         
-               $$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
-         }
-/*     | primary_expression rank_specifiers
-         {
-               // So the super-trick is that primary_expression
-               // can only be either a SimpleName or a MemberAccess.
-               // The MemberAccess case arises when you have a fully qualified type-name like :
-               // Foo.Bar.Blah i;
-               // SimpleName is when you have
-               // Blah i;
-               Expression expr = (Expression) $1;
                
-               if (!(expr is SimpleName || expr is MemberAccess)) {
-                       Error_ExpectingTypeName (lexer.Location, expr);
-                       $$ = TypeManager.system_object_expr;
-               } else {
-                       //
-                       // So we extract the string corresponding to the SimpleName
-                       // or MemberAccess
-                       //
-                       $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
-               }
-         }*/
-       ;
-
 expression
-       : conditional_expression { $$ = $1; }
-       /*| assignment_expression*/
-       ;
-
-opt_expression
-       : /* empty */
-       | expression
-       ;
-       
-expression_list
-       : expression
-         {
-               ArrayList list = new ArrayList ();
-               list.Add ($1);
-               $$ = list;
-         }
-       | expression_list COMMA expression
-         {
-               ArrayList list = (ArrayList) $1;
-               list.Add ($3);
-               $$ = list;
-         }
+       : conditional_xor_expression { $$ = $1; }
+       /*| assignment_expression*/
        ;
 
-opt_expression_list
-       : /*empty */ { $$ = null; }
-       | expression_list
+opt_expression
+       : /* empty */
+       | expression
        ;
-       
+               
 this_access
        : ME
          {
                $$ = new This (current_block, lexer.Location);
          }
-       ;
-
-unary_expression
-       : primary_expression
-       | NOT prefixed_unary_expression
+       | MYCLASS
          {
-               $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
+               // FIXME: This is actually somewhat different from Me
+               // because it is for accessing static (classifier) methods/properties/fields
+               $$ = new This (current_block, 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);
-         }     
-       | CTYPE OPEN_PARENS expression COMMA expression CLOSE_PARENS
+               // 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
        : CBOOL         { $$ = TypeManager.system_boolean_expr;         }
        | CBYTE         { $$ = TypeManager.system_byte_expr;            }
        | CCHAR         { $$ = TypeManager.system_char_expr;            }
-       | CDATE         { $$ = TypeManager.system_decimal_expr;         } //FIXME
+       | CDATE         { $$ = TypeManager.system_date_expr;            }
        | CDBL          { $$ = TypeManager.system_double_expr;          }
        | CDEC          { $$ = TypeManager.system_decimal_expr;         }
        | CINT          { $$ = TypeManager.system_int32_expr;           }
@@ -2851,27 +3904,34 @@ cast_operator
        | CSNG          { $$ = TypeManager.system_single_expr;          }
        | CSTR          { $$ = TypeManager.system_string_expr;  }
        ;
+
+get_type_expression
+       : GETTYPE OPEN_PARENS type CLOSE_PARENS
+         {
+               //TODO
+         }
+       ;
+       
+exponentiation_expression
+       : primary_expression
+       | exponentiation_expression OP_EXP primary_expression
+         {
+               //TODO
+         }                             
+       ;
        
-       //
-       // The idea to split this out is from Rhys' grammar
-       // to solve the problem with casts.
-       //
 prefixed_unary_expression
-       : unary_expression
+       : exponentiation_expression
        | PLUS prefixed_unary_expression
          {
+               //FIXME: Is this rule correctly defined ?
                $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
          }
        | MINUS prefixed_unary_expression
          {
+               //FIXME: Is this rule correctly defined ?
                $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
          }
-       | ADDRESSOF prefixed_unary_expression
-         {
-               // FIXME: We should generate an error if AddressOf is NOT used
-               // during delegate creation
-               $$ = $2;
-         }       
        ;
 
 multiplicative_expression
@@ -2886,97 +3946,124 @@ multiplicative_expression
                $$ = new Binary (Binary.Operator.Division,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | multiplicative_expression OP_MODULUS prefixed_unary_expression
+       ;
+
+integer_division_expression
+       : multiplicative_expression
+       | integer_division_expression OP_IDIV multiplicative_expression
+          {
+               //FIXME: Is this right ?
+               $$ = new Binary (Binary.Operator.Division,
+                          (Expression) $1, (Expression) $3, lexer.Location);
+          }
+       ;
+
+mod_expression
+       : integer_division_expression
+       | mod_expression MOD integer_division_expression
          {
-               $$ = new Binary (Binary.Operator.Modulus,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+             $$ = new Binary (Binary.Operator.Modulus,
+                              (Expression) $1, (Expression) $3, lexer.Location);
          }
        ;
-
+       
 additive_expression
-       : multiplicative_expression
-       | additive_expression PLUS multiplicative_expression
+       : mod_expression
+       | additive_expression PLUS mod_expression
          {
                $$ = new Binary (Binary.Operator.Addition,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | additive_expression MINUS multiplicative_expression
+       | additive_expression MINUS mod_expression
          {
                $$ = new Binary (Binary.Operator.Subtraction,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | additive_expression OP_CONCAT multiplicative_expression
+       ;
+
+concat_expression
+       : additive_expression
+       | concat_expression OP_CONCAT additive_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);
+         }     
+       ;
+
+shift_expression
+       : concat_expression
+       | shift_expression OP_SHIFT_LEFT concat_expression
          {
-               // FIXME: This should only work for String expressions
-               // We probably need to use something from the runtime
-               $$ = new Binary (Binary.Operator.Addition,
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }       
+               // TODO
+         }
+       | shift_expression OP_SHIFT_RIGHT concat_expression
+         {
+               //TODO
+         }
        ;
 
 relational_expression
-       : additive_expression
-       | relational_expression OP_LT additive_expression
+       : shift_expression
+       | relational_expression ASSIGN shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Equality,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | relational_expression OP_NE shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Inequality, 
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }       
+       | relational_expression OP_LT shift_expression
          {
                $$ = new Binary (Binary.Operator.LessThan,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | relational_expression OP_GT additive_expression
+       | relational_expression OP_GT shift_expression
          {
                $$ = new Binary (Binary.Operator.GreaterThan,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | relational_expression OP_LE additive_expression
+       | relational_expression OP_LE shift_expression
          {
                $$ = new Binary (Binary.Operator.LessThanOrEqual,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | relational_expression OP_GE additive_expression
+       | relational_expression OP_GE shift_expression
          {
                $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       | relational_expression IS type_name
+       | relational_expression IS shift_expression
          {
-               $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
+               //FIXME: Is this rule correctly defined ?
          }
-       | relational_expression AS type_name
+       | TYPEOF shift_expression IS namespace_or_type_name
          {
-               $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
+                 //FIXME: Is this rule correctly defined ?
          }
        ;
 
-equality_expression
+negation_expression
        : relational_expression
-       | equality_expression ASSIGN relational_expression
-         {
-               $$ = new Binary (Binary.Operator.Equality,
-                                (Expression) $1, (Expression) $3, lexer.Location);
-         }
-       ;
-
-and_expression
-       : equality_expression
-       | and_expression OP_AND equality_expression
+       | NOT negation_expression 
          {
-               $$ = new Binary (Binary.Operator.BitwiseAnd,
-                                (Expression) $1, (Expression) $3, lexer.Location);
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
          }
        ;
-
-exclusive_or_expression
-       : and_expression
-       | exclusive_or_expression OP_XOR and_expression
+       
+conditional_and_expression
+       : negation_expression
+       | conditional_and_expression AND negation_expression
          {
-               $$ = new Binary (Binary.Operator.ExclusiveOr,
+               $$ = new Binary (Binary.Operator.LogicalAnd,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
-       ;
-
-conditional_and_expression
-       : exclusive_or_expression
-       | conditional_and_expression OP_AND exclusive_or_expression
-         {
+       | conditional_and_expression ANDALSO negation_expression
+         {     // FIXME: this is likely to be broken
                $$ = new Binary (Binary.Operator.LogicalAnd,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
@@ -2984,15 +4071,25 @@ conditional_and_expression
 
 conditional_or_expression
        : conditional_and_expression
-       | conditional_or_expression OP_OR conditional_and_expression
+       | conditional_or_expression OR conditional_and_expression
          {
                $$ = new Binary (Binary.Operator.LogicalOr,
                                 (Expression) $1, (Expression) $3, lexer.Location);
          }
+       | conditional_or_expression ORELSE conditional_and_expression
+         {     // FIXME: this is likely to be broken
+               $$ = new Binary (Binary.Operator.LogicalOr,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
        ;
 
-conditional_expression
+conditional_xor_expression
        : conditional_or_expression
+       | conditional_xor_expression XOR conditional_or_expression
+       {
+             $$ = new Binary (Binary.Operator.ExclusiveOr,
+                              (Expression) $1, (Expression) $3, lexer.Location);
+       }
        ;
 
 assignment_expression
@@ -3000,6 +4097,16 @@ assignment_expression
          { 
                $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
          }
+       | 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);
+         }
        ;
 
 constant_expression
@@ -3011,16 +4118,12 @@ boolean_expression
        ;
 
 type
-       : type_name {   /* class_type */
-               /*
-                  This does interfaces, delegates, struct_types, class_types,
-                  parent classes, and more! 4.2
-                */
+       : namespace_or_type_name 
+         {     
                $$ = DecomposeQI ((string) $1, lexer.Location); 
          }
        | builtin_types 
-       /*| array_type 
-        | pointer_type */
+       //| array_type 
        ;
 
 type_list
@@ -3040,73 +4143,174 @@ type_list
          }
        ;
 
-type_name
-       : namespace_or_type_name
-       ;
-       
 namespace_or_type_name
        : qualified_identifier
        ;
 
-array_type
-       : type bracketed_rank_specifiers
-         {
-               $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
-         }
+builtin_types
+       : OBJECT        { $$ = TypeManager.system_object_expr; }
+       | primitive_type
        ;
-       
-bracketed_rank_specifiers
-       : bracketed_rank_specifier bracketed_opt_rank_specifier
-         {
-                 $$ = (string) $2 + (string) $1;
-         }
-        ;
 
-bracketed_rank_specifier
-       : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
-         {
-               $$ = "[" + (string) $2 + "]";
-         }
+primitive_type
+       : numeric_type
+       | BOOLEAN       { $$ = TypeManager.system_boolean_expr; }
+       | DATE          { $$ = TypeManager.system_date_expr; }
+       | CHAR          { $$ = TypeManager.system_char_expr; }
+       | STRING        { $$ = TypeManager.system_string_expr; }
        ;
+       
 
-bracketed_opt_rank_specifier
-       : /* empty */
-         {
-                 $$ = "";
-         }
-       | bracketed_rank_specifiers
-         {
-               $$ = $1;
-         }
-       ;               
-
-/* Built-in / Integral types */
-builtin_types
-       : OBJECT        { $$ = TypeManager.system_object_expr; }
-       | STRING        { $$ = TypeManager.system_string_expr; }
-       | BOOLEAN       { $$ = TypeManager.system_boolean_expr; }
+numeric_type
+       : integral_type
+       | floating_point_type
        | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
-       | SINGLE        { $$ = TypeManager.system_single_expr; }
-       | DOUBLE        { $$ = TypeManager.system_double_expr; }
-       | integral_type
        ;
 
 integral_type
-       : /*SBYTE               { $$ = TypeManager.system_sbyte_expr; }
+       :
        | BYTE          { $$ = TypeManager.system_byte_expr; }
        | SHORT         { $$ = TypeManager.system_int16_expr; }
-       | USHORT        { $$ = TypeManager.system_uint16_expr; }
-       | */ INTEGER    { $$ = TypeManager.system_int32_expr; }/*
-       | UINT          { $$ = TypeManager.system_uint32_expr; }
+       | INTEGER       { $$ = TypeManager.system_int32_expr; }
        | LONG          { $$ = TypeManager.system_int64_expr; }
-       | ULONG         { $$ = TypeManager.system_uint64_expr; }
-       | CHAR          { $$ = TypeManager.system_char_expr; }
-       | VOID          { $$ = TypeManager.system_void_expr; }*/
+       ;
+       
+floating_point_type
+       : SINGLE        { $$ = TypeManager.system_single_expr; }
+       | DOUBLE        { $$ = TypeManager.system_double_expr; }
        ;
 
 interface_type
-       : type_name
+       : namespace_or_type_name
        ;
+       
+pp_directive
+       : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
+         { 
+               if(tokenizerController.IsAcceptingTokens)
+               {
+                       if(in_external_source) 
+                               Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
+                       else {
+                               in_external_source = true;
+                       
+                               lexer.EffectiveSource = (string) $4;
+                               lexer.EffectiveLine = (int) $6;
+                       }
+               }
+         }
+       | HASH IDENTIFIER LITERAL_STRING EOL
+         {
+               if(tokenizerController.IsAcceptingTokens) 
+               {
+                       string id = ($2 as string);
+               
+                       if(!($2 as string).ToLower().Equals("region"))
+                               Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
+                       else
+                       {
+                               ++in_marked_region;
+                       }
+               }
+         }
+       | HASH END IDENTIFIER EOL
+         {
+               if(tokenizerController.IsAcceptingTokens)
+               {
+                       if( ($3 as string).ToLower().Equals("externalsource")) {
+                               if(!in_external_source)
+                                       Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
+                               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, lexer.Location, "'#End Region' must be preceded  by a matching '#Region'");
+                       }
+                       else {
+                               Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
+                       }       
+               }
+         }
+       | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
+         {
+               if(tokenizerController.IsAcceptingTokens)
+               {
+                       //TODO;
+               }
+         }
+       | HASH IF 
+         {
+               IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
+
+               try {
+                       ifElseStateMachine.HandleToken(tok);
+               }
+               catch(ApplicationException) {
+                       throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+               }
+         }
+          boolean_literal opt_then  EOL 
+         {
+               HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
+         }
+       | HASH ELSEIF 
+         {
+                     IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
+                     try {
+                             ifElseStateMachine.HandleToken(tok);
+                     }
+                     catch(ApplicationException) {
+                             throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                     }
+         }
+          boolean_literal opt_then  EOL 
+         { 
+                 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
+         }
+       | HASH ELSE  
+         {
+                   IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
+                   try {
+                           ifElseStateMachine.HandleToken(tok);
+                   }
+                   catch(ApplicationException) {
+                           throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                   }
+         }
+         EOL 
+         { 
+               HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
+         }
+       | HASH END IF  
+         {
+                 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
+                 try {
+                         ifElseStateMachine.HandleToken(tok);
+                 }
+                 catch(ApplicationException) {
+                         throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                 }
+         }
+         EOL 
+         { 
+               HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
+         }
+       | HASH error EOL          
+       {
+               if(tokenizerController.IsAcceptingTokens)
+                       Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
+               else
+                       Report.Warning (9999, lexer.Location,   "Unrecognized Pre-Processor statement");
+       }
+         
+       ;               
+
 %%
 
 
@@ -3203,23 +4407,39 @@ Block declare_local_variables (Expression dummy_type, ArrayList variable_declara
        return implicit_block;
 }
 
-
-Block declare_local_constant (Expression type, VariableDeclaration decl)
+Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
 {
        Block implicit_block;
+       VariableDeclaration.FixupTypes (variable_declarators);
 
        if (current_block.Used)
                implicit_block = new Block (current_block, true);
        else
                implicit_block = current_block;
 
-       if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
-                                         current_local_parameters, decl.Location))){
+       foreach (VariableDeclaration decl in variable_declarators){
+               Expression type = decl.type;
+               implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
+                                         current_local_parameters, decl.Location);
        }
        
        return implicit_block;
 }
 
+struct VarName {
+                public object Name;
+                public object Type;
+               public object Rank;
+                                                                                
+                public VarName (object n, object t, object r)
+                {
+                        Name = n;
+                        Type = t;
+                       Rank = r;
+                }
+        }
+
+
 // <summary>
 //   A class used to pass around variable declarations and constants
 // </summary>
@@ -3254,6 +4474,12 @@ public class VariableDeclaration {
        {
        }       
        
+       public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
+       {       
+               // FIXME : This is broken: only the first rank is parsed
+               return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
+       }
+       
        public static void FixupTypes (ArrayList vars)
        {
                int varcount =  vars.Count;
@@ -3274,16 +4500,32 @@ public class VariableDeclaration {
                }
        }
        
-       public static bool DimsSpecified (string varname)
+       public static bool IndexesSpecifiedInRank (ArrayList IndexList)
        {
                bool res = false;
                
-               if (varname.IndexOf("[") >= 0) {
-                       char[] ds = {'1','2','3','4','5','6','7','8','9'};
-                       
-                       string dimpart = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
-                       if (dimpart.IndexOfAny (ds) >= 0) 
-                               res = true;
+               if (IndexList != null) {
+                       foreach (Expression e in IndexList)
+                               if (!(e is EmptyExpression)) {
+                                       res = true;
+                                       break;
+                               }       
+               }
+               return (res);
+       }       
+       
+       
+       public static bool IndexesSpecified (ArrayList ranks)
+       {
+               bool res = false;
+               
+               if (ranks != null) {
+                       foreach (ArrayList IndexList in ranks) {
+                               if (IndexesSpecifiedInRank (IndexList)) {
+                                       res = true;
+                                       break;
+                               }       
+                       }       
                }
                return (res);
        }
@@ -3308,42 +4550,67 @@ public class VariableDeclaration {
                return (StripDims(varname, ref dres));
        }       
        
-       public static string GetRank (string dims)
+       public static string StripIndexesFromDims (string dims)
+       {
+               StringBuilder sb = new StringBuilder();
+
+               foreach (char c in dims) 
+                       if (c == ',' || c == ']' || c == '[')
+                               sb.Append (c);
+                               
+               return sb.ToString();                           
+       }
+       
+       public static string BuildRank (ArrayList rank)
        {
                string res = "";
-               int x;
+
+               res += "[";
+               for (int x = 0; x < (rank.Count -1 ); x++)
+                       res += ",";
+                       
+               res += "]";
+               return res;
+       }
                
-               for (x = 0; x < dims.Length; x++) {
-                       if (dims[x] == '[' || dims[x] == ']' || dims[x] == ',')
-                               res = res + dims[x];
-               }                               
-               return (res);
-       }               
+       public static string BuildRanks (Parser t)
+       {
+               string res = "";
+
+               foreach (ArrayList rank in t.current_rank_specifiers)
+                       res += BuildRank (rank);
+
+               return res;
+       }       
        
-       public static ArrayList ParseDimList (string dims)
+       public static void VBFixIndexList (ref ArrayList IndexList)
        {
-               ArrayList res = new ArrayList();
-               string d = dims.Substring (1, dims.Length -2);
-               Array a = d.Split (',');
-               
-               if (a.GetLength(0) > 32) {
-                       Report.Error (999, "Arrays cannot have more than 32 dimensions");
+               if (IndexList != null) {
+                       for (int x = 0; x < IndexList.Count; x++) {
+                               Expression e = (Expression) IndexList[x];
+                               if (!(e is EmptyExpression)) {
+                                       IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
+                               }
+                       }
                }
-               
-               foreach (string s in a) 
-                       if (s != "")
-                               res.Add (new IntLiteral ((Int32) Convert.ToInt32(s)));
-                       else
-                               res.Add (new IntLiteral ((Int32) 0));
-               
-               return (res);
        }               
        
-       public static bool IsArrayDecl (string varname)
+       public static bool IsArrayDecl (Parser t)
        {
-               return (varname.IndexOf("[") >= 0);
+               // return (varname.IndexOf("[") >= 0);
+               return (t.current_rank_specifiers != null);
        }                       
        
+       public static void VBFixIndexLists (ref ArrayList ranks)
+       {       
+               if (ranks != null) {
+                       for (int x = 0; x < ranks.Count; x++) {
+                               ArrayList IndexList = (ArrayList) ranks[x];
+                               VBFixIndexList (ref IndexList);
+                       }       
+               }       
+       }
+               
        public static void FixupArrayTypes (ArrayList vars)
        {
                int varcount =  vars.Count;
@@ -3360,6 +4627,7 @@ public class VariableDeclaration {
        }                               
 }
 
+
 public Property BuildSimpleProperty (Expression p_type, string name, 
                                        Field p_fld, int mod_flags,
                                        Attributes attrs, Location loc) 
@@ -3394,7 +4662,7 @@ public Property BuildSimpleProperty (Expression p_type, string name,
        
        return (p);
 }
-               
+       
 void start_block () 
 {
        current_block = new Block (current_block, current_local_parameters,
@@ -3453,20 +4721,13 @@ private void RaiseEvent (string evt_name, ArrayList args)
        current_block.AddStatement (s); 
 }
 
-// FIXME: THIS DOES NOT WORK!!!
 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
 {
-       Location loc = lexer.Location;
-       ArrayList neh_args = new ArrayList();
-       neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
-       
-       ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
-       
-       CompoundAssign ca = new CompoundAssign (
-                       Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
-                       
-       Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc)); 
-       b.AddStatement (s);     
+       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);
 }
 
 // <summary>
@@ -3491,7 +4752,29 @@ private void RemoveHandler (Expression evt_definition, string handler_name)
        RemoveHandler (current_block, evt_definition, handler_name);
 }
 
-
+private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
+{
+       ConstructorInitializer ci = null;
+       
+       if (s.Count > 0) {
+               if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
+                       Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
+                       
+                       if (i.expr is BaseAccess) {
+                               BaseAccess ba = (BaseAccess) i.expr;
+                               if (ba.member == "New" || ba.member == ".ctor") {
+                                       ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
+                                       s.RemoveAt(0);
+                               }
+                       }
+                       if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
+                               ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location); 
+                               s.RemoveAt(0);
+                       }
+               }
+       }
+       return ci;
+}
 
 void Error_ExpectingTypeName (Location l, Expression expr)
 {
@@ -3506,39 +4789,85 @@ static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
        return true;
 }
 
-public override int parse ()
+private void ReportError9998()
+{
+       Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
+}
+
+protected override int parse ()
 {
+       RootContext.InitializeImports(ImportsList);
        current_namespace = new Namespace (null, RootContext.RootNamespace);
        current_container = RootContext.Tree.Types;
        current_container.Namespace = current_namespace;
        oob_stack = new Stack ();
        switch_stack = new Stack ();
-       
+       expr_stack = new Stack ();      
+       tmp_blocks = new Stack(); 
+       with_stack = new Stack();
+       statement_stack = new Stack();  
+
        UseExtendedSyntax = name.EndsWith(".mbs");
        OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
        OptionStrict = InitialOptionStrict || UseExtendedSyntax;
        OptionCompareBinary = InitialOptionCompareBinary;
 
        lexer = new Tokenizer (input, name, defines);
+       
+       ifElseStateMachine = new IfElseStateMachine();
+       tokenizerController = new TokenizerController(lexer);
+       
        StringBuilder value = new StringBuilder ();
-       //yacc_verbose_flag=true;
-       try 
-       {
+       try {
                if (yacc_verbose_flag)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
-               else
+               else {
                        yyparse (lexer);
+                       cleanup();
+               }
        } 
-       catch (Exception e)
-       {
-               Console.WriteLine (lexer.location + "  : Parsing error in " + lexer.ref_name);
-               Report.Error (9999, lexer.Location, "");
-               Console.WriteLine (e);
+       catch(MBASException e) {
+               Report.Error(e.code, e.loc, e.Message);
        }
-       
+       catch (Exception e) {
+               Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.EffectiveSource + "\n" + e.ToString());
+       }
+
+       RootContext.VerifyImports();
+
        return Report.Errors;
 }
 
-/* end end end */
+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 */
+}