2003-04-28 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / cs-parser.jay
index 67d928a6634838eb6ea52379fa85f35ce4ccf58a..005def9fa45a8608bce2ffa6a55904997d37358b 100755 (executable)
@@ -2,28 +2,24 @@
 //
 // cs-parser.jay: The Parser for the C# compiler
 //
-// Author: Miguel de Icaza (miguel@gnu.org)
+// Authors: Miguel de Icaza (miguel@gnu.org)
+//          Ravi Pratap     (ravi@ximian.com)
 //
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
 //
 // TODO:
-//   (1) Get rid of the *Collections.cs, that is an idea I took from System.CodeDOM
-//       And come to think of it, it is not that great, it duplicates a lot of code
-//       for something which is not really needed.  We still have piles of typecasts
-//       anwyays (due to the nature of the stack being a collection of Objects).
-//
-//   (2) Figure out why error productions dont work.  `type-declaration' is a
+//   (1) Figure out why error productions dont work.  `type-declaration' is a
 //       great spot to put an `error' because you can reproduce it with this input:
 //      "public X { }"
 //
-//   (3) Move Modifier checking from each object into the parser itself, that will
-//       get rid of the global "error" symbol that we use now to report errors. 
-//       We still need to pass a pointer to the tree.ErrorHandler, but that is a 
-//      separate problem
+// Possible optimization:
+//   Run memory profiler with parsing only, and consider dropping 
+//   arraylists where not needed.   Some pieces can use linked lists.
 //
 using System.Text;
+using System.IO;
 using System;
 
 namespace Mono.CSharp
@@ -38,6 +34,8 @@ namespace Mono.CSharp
                Namespace     current_namespace;
                TypeContainer current_container;
        
+               IIteratorContainer iterator_container;
+
                // <summary>
                //   Current block is used to add statements as we find
                //   them.  
@@ -63,7 +61,7 @@ namespace Mono.CSharp
                //   value parameter that is passed to the "set" and "get"accesor
                //   methods (properties and indexers).
                // </summary>
-               string     implicit_value_parameter_type;
+               Expression implicit_value_parameter_type;
                Parameters indexer_parameters;
 
                // <summary>
@@ -76,6 +74,16 @@ namespace Mono.CSharp
                // An out-of-band stack.
                //
                Stack oob_stack;
+
+               //
+               // Switch stack.
+               //
+               Stack switch_stack;
+
+               //
+               // The current file.
+               //
+               SourceFile file;
 %}
 
 %token EOF
@@ -89,6 +97,7 @@ namespace Mono.CSharp
 %token ABSTRACT        
 %token AS
 %token ADD
+%token ASSEMBLY
 %token BASE    
 %token BOOL    
 %token BREAK   
@@ -145,6 +154,7 @@ namespace Mono.CSharp
 %token SEALED  
 %token SHORT   
 %token SIZEOF  
+%token STACKALLOC
 %token STATIC  
 %token STRING  
 %token STRUCT  
@@ -165,6 +175,9 @@ namespace Mono.CSharp
 %token VOLATILE
 %token WHILE   
 
+/* v2 tokens */
+%token YIELD
+
 /* C# keywords which are not really keywords */
 %token GET           "get"
 %token SET           "set"
@@ -249,21 +262,30 @@ namespace Mono.CSharp
 %nonassoc HIGHPREC
 
 %start compilation_unit
-/*%start namespace_declaration */
 %%
 
 compilation_unit
-       : opt_using_directives opt_namespace_member_declarations opt_EOF
-         {
-               // Check that using comes only before namespace elements
-         }
-       ;
-
+        : outer_declarations opt_EOF
+        | outer_declarations attribute_sections opt_EOF
+        | attribute_sections opt_EOF
+       | opt_EOF /* allow empty files */
+        ;
+       
 opt_EOF
        : /* empty */
        | EOF
        ;
 
+outer_declarations
+        : outer_declaration
+        | outer_declarations outer_declaration
+        ;
+outer_declaration
+        : using_directive
+        | namespace_member_declaration
+        ;
+  
 using_directives
        : using_directive 
        | using_directives using_directive
@@ -285,19 +307,32 @@ using_alias_directive
 using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
-               current_namespace.Using ((string) $2);
+               current_namespace.Using ((string) $2, lexer.Location);
           }
        ;
 
-//  namespace_declarations
-//     : namespace_declaration
-//     | namespace_declarations namespace_declaration
-
+//
+// Strictly speaking, namespaces don't have attributes but
+// we parse global attributes along with namespace declarations and then
+// detach them
+// 
 namespace_declaration
-       : NAMESPACE qualified_identifier 
-         {
-               current_namespace = RootContext.Tree.RecordNamespace (current_namespace, name, (string) $2);
-         } 
+       : opt_attributes NAMESPACE qualified_identifier 
+       {
+               Attributes attrs = (Attributes) $1;
+
+               if (attrs != null) {
+                       foreach (AttributeSection asec in attrs.AttributeSections)
+                               if (asec.Target == "assembly")
+                                       RootContext.AddGlobalAttributeSection (current_container, asec);
+                               else
+                                       Report.Error(1518, Lexer.Location,
+                                       "Attributes cannot be applied to namespaces."
+                                       + " Expected class, delegate, enum, interface, or struct");
+               }
+
+               current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3);
+       } 
          namespace_body opt_semicolon
          { 
                current_namespace = current_namespace.Parent;
@@ -372,8 +407,11 @@ namespace_member_declaration
                                "Namespace elements cant be explicitly " +
                                "declared private or protected in `" + name + "'");
                }
+               current_namespace.DeclarationFound = true;
+         }
+       | namespace_declaration {
+               current_namespace.DeclarationFound = true;
          }
-       | namespace_declaration
        ;
 
 type_declaration
@@ -393,24 +431,42 @@ type_declaration
 //
 // Attributes 17.2
 //
+
 opt_attributes
-       : /* empty */ { $$ = null; }
-       | attribute_section opt_attributes
-         {
-               Attributes attrs;
+        : /* empty */
+       | attribute_sections { $$ = $1; }
+        ;
+attribute_sections
+       : attribute_section
+          {
+               AttributeSection sect = (AttributeSection) $1;
+
+               if (sect.Target == "assembly") 
+                       RootContext.AddGlobalAttributeSection (current_container, sect);
                
-               if ($2 != null) {
-                       attrs = (Attributes) $2;
-                       attrs.AddAttribute ((AttributeSection) $1);
-               } else
-                       attrs = new Attributes ((AttributeSection) $1);
+
+               $$ = new Attributes ((AttributeSection) $1);
+          }
+       | attribute_sections attribute_section
+         {
+               Attributes attrs = null;
+               AttributeSection sect = (AttributeSection) $2;
+
+               if (sect.Target == "assembly")
+                       RootContext.AddGlobalAttributeSection (current_container, sect);
+
+               if ($1 != null) {
+                       attrs = (Attributes) $1;
+                       attrs.AddAttributeSection (sect);
+               }
                
                $$ = attrs;
          }
        ;
 
 attribute_section
-       : OPEN_BRACKET attribute_target_specifier attribute_list CLOSE_BRACKET
+       : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
          {
                string target = null;
                
@@ -419,7 +475,7 @@ attribute_section
                
                $$ = new AttributeSection (target, (ArrayList) $3);
          }
-        | OPEN_BRACKET attribute_list CLOSE_BRACKET
+        | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
          {
                $$ = new AttributeSection (null, (ArrayList) $2);
          }
@@ -485,12 +541,16 @@ opt_attribute_arguments
 
 
 attribute_arguments
-       : positional_argument_list
+       : opt_positional_argument_list
          {
-               ArrayList args = new ArrayList ();
-               args.Add ($1);
+               if ($1 == null)
+                       $$ = null;
+               else {
+                       ArrayList args = new ArrayList ();
+                       args.Add ($1);
                
-               $$ = args;
+                       $$ = args;
+               }
          }
         | positional_argument_list COMMA named_argument_list
          {
@@ -511,6 +571,11 @@ attribute_arguments
         ;
 
 
+opt_positional_argument_list
+       : /* empty */           { $$ = null; } 
+       | positional_argument_list
+       ;
+
 positional_argument_list
        : expression
          {
@@ -595,34 +660,23 @@ struct_declaration
                                         (Attributes) $1, lexer.Location);
                current_container = new_struct;
                current_container.Namespace = current_namespace;
-               RootContext.Tree.RecordStruct (full_struct_name, new_struct);
+               RootContext.Tree.RecordDecl (full_struct_name, new_struct);
          }
-         opt_struct_interfaces
+         opt_class_base
          struct_body
          opt_semicolon
          {
                Struct new_struct = (Struct) current_container;
 
+               if ($6 != null)
+                       new_struct.Bases = (ArrayList) $6;
+
                current_container = current_container.Parent;
-               CheckDef (current_container.AddStruct (new_struct), new_struct.Name);
+               CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
                $$ = new_struct;
          }
        ;
 
-opt_struct_interfaces
-       : /* empty */
-       | struct_interfaces
-       ;
-
-struct_interfaces
-       : struct_interface
-       | struct_interfaces struct_interface
-       ; 
-
-struct_interface
-       : COLON type_list
-       ;
-
 struct_body
        : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE
        ;
@@ -664,12 +718,14 @@ constant_declaration
          SEMICOLON
          {
                foreach (VariableDeclaration constant in (ArrayList) $5){
+                       Location l = constant.Location;
+
                        Const c = new Const (
-                               (string) $4, (string) constant.identifier, 
-                               (Expression) constant.expression_or_array_initializer, (int) $2, (Attributes) $1,
-                               constant.Location);
+                               (Expression) $4, (string) constant.identifier, 
+                               (Expression) constant.expression_or_array_initializer, (int) $2, 
+                               (Attributes) $1, l);
 
-                       CheckDef (current_container.AddConstant (c), c.Name);
+                       CheckDef (current_container.AddConstant (c), c.Name, l);
                }
          }
        ;
@@ -703,14 +759,17 @@ field_declaration
          variable_declarators
          SEMICOLON
          { 
-               string type = (string) $3;
+               Expression type = (Expression) $3;
                int mod = (int) $2;
 
                foreach (VariableDeclaration var in (ArrayList) $4){
+                       Location l = var.Location;
+
                        Field field = new Field (type, mod, var.identifier, 
-                                                var.expression_or_array_initializer, (Attributes) $1, var.Location);
+                                                var.expression_or_array_initializer, 
+                                                (Attributes) $1, l);
 
-                       CheckDef (current_container.AddField (field), field.Name);
+                       CheckDef (current_container.AddField (field), field.Name, l);
                }
          }
        ;
@@ -747,17 +806,23 @@ variable_initializer
                $$ = $1;
          }
        | array_initializer
-       {
+         {
                $$ = $1;
-       }
+         }
+       | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
+         {
+               $$ = new StackAlloc ((Expression) $2, (Expression) $4, lexer.Location);
+         }
        ;
 
 method_declaration
-       : method_header
+       : method_header {
+               iterator_container = (IIteratorContainer) $1;
+         }
          method_body
          {
                Method method = (Method) $1;
-               Block b = (Block) $2;
+               Block b = (Block) $3;
                const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
 
                if (b == null){
@@ -774,10 +839,11 @@ method_declaration
                        }
                }
 
-               method.Block = (Block) $2;
-               CheckDef (current_container.AddMethod (method), method.Name);
+               method.Block = (Block) $3;
+               CheckDef (current_container.AddMethod (method), method.Name, method.Location);
 
                current_local_parameters = null;
+               iterator_container = null;
          }
        ;
 
@@ -807,7 +873,7 @@ method_header
          member_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
          {
-               Method method = new Method ((string) $3, (int) $2, (string) $4, 
+               Method method = new Method ((Expression) $3, (int) $2, (string) $4, 
                                            (Parameters) $6, (Attributes) $1, lexer.Location);
 
                current_local_parameters = (Parameters) $6;
@@ -820,7 +886,7 @@ method_header
          member_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
          {
-               Method method = new Method ("System.Void", (int) $2, (string) $4, 
+               Method method = new Method (TypeManager.system_void_expr, (int) $2, (string) $4, 
                                            (Parameters) $6, (Attributes) $1, lexer.Location);
 
                current_local_parameters = (Parameters) $6;
@@ -834,7 +900,7 @@ method_body
        ;
 
 opt_formal_parameter_list
-       : /* empty */                   { $$ = Parameters.GetEmptyReadOnlyParameters (); }
+       : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
        | formal_parameter_list
        ;
 
@@ -886,7 +952,7 @@ fixed_parameter
          type
          IDENTIFIER
          {
-               $$ = new Parameter ((string) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
+               $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
          }
        ;
 
@@ -896,14 +962,14 @@ opt_parameter_modifier
        ;
 
 parameter_modifier
-       : REF                   { $$ = Parameter.Modifier.REF; }
-       | OUT                   { $$ = Parameter.Modifier.OUT; }
+       : REF                   { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
+       | OUT                   { $$ = Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF; }
        ;
 
 parameter_array
        : opt_attributes PARAMS type IDENTIFIER
          { 
-               $$ = new Parameter ((string) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
+               $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
                note ("type must be a single-dimension array type"); 
          }
        ;
@@ -918,7 +984,7 @@ property_declaration
          type member_name
          OPEN_BRACE 
          {
-               implicit_value_parameter_type = (string) $3;
+               implicit_value_parameter_type = (Expression) $3;
 
                lexer.PropertyParsing = true;
 
@@ -932,18 +998,14 @@ property_declaration
          { 
                Property prop;
                Pair pair = (Pair) $7;
-               Block get_block = null;
-               Block set_block = null;
-
-               if (pair.First != null)
-                       get_block = (Block) pair.First;
-               if (pair.Second != null)
-                       set_block = (Block) pair.Second;
+               Accessor get_block = (Accessor) pair.First;
+               Accessor set_block = (Accessor) pair.Second;
 
-               prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block,
-                                    (Attributes) $1, (Location) $6);
+               Location loc = (Location) $6;
+               prop = new Property ((Expression) $3, (string) $4, (int) $2, get_block, set_block,
+                                    (Attributes) $1, loc);
                
-               CheckDef (current_container.AddProperty (prop), prop.Name);
+               CheckDef (current_container.AddProperty (prop), prop.Name, loc);
                implicit_value_parameter_type = null;
          }
        ;
@@ -982,7 +1044,7 @@ get_accessor_declaration
          }
           accessor_body
          {
-               $$ = $4;
+               $$ = new Accessor ((Block) $4, (Attributes) $1);
                current_local_parameters = null;
                lexer.PropertyParsing = true;
          }
@@ -999,22 +1061,27 @@ set_accessor_declaration
                if (parsing_indexer == false) {
                        args  = new Parameter [1];
                        args [0] = implicit_value_parameter;
+                       current_local_parameters = new Parameters (args, null, lexer.Location);
                } else {
-                       Parameter [] fp = indexer_parameters.FixedParameters;
-                       int count = fp.Length;
-
-                       args = new Parameter [count + 1];
-       
-                       fp.CopyTo (args, 0);
-                       args [count] = implicit_value_parameter;
+                       Parameter [] fpars = indexer_parameters.FixedParameters;
+
+                       if (fpars != null){
+                               int count = fpars.Length;
+
+                               args = new Parameter [count + 1];
+                               fpars.CopyTo (args, 0);
+                               args [count] = implicit_value_parameter;
+                       } else 
+                               args = null;
+                       current_local_parameters = new Parameters (
+                               args, indexer_parameters.ArrayParameter, lexer.Location);
                }
                
-               current_local_parameters = new Parameters (args, null, lexer.Location);
                lexer.PropertyParsing = false;
          }
          accessor_body
          {
-               $$ = $4;
+               $$ = new Accessor ((Block) $4, (Attributes) $1);
                current_local_parameters = null;
                lexer.PropertyParsing = true;
          }
@@ -1022,7 +1089,7 @@ set_accessor_declaration
 
 accessor_body
        : block 
-       | SEMICOLON             { $$ = new Block (null); }
+       | SEMICOLON             { $$ = null; }
        ;
 
 interface_declaration
@@ -1041,10 +1108,10 @@ interface_declaration
                }
                current_interface = new_interface;
                new_interface.Namespace = current_namespace;
-               RootContext.Tree.RecordInterface (full_interface_name, new_interface);
+               RootContext.Tree.RecordDecl (full_interface_name, new_interface);
          }
          opt_interface_base
-         interface_body
+         interface_body opt_semicolon
          { 
                Interface new_interface = (Interface) current_interface;
 
@@ -1052,7 +1119,8 @@ interface_declaration
                        new_interface.Bases = (ArrayList) $6;
 
                current_interface = null;
-               CheckDef (current_container.AddInterface (new_interface), new_interface.Name);
+               CheckDef (current_container.AddInterface (new_interface), 
+                         new_interface.Name, new_interface.Location);
          }
        ;
 
@@ -1102,25 +1170,25 @@ interface_member_declaration
          { 
                InterfaceMethod m = (InterfaceMethod) $1;
 
-               CheckDef (current_interface.AddMethod (m), m.Name);
+               CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
          }
        | interface_property_declaration        
          { 
                InterfaceProperty p = (InterfaceProperty) $1;
 
-               CheckDef (current_interface.AddProperty (p), p.Name);
+               CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
           }
        | interface_event_declaration 
           { 
                InterfaceEvent e = (InterfaceEvent) $1;
 
-               CheckDef (current_interface.AddEvent (e), e.Name);
+               CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
          }
        | interface_indexer_declaration
          { 
                InterfaceIndexer i = (InterfaceIndexer) $1;
 
-               CheckDef (current_interface.AddIndexer (i), "indexer");
+               CheckDef (current_interface.AddIndexer (i), "indexer", i.Location);
          }
        ;
 
@@ -1134,14 +1202,15 @@ interface_method_declaration
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
          SEMICOLON
          {
-               $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2, 
+               $$ = new InterfaceMethod ((Expression) $3, (string) $4, (bool) $2, 
                                          (Parameters) $6, (Attributes) $1, lexer.Location);
          }
        | opt_attributes opt_new VOID IDENTIFIER 
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
          SEMICOLON
          {
-               $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6, 
+               $$ = new InterfaceMethod (
+                       TypeManager.system_void_expr, (string) $4, (bool) $2, (Parameters) $6, 
                                          (Attributes) $1, lexer.Location);
          }
        ;
@@ -1158,7 +1227,7 @@ interface_property_declaration
          {
                int gs = (int) $7;
 
-               $$ = new InterfaceProperty ((string) $3, (string) $4, (bool) $2, 
+               $$ = new InterfaceProperty ((Expression) $3, (string) $4, (bool) $2, 
                                            (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1,
                                            lexer.Location);
          }
@@ -1176,7 +1245,8 @@ interface_accesors
 interface_event_declaration
        : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
          {
-               $$ = new InterfaceEvent ((string) $4, (string) $5, (bool) $2, (Attributes) $1);
+               $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
+                                        lexer.Location);
          }
        ;
 
@@ -1194,13 +1264,13 @@ interface_indexer_declaration
                bool do_get = (a_flags & 1) == 1;
                bool do_set = (a_flags & 2) == 2;
 
-               $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set,
+               $$ = new InterfaceIndexer ((Expression) $3, (Parameters) $6, do_get, do_set,
                                           (bool) $2, (Attributes) $1, lexer.Location);
          }
        ;
 
 operator_declaration
-       : opt_attributes opt_modifiers operator_declarator block
+       : opt_attributes opt_modifiers operator_declarator operator_body
          {
                OperatorDeclaration decl = (OperatorDeclaration) $3;
                
@@ -1214,6 +1284,10 @@ operator_declaration
          }
        ;
 
+operator_body 
+       : block
+       | SEMICOLON { $$ = null; }
+       ; 
 operator_declarator
        : type OPERATOR overloadable_operator 
          OPEN_PARENS type IDENTIFIER CLOSE_PARENS
@@ -1229,11 +1303,11 @@ operator_declarator
 
                Parameter [] pars = new Parameter [1];
 
-               pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);
 
-               $$ = new OperatorDeclaration (op, (string) $1, (string) $5, (string) $6,
+               $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6,
                                              null, null, lexer.Location);
        }
        | type OPERATOR overloadable_operator
@@ -1246,13 +1320,14 @@ operator_declarator
 
               Parameter [] pars = new Parameter [2];
 
-              pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
-              pars [1] = new Parameter ((string) $8, (string) $9, Parameter.Modifier.NONE, null);
+              pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
+              pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null);
 
               current_local_parameters = new Parameters (pars, null, lexer.Location);
               
-              $$ = new OperatorDeclaration ((Operator.OpType) $3, (string) $1, (string) $5, (string) $6,
-                                            (string) $8, (string) $9, lexer.Location);
+              $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1, 
+                                            (Expression) $5, (string) $6,
+                                            (Expression) $8, (string) $9, lexer.Location);
         }
        | conversion_operator_declarator
        ;
@@ -1290,22 +1365,22 @@ conversion_operator_declarator
          {
                Parameter [] pars = new Parameter [1];
 
-               pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);  
                  
-               $$ = new OperatorDeclaration (Operator.OpType.Implicit, (string) $3, (string) $5, (string) $6,
+               $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, (Expression) $5, (string) $6,
                                              null, null, lexer.Location);
          }
        | EXPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
          {
                Parameter [] pars = new Parameter [1];
 
-               pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);  
                  
-               $$ = new OperatorDeclaration (Operator.OpType.Explicit, (string) $3, (string) $5, (string) $6,
+               $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, (Expression) $5, (string) $6,
                                              null, null, lexer.Location);
          }
        | IMPLICIT error 
@@ -1322,31 +1397,44 @@ constructor_declaration
        : opt_attributes
          opt_modifiers
          constructor_declarator
-         block
+         constructor_body
          { 
                Constructor c = (Constructor) $3;
                c.Block = (Block) $4;
-               c.ModFlags = (int) $2;
                c.OptAttributes = (Attributes) $1;
-
-               if ((c.ModFlags & Modifiers.STATIC) != 0){
-                       if ((c.ModFlags & Modifiers.Accessibility) != 0) {
-                               Location l = lexer.Location;
-                               Report.Error (515, l, "Access modifiers are not allowed on static constructors");
+               c.ModFlags = (int) $2;
+       
+               if (c.Name == current_container.Basename){
+                       if ((c.ModFlags & Modifiers.STATIC) != 0){
+                               if ((c.ModFlags & Modifiers.Accessibility) != 0){
+                                       Report.Error (
+                                               515, c.Location, String.Format (
+                                               "`{0}.{1}': static constructor can not have access modifiers",
+                                               c.Name, current_container.Name));
+                               }
+       
+                               c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);   
+       
+                               if (c.Initializer != null){
+                                       Report.Error (
+                                               514, c.Location, 
+                                               "Static constructors can not have an explicit this or base " +
+                                               "constructor invocations");
+                               }
+       
+                               if (!c.Parameters.Empty){
+                                       Report.Error (
+                                               132, c.Location, "Static constructors should not have parameters");
+                               }
+                       } else {
+                               c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
                        }
+               } else {
+                       // We let another layer check the validity of the constructor.
+                       Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename);
+               }
 
-                       if (c.Initializer != null){
-                               Location l = lexer.Location;
-                               Report.Error (514, l, "Static constructors can not have an explicit this or base constructor invocations");
-                       }
-
-                       if (!c.Parameters.Empty){
-                               Location l = lexer.Location;
-                               Report.Error (132, l, "Static constructors should not have parameters");
-                       }
-               } 
-               
-               CheckDef (current_container.AddConstructor (c), c.Name);
+               CheckDef (current_container.AddConstructor (c), c.Name, c.Location);
 
                current_local_parameters = null;
          }
@@ -1367,6 +1455,11 @@ constructor_declarator
          }
        ;
 
+constructor_body
+       : block
+       | SEMICOLON             { $$ = null; }
+       ;
+
 opt_constructor_initializer
        : /* empty */                   { $$ = null; }
        | constructor_initializer
@@ -1375,11 +1468,11 @@ opt_constructor_initializer
 constructor_initializer
        : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
          {
-               $$ = new ConstructorBaseInitializer ((ArrayList) $4, lexer.Location);
+               $$ = new ConstructorBaseInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
          }
        | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
          {
-               $$ = new ConstructorThisInitializer ((ArrayList) $4, lexer.Location);
+               $$ = new ConstructorThisInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
          }
        ;
 
@@ -1393,12 +1486,18 @@ destructor_declaration
                } else {
                        Location l = lexer.Location;
 
+                       int m;
+                       if (!RootContext.StdLib && current_container.Name == "System.Object")
+                               m = Modifiers.PROTECTED | Modifiers.VIRTUAL;
+                       else
+                               m = Modifiers.PROTECTED | Modifiers.OVERRIDE;
+
                        Method d = new Method (
-                               "System.Void", 0, "Finalize", 
+                               TypeManager.system_void_expr, m, "Finalize", 
                                new Parameters (null, null, l), (Attributes) $1, l);
                  
                        d.Block = (Block) $6;
-                       CheckDef (current_container.AddMethod (d), d.Name);
+                       CheckDef (current_container.AddMethod (d), d.Name, d.Location);
                }
          }
        ;
@@ -1410,10 +1509,11 @@ event_declaration
          {
                foreach (VariableDeclaration var in (ArrayList) $5) {
 
-                       Event e = new Event ((string) $4, var.identifier, var.expression_or_array_initializer,
+                       Event e = new Event ((Expression) $4, var.identifier, 
+                                            var.expression_or_array_initializer,
                                             (int) $2, null, null, (Attributes) $1, lexer.Location);
 
-                       CheckDef (current_container.AddEvent (e), e.Name);
+                       CheckDef (current_container.AddEvent (e), e.Name, e.Location);
                                       
                }
          }
@@ -1422,8 +1522,9 @@ event_declaration
          EVENT type member_name
          OPEN_BRACE
          {
-               implicit_value_parameter_type = (string) $4;  
+               implicit_value_parameter_type = (Expression) $4;  
                lexer.EventParsing = true;
+               oob_stack.Push (lexer.Location);
          }
          event_accessor_declarations
          {
@@ -1431,19 +1532,21 @@ event_declaration
          }
          CLOSE_BRACE
          {
+               Location loc = (Location) oob_stack.Pop ();
+
                Pair pair = (Pair) $8;
-               Block add_block = null;
-               Block rem_block = null;
+               Accessor add_accessor = null;
+               Accessor rem_accessor = null;
 
                if (pair.First != null)
-                       add_block = (Block) pair.First;
+                       add_accessor = (Accessor) pair.First;
                if (pair.Second != null)
-                       rem_block = (Block) pair.Second;
+                       rem_accessor = (Accessor) pair.Second;
                
-               Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_block, rem_block,
-                                    (Attributes) $1, lexer.Location);
+               Event e = new Event ((Expression) $4, (string) $5, null, (int) $2, add_accessor, rem_accessor,
+                                    (Attributes) $1, loc);
                
-               CheckDef (current_container.AddEvent (e), e.Name);
+               CheckDef (current_container.AddEvent (e), e.Name, loc);
                implicit_value_parameter_type = null;
          }
        ;
@@ -1474,9 +1577,13 @@ add_accessor_declaration
          }
           block
          {
-               $$ = $4;
+               $$ = new Accessor ((Block) $4, (Attributes) $1);
                lexer.EventParsing = true;
          }
+       | opt_attributes ADD error {
+               Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
+               $$ = null;
+         }
        ;
 
 remove_accessor_declaration
@@ -1494,9 +1601,13 @@ remove_accessor_declaration
          }
           block
          {
-               $$ = $4;
+               $$ = new Accessor ((Block) $4, (Attributes) $1);
                lexer.EventParsing = true;
          }
+       | opt_attributes REMOVE error {
+               Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
+               $$ = null;
+         }
        ;
 
 indexer_declaration
@@ -1511,7 +1622,7 @@ indexer_declaration
                parsing_indexer  = true;
                
                indexer_parameters = decl.param_list;
-               $$ = lexer.Location;
+               oob_stack.Push (lexer.Location);
          }
           accessor_declarations 
          {
@@ -1522,20 +1633,15 @@ indexer_declaration
          { 
                // The signature is computed from the signature of the indexer.  Look
                // at section 3.6 on the spec
-
+               Location loc = (Location) oob_stack.Pop ();
                Indexer indexer;
                IndexerDeclaration decl = (IndexerDeclaration) $3;
                Pair pair = (Pair) $6;
-               Block get_block = null;
-               Block set_block = null;
-
-               if (pair.First != null)
-                       get_block = (Block) pair.First;
-               if (pair.Second != null)
-                       set_block = (Block) pair.Second;
+               Accessor get_block = (Accessor) pair.First;
+               Accessor set_block = (Accessor) pair.Second;
 
                indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list,
-                                      get_block, set_block, (Attributes) $1, (Location) $5);
+                                      get_block, set_block, (Attributes) $1, loc);
 
                // Note that there is no equivalent of CheckDef for this case
                // We shall handle this in semantic analysis
@@ -1553,47 +1659,56 @@ indexer_declarator
          {
                Parameters pars = (Parameters) $4;
 
-               if (pars.FixedParameters == null){
+               if (pars.FixedParameters == null && pars.ArrayParameter == null){
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
 
-               $$ = new IndexerDeclaration ((string) $1, null, pars);
+               $$ = new IndexerDeclaration ((Expression) $1, null, pars);
          }
        | type qualified_identifier DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
          {
                Parameters pars = (Parameters) $6;
 
-               if (pars.FixedParameters == null){
+               if (pars.FixedParameters == null && pars.ArrayParameter == null){
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
-               $$ = new IndexerDeclaration ((string) $1, (string) $2, pars);
+               $$ = new IndexerDeclaration ((Expression) $1, (string) $2, pars);
          }
        ;
 
 enum_declaration
        : opt_attributes
          opt_modifiers
-         ENUM IDENTIFIER
+         ENUM IDENTIFIER 
          opt_enum_base
          enum_body
          opt_semicolon
          { 
+               Location enum_location = lexer.Location;
+
                string full_name = MakeName ((string) $4);
-               Enum e = new Enum (current_container, (string) $5, (int) $2, full_name, (Attributes) $1, lexer.Location);
+               Enum e = new Enum (current_container, (Expression) $5, (int) $2, full_name, 
+                                  (Attributes) $1, enum_location);
+               
+               foreach (VariableDeclaration ev in (ArrayList) $6) {
+                       Location loc = (Location) ev.Location;
 
-               foreach (VariableDeclaration ev in (ArrayList) $6){
                        CheckDef (e.AddEnumMember (ev.identifier, 
                                                   (Expression) ev.expression_or_array_initializer,
-                                                  (Location) ev.Location),
-                                 ev.identifier);
+                                                  loc, ev.OptAttributes),
+                                 ev.identifier, loc);
                }
 
-               CheckDef (current_container.AddEnum (e), name);
+               e.Namespace = current_namespace;
+
+               CheckDef (current_container.AddEnum (e), full_name, enum_location);
+               RootContext.Tree.RecordDecl (full_name, e);
+
          }
        ;
 
 opt_enum_base
-       : /* empty */           { $$ = "System.Int32"; }
+       : /* empty */           { $$ = TypeManager.system_int32_expr; }
        | COLON type            { $$ = $2;   }
        ;
 
@@ -1630,7 +1745,7 @@ enum_member_declarations
 enum_member_declaration
        : opt_attributes IDENTIFIER 
          {
-               $$ = new VariableDeclaration ((string) $2, null, lexer.Location);
+               $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
          }
        | opt_attributes IDENTIFIER
          {
@@ -1638,7 +1753,7 @@ enum_member_declaration
          }
           ASSIGN expression
          { 
-               $$ = new VariableDeclaration ((string) $2, $5, lexer.Location);
+               $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
          }
        ;
 
@@ -1651,11 +1766,13 @@ delegate_declaration
          CLOSE_PARENS 
          SEMICOLON
          {
-               Delegate del = new Delegate ((string) $4, (int) $2, 
+               Location l = lexer.Location;
+               Delegate del = new Delegate (current_container, (Expression) $4, (int) $2, 
                                             MakeName ((string) $5), (Parameters) $7, 
-                                            (Attributes) $1, lexer.Location);
+                                            (Attributes) $1, l);
                  
-               CheckDef (current_container.AddDelegate (del), del.Name);
+               del.Namespace = current_namespace;
+               CheckDef (current_container.AddDelegate (del), del.Name, l);
          }     
        | opt_attributes
          opt_modifiers
@@ -1665,10 +1782,14 @@ delegate_declaration
          CLOSE_PARENS 
          SEMICOLON
          {
-               Delegate del = new Delegate ("System.Void", (int) $2, (string) $5, (Parameters) $7, 
-                                            (Attributes) $1, lexer.Location);
+               Location l = lexer.Location;
+               Delegate del = new Delegate (
+                       current_container,
+                       TypeManager.system_void_expr, (int) $2, MakeName ((string) $5), 
+                       (Parameters) $7, (Attributes) $1, l);
 
-               CheckDef (current_container.AddDelegate (del), del.Name);
+               del.Namespace = current_namespace;
+               CheckDef (current_container.AddDelegate (del), del.Name, l);
          }
        ;
 
@@ -1692,7 +1813,7 @@ type
                   This does interfaces, delegates, struct_types, class_types, 
                   parent classes, and more! 4.2 
                 */
-               $$ = $1; 
+               $$ = DecomposeQI ((string) $1, lexer.Location);
          }
        | builtin_types
        | array_type
@@ -1708,19 +1829,16 @@ pointer_type
                // can't perform checks during this phase - we do it during
                // semantic analysis.
                //
-               $$ = (string) $1 + "*";
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
          }
        | VOID STAR
          {
-               $$ = "System.Void*";
+               $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);
          }
        ;
 
 non_expression_type
        : builtin_types 
-         {
-               $$ = new SimpleName ((string) $1, lexer.Location);
-         }
        | non_expression_type rank_specifier
          {
                $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
@@ -1737,6 +1855,15 @@ non_expression_type
          {
                $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
          }
+       
+       //
+       // We need this because the parser will happily go and reduce IDENTIFIER STAR
+       // through this different path
+       //
+       | multiplicative_expression STAR 
+         {
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+         }
        ;
 
 type_list
@@ -1761,25 +1888,26 @@ type_list
  * simple types, but we need this to reuse it easily in local_variable_type
  */
 builtin_types
-       : OBJECT        { $$ = "System.Object"; }
-       | STRING        { $$ = "System.String"; }
-       | BOOL          { $$ = "System.Boolean"; }
-       | DECIMAL       { $$ = "System.Decimal"; }
-       | FLOAT         { $$ = "System.Single"; }
-       | DOUBLE        { $$ = "System.Double"; }
+       : OBJECT        { $$ = TypeManager.system_object_expr; }
+       | STRING        { $$ = TypeManager.system_string_expr; }
+       | BOOL          { $$ = TypeManager.system_boolean_expr; }
+       | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
+       | FLOAT         { $$ = TypeManager.system_single_expr; }
+       | DOUBLE        { $$ = TypeManager.system_double_expr; }
        | integral_type
        ;
 
 integral_type
-       : SBYTE         { $$ = "System.SByte"; }
-       | BYTE          { $$ = "System.Byte"; }
-       | SHORT         { $$ = "System.Int16"; }
-       | USHORT        { $$ = "System.UInt16"; }
-       | INT           { $$ = "System.Int32"; }
-       | UINT          { $$ = "System.UInt32"; }
-       | LONG          { $$ = "System.Int64"; }
-       | ULONG         { $$ = "System.UInt64"; }
-       | CHAR          { $$ = "System.Char"; }
+       : SBYTE         { $$ = TypeManager.system_sbyte_expr; }
+       | BYTE          { $$ = TypeManager.system_byte_expr; }
+       | SHORT         { $$ = TypeManager.system_int16_expr; }
+       | USHORT        { $$ = TypeManager.system_uint16_expr; }
+       | INT           { $$ = TypeManager.system_int32_expr; }
+       | UINT          { $$ = TypeManager.system_uint32_expr; }
+       | LONG          { $$ = TypeManager.system_int64_expr; }
+       | ULONG         { $$ = TypeManager.system_uint64_expr; }
+       | CHAR          { $$ = TypeManager.system_char_expr; }
+       | VOID          { $$ = TypeManager.system_void_expr; }
        ;
 
 interface_type
@@ -1789,7 +1917,7 @@ interface_type
 array_type
        : type rank_specifiers
          {
-                 $$ = (string) $1 + (string) $2;
+               $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
          }
        ;
 
@@ -1823,8 +1951,6 @@ primary_expression
        | checked_expression
        | unchecked_expression
        | pointer_member_access
-       // TODO: pointer_element_access
-       // TODO: sizeof-expression
        ;
 
 literal
@@ -1846,10 +1972,6 @@ integer_literal
        : LITERAL_INTEGER       { 
                object v = lexer.Value;
 
-               // 
-               // FIXME: Possible optimization would be to 
-               // compute the *Literal objects directly in the scanner
-               //
                if (v is int)
                        $$ = new IntLiteral ((Int32) v); 
                else if (v is uint)
@@ -1880,7 +2002,7 @@ member_access
          }
        | predefined_type DOT IDENTIFIER
          {
-               $$ = new SimpleName ((string) $1 + "." + (string) $3, lexer.Location);
+               $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
          }
        ;
 
@@ -1893,7 +2015,7 @@ invocation_expression
          {
                if ($1 == null) {
                        Location l = lexer.Location;
-                       Report.Error (1, l, "THIS IS CRAZY");
+                       Report.Error (1, l, "Parse error");
                }
                $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
          }
@@ -1953,17 +2075,18 @@ element_access
                // Blah i;
                  
                Expression expr = (Expression) $1;  
-               if (!(expr is SimpleName || expr is MemberAccess)) {
-                       Location l = lexer.Location;
-                       Report.Error (-1, l, "Invalid Type definition");
-                       $$ = "System.Object";
+               if (expr is ComposedCast){
+                       $$ = new ComposedCast (expr, (string) $2, lexer.Location);
+               } else 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 ComposedCast (expr, (string) $2, lexer.Location);
                }
-               
-               //
-               // So we extract the string corresponding to the SimpleName
-               // or MemberAccess
-               // 
-               $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
          }
        ;
 
@@ -1985,7 +2108,7 @@ expression_list
 this_access
        : THIS
          {
-               $$ = new This (lexer.Location);
+               $$ = new This (current_block, lexer.Location);
          }
        ;
 
@@ -2024,7 +2147,7 @@ new_expression
 object_or_delegate_creation_expression
        : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
          {
-               $$ = new New ((string) $2, (ArrayList) $4, lexer.Location);
+               $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
          }
        ;
 
@@ -2033,12 +2156,11 @@ array_creation_expression
          opt_rank_specifier
          opt_array_initializer
          {
-               $$ = new ArrayCreation ((string) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, 
-                                       lexer.Location);
+               $$ = new ArrayCreation ((Expression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, lexer.Location);
          }
        | NEW type rank_specifiers array_initializer
          {
-               $$ = new ArrayCreation ((string) $2, (string) $3, (ArrayList) $4, lexer.Location);
+               $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, lexer.Location);
          }
        | NEW type error 
          {
@@ -2058,14 +2180,10 @@ opt_rank_specifier
        ;
 
 rank_specifiers
-       : rank_specifier
-         {
-                 $$ = $1;
-         }
-       | rank_specifiers rank_specifier
+       : rank_specifier opt_rank_specifier
          {
                  $$ = (string) $2 + (string) $1;
-         }             
+         }
         ;
 
 rank_specifier
@@ -2138,30 +2256,27 @@ variable_initializer_list
 typeof_expression
        : TYPEOF OPEN_PARENS type CLOSE_PARENS
          {
-               $$ = new TypeOf ((string) $3, lexer.Location);
+               $$ = new TypeOf ((Expression) $3, lexer.Location);
          }
        ;
 
 sizeof_expression
        : SIZEOF OPEN_PARENS type CLOSE_PARENS { 
-               $$ = new SizeOf ((string) $3, lexer.Location);
-
-               note ("Verify type is unmanaged"); 
-               note ("if (5.8) builtin, yield constant expression");
+               $$ = new SizeOf ((Expression) $3, lexer.Location);
          }
        ;
 
 checked_expression
        : CHECKED OPEN_PARENS expression CLOSE_PARENS
          {
-               $$ = new CheckedExpr ((Expression) $3);
+               $$ = new CheckedExpr ((Expression) $3, lexer.Location);
          }
        ;
 
 unchecked_expression
        : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
          {
-               $$ = new UnCheckedExpr ((Expression) $3);
+               $$ = new UnCheckedExpr ((Expression) $3, lexer.Location);
          }
        ;
 
@@ -2184,7 +2299,11 @@ unary_expression
          {
                $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location);
          }
-        | OPEN_PARENS expression CLOSE_PARENS unary_expression
+       | cast_expression
+       ;
+
+cast_expression
+        : OPEN_PARENS expression CLOSE_PARENS unary_expression
          {
                  $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
          }
@@ -2315,11 +2434,11 @@ relational_expression
          }
        | relational_expression IS type
          {
-               $$ = new Is ((Expression) $1, (string) $3, lexer.Location);
+               $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
          }
        | relational_expression AS type
          {
-               $$ = new As ((Expression) $1, (string) $3, lexer.Location);
+               $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
          }
        ;
 
@@ -2399,91 +2518,71 @@ assignment_expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.Multiply, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_DIV_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.Division, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_MOD_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.Modulus, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.Modulus, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_ADD_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.Addition, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_SUB_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.Subtraction, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.LeftShift, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.RightShift, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.RightShift, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_AND_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.BitwiseAnd, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_OR_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.BitwiseOr, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, l);
          }
        | prefixed_unary_expression OP_XOR_ASSIGN expression
          {
                Location l = lexer.Location;
 
-               $$ = new Assign ((Expression) $1,
-                                new Binary (Binary.Operator.ExclusiveOr, 
-                                            (Expression) $1,
-                                            (Expression) $3, l), l);
+               $$ = new CompoundAssign (
+                       Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, l);
          }
        ;
 
@@ -2517,7 +2616,7 @@ class_declaration
                                       (Attributes) $1, lexer.Location);
                current_container = new_class;
                current_container.Namespace = current_namespace;
-               RootContext.Tree.RecordClass (name, new_class);
+               RootContext.Tree.RecordDecl (name, new_class);
          }
          opt_class_base
          class_body 
@@ -2529,7 +2628,7 @@ class_declaration
                        new_class.Bases = (ArrayList) $6;
 
                current_container = current_container.Parent;
-               CheckDef (current_container.AddClass (new_class), new_class.Name);
+               CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
 
                $$ = new_class;
          }
@@ -2597,13 +2696,15 @@ class_base
 block
        : OPEN_BRACE 
          {
-               current_block = new Block (current_block);
+               current_block = new Block (current_block, current_local_parameters,
+                                          lexer.Location, Location.Null);
          } 
          opt_statement_list CLOSE_BRACE 
          { 
                while (current_block.Implicit)
                        current_block = current_block.Parent;
                $$ = current_block;
+               current_block.SetEndLocation (lexer.Location);
                current_block = current_block.Parent;
          }
        ;
@@ -2621,7 +2722,7 @@ statement_list
 statement
        : declaration_statement
          {
-               if ((Block) $1 != current_block){
+               if ($1 != null && (Block) $1 != current_block){
                        current_block.AddStatement ((Statement) $1);
                        current_block = (Block) $1;
                }
@@ -2662,7 +2763,7 @@ empty_statement
 labeled_statement
        : IDENTIFIER COLON 
          {
-               LabeledStatement labeled = new LabeledStatement ((string) $1);
+               LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
 
                if (!current_block.AddLabel ((string) $1, labeled)){
                        Location l = lexer.Location;
@@ -2676,16 +2777,20 @@ labeled_statement
 declaration_statement
        : local_variable_declaration SEMICOLON
          {
-               DictionaryEntry de = (DictionaryEntry) $1;
+               if ($1 != null){
+                       DictionaryEntry de = (DictionaryEntry) $1;
 
-               $$ = declare_local_variables ((string) de.Key, (ArrayList) de.Value, lexer.Location);
+                       $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
+               }
          }
 
        | local_constant_declaration SEMICOLON
          {
-               DictionaryEntry de = (DictionaryEntry) $1;
+               if ($1 != null){
+                       DictionaryEntry de = (DictionaryEntry) $1;
 
-               $$ = declare_local_constant ((string) de.Key, (VariableDeclaration) de.Value);
+                       $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
+               }
          }
        ;
 
@@ -2715,21 +2820,27 @@ local_variable_type
                // Blah i;
                  
                Expression expr = (Expression) $1;  
-               if (!(expr is SimpleName || expr is MemberAccess)) {
-                       Location l = lexer.Location;
-                       Report.Error (-1, l, "Invalid Type definition");
-                       $$ = "System.Object";
+               if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
+                       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);
                }
-               
-               //
-               // So we extract the string corresponding to the SimpleName
-               // or MemberAccess
-               // 
-               $$ = GetQualifiedIdentifier (expr) + (string) $2;
          }
        | builtin_types opt_rank_specifier
          {
-                 $$ = (string) $1 + (string) $2;
+               if ((string) $2 == "")
+                       $$ = $1;
+               else
+                       $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
          }
         ;
 
@@ -2737,43 +2848,59 @@ local_variable_pointer_type
        : primary_expression STAR
          {
                Expression expr = (Expression) $1;  
-               if (!(expr is SimpleName || expr is MemberAccess)) {
-                       Location l = lexer.Location;
-                       Report.Error (-1, l, "Invalid Type definition");
-                       $$ = "System.Object";
-               }
-               
-               $$ = GetQualifiedIdentifier (expr) + "*";
+               Location l = lexer.Location;
+
+               if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
+                       Error_ExpectingTypeName (l, expr);
+
+                       $$ = null;
+               } else 
+                       $$ = new ComposedCast ((Expression) $1, "*", l);
          }
         | builtin_types STAR
          {
-               $$ = (string) $1 + "*";
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);;
          }
         | VOID STAR
          {
-               $$ = "System.Void*";
+               $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);;
          }
        | local_variable_pointer_type STAR
           {
-               $$ = (string) $1 + "*";
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
          }
         ;
 
 local_variable_declaration
        : local_variable_type variable_declarators
          {
-               $$ = new DictionaryEntry ($1, $2);
+               if ($1 != null)
+                       $$ = new DictionaryEntry ($1, $2);
+               else
+                       $$ = null;
          }
         | local_variable_pointer_type opt_rank_specifier variable_declarators
        {
-               $$ = new DictionaryEntry ((string) $1 + (string) $2, $3);
+               if ($1 != null){
+                       Expression t;
+
+                       if ((string) $2 == "")
+                               t = (Expression) $1;
+                       else
+                               t = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
+                       $$ = new DictionaryEntry (t, $3);
+               } else 
+                       $$ = null;
        }
        ;
 
 local_constant_declaration
        : CONST local_variable_type constant_declarator
          {
-               $$ = new DictionaryEntry ($2, $3);
+               if ($2 != null)
+                       $$ = new DictionaryEntry ($2, $3);
+               else
+                       $$ = null;
          }
        ;
 
@@ -2789,13 +2916,13 @@ expression_statement
        // because statement_expression is used for example in for_statement
        //
 statement_expression
-       : invocation_expression         { $$ = new StatementExpression ((ExpressionStatement) $1); }
-       | object_creation_expression    { $$ = new StatementExpression ((ExpressionStatement) $1); }
-       | assignment_expression         { $$ = new StatementExpression ((ExpressionStatement) $1); }
-       | post_increment_expression     { $$ = new StatementExpression ((ExpressionStatement) $1); }
-       | post_decrement_expression     { $$ = new StatementExpression ((ExpressionStatement) $1); }
-       | pre_increment_expression      { $$ = new StatementExpression ((ExpressionStatement) $1); }
-       | pre_decrement_expression      { $$ = new StatementExpression ((ExpressionStatement) $1); }
+       : invocation_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+       | object_creation_expression    { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+       | assignment_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+       | post_increment_expression     { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+       | post_decrement_expression     { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+       | pre_increment_expression      { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+       | pre_decrement_expression      { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
        | error {
                Report.Error (1002, lexer.Location, "Expecting `;'");
          }
@@ -2812,21 +2939,39 @@ selection_statement
        ; 
 
 if_statement
-       : IF OPEN_PARENS boolean_expression CLOSE_PARENS 
+       : if_statement_open if_statement_rest
+         {
+               $$ = $2;
+         }
+       ;
+
+if_statement_open
+       : IF OPEN_PARENS 
+         {
+               oob_stack.Push (lexer.Location);
+         }
+       ;
+
+if_statement_rest
+       : boolean_expression CLOSE_PARENS 
          embedded_statement
          { 
-               $$ = new If ((Expression) $3, (Statement) $5);
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new If ((Expression) $1, (Statement) $3, l);
 
                if (RootContext.WarningLevel >= 3){
-                       if ($5 is EmptyStatement)
+                       if ($3 is EmptyStatement)
                                Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
                }
 
          }
-       | IF OPEN_PARENS boolean_expression CLOSE_PARENS
+       | boolean_expression CLOSE_PARENS
          embedded_statement ELSE embedded_statement
          {
-               $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7);
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new If ((Expression) $1, (Statement) $3, (Statement) $5, l);
          }
        ;
 
@@ -2834,11 +2979,13 @@ switch_statement
        : SWITCH OPEN_PARENS 
          { 
                oob_stack.Push (lexer.Location);
+               switch_stack.Push (current_block);
          }
          expression CLOSE_PARENS 
          switch_block
          {
                $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) oob_stack.Pop ());
+               current_block = (Block) switch_stack.Pop ();
          }
        ;
 
@@ -2879,14 +3026,15 @@ switch_sections
 switch_section
        : switch_labels
          {
-               current_block = new Block (current_block);
+               current_block = new Block (current_block, lexer.Location, lexer.Location);
          }
          statement_list 
          {
-               while (current_block.Implicit)
-                       current_block = current_block.Parent;
-               $$ = new SwitchSection ((ArrayList) $1, current_block);
-               current_block = current_block.Parent;
+               Block topmost = current_block;
+
+               while (topmost.Implicit)
+                       topmost = topmost.Parent;
+               $$ = new SwitchSection ((ArrayList) $1, topmost);
          }
        ;
 
@@ -2925,12 +3073,17 @@ iteration_statement
        ;
 
 while_statement
-       : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement
+       : WHILE OPEN_PARENS 
        {
-               $$ = new While ((Expression) $3, (Statement) $5);
+               oob_stack.Push (lexer.Location);
+       }
+       boolean_expression CLOSE_PARENS embedded_statement
+       {
+               Location l = (Location) oob_stack.Pop ();
+               $$ = new While ((Expression) $4, (Statement) $6, l);
        
                if (RootContext.WarningLevel >= 3){
-                       if ($5 is EmptyStatement)
+                       if ($6 is EmptyStatement)
                                Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
                }
        }
@@ -2938,9 +3091,14 @@ while_statement
 
 do_statement
        : DO embedded_statement 
-         WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
+         WHILE OPEN_PARENS {
+               oob_stack.Push (lexer.Location);
+         }
+         boolean_expression CLOSE_PARENS SEMICOLON
          {
-               $$ = new Do ((Statement) $2, (Expression) $5);
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new Do ((Statement) $2, (Expression) $6, l);
          }
        ;
 
@@ -2954,51 +3112,50 @@ for_statement
                if ($3 is DictionaryEntry){
                        DictionaryEntry de = (DictionaryEntry) $3;
                        
-                       string type = (string) de.Key;
+                       Expression type = (Expression) de.Key;
                        ArrayList var_declarators = (ArrayList) de.Value;
 
                        foreach (VariableDeclaration decl in var_declarators){
 
-                               if (!current_block.AddVariable (type, decl.identifier, current_local_parameters,
-                                                               decl.Location)) {
-                                       Report.Error (128, decl.Location, 
-                                                     "A local variable `" + decl.identifier + "' is already" +
-                                                     "defined in this scope");
-                               } else {
+                               VariableInfo vi;
 
-                                       Location l = lexer.Location;
-                                       Expression expr;
-                                       if (decl.expression_or_array_initializer is Expression){
-                                               expr = (Expression) decl.expression_or_array_initializer;
-                                               
-                                       } else {
-                                               
-                                               ArrayList init = (ArrayList) decl.expression_or_array_initializer;
-                                               
-                                               string base_type = type.Substring (0, type.IndexOf ("["));
-                                               string rank = type.Substring (type.IndexOf ("["));
-                                               
-                                               expr = new ArrayCreation (base_type, rank, init, decl.Location);
-                                       }
-                                       
-                                       LocalVariableReference var;
-                                       var = new LocalVariableReference (
-                                                                         assign_block, decl.identifier, l);
+                               vi = current_block.AddVariable (
+                                       type, decl.identifier, current_local_parameters, decl.Location);
+                               if (vi == null)
+                                       continue;
+
+                               Location l = lexer.Location;
+                               Expression expr;
+                               if (decl.expression_or_array_initializer is Expression){
+                                       expr = (Expression) decl.expression_or_array_initializer;
+                               } else if (decl.expression_or_array_initializer == null) {
+                                       expr = null;
+                               } else {
+                                       ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+                                       expr = new ArrayCreation (type, "", init, decl.Location);
+                               }
                                        
+                               LocalVariableReference var;
+                               var = new LocalVariableReference (assign_block, decl.identifier, l);
+
+                               if (expr != null) {
                                        Assign a = new Assign (var, expr, decl.Location);
                                        
-                                       assign_block.AddStatement (new StatementExpression (a));
+                                       assign_block.AddStatement (new StatementExpression (a, lexer.Location));
                                }
                        }
                        
                        $3 = null;
                } 
+               oob_stack.Push (lexer.Location);
          } 
          opt_for_condition SEMICOLON
          opt_for_iterator CLOSE_PARENS 
          embedded_statement
          {
-               For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10);
+               Location l = (Location) oob_stack.Pop ();
+
+               For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l);
 
                if (RootContext.WarningLevel >= 3){
                        if ($10 is EmptyStatement)
@@ -3040,7 +3197,8 @@ for_iterator
 statement_expression_list
        : statement_expression  
          {
-               Block b = new Block (null, true);
+               // CHANGE: was `null'
+               Block b = new Block (current_block, Block.Flags.Implicit);   
 
                b.AddStatement ((Statement) $1);
                $$ = b;
@@ -3061,26 +3219,40 @@ foreach_statement
          }
          expression CLOSE_PARENS 
          {
-               Block foreach_block = new Block (current_block, true);
-               LocalVariableReference v;
+               oob_stack.Push (current_block);
+
+               Block foreach_block = new Block (current_block, Block.Flags.Implicit);
+               LocalVariableReference v = null;
                Location l = lexer.Location;
+               VariableInfo vi;
 
-               foreach_block.AddVariable ((string) $3, (string) $4, current_local_parameters, l);
-               v = new LocalVariableReference (foreach_block, (string) $4, l);
+               vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l);
+               if (vi != null) {
+                       vi.ReadOnly = true;
 
-               current_block.AddStatement (foreach_block);
+                       // Get a writable reference to this read-only variable.
+                       v = new LocalVariableReference (foreach_block, (string) $4, l, vi, false);
+               }
                current_block = foreach_block;
 
-               oob_stack.Push (foreach_block);
                oob_stack.Push (v);
+               oob_stack.Push (current_block);
          } 
          embedded_statement 
          {
-               LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
                Block foreach_block = (Block) oob_stack.Pop ();
+               LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
+               Block prev_block = (Block) oob_stack.Pop ();
                Location l = (Location) oob_stack.Pop ();
 
-               $$ = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
+               current_block = prev_block;
+
+               if (v != null) {
+                       Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l);
+                       foreach_block.AddStatement (f);
+               }
+
+               $$ = foreach_block;
          }
        ;
 
@@ -3090,6 +3262,7 @@ jump_statement
        | goto_statement
        | return_statement
        | throw_statement
+       | yield_statement
        ;
 
 break_statement
@@ -3135,6 +3308,29 @@ throw_statement
          }
        ;
 
+yield_statement 
+       : YIELD expression SEMICOLON
+         {
+               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 BREAK SEMICOLON
+         {
+               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);
+               }
+         }
+       ;
+
 opt_expression
        : /* empty */
        | expression
@@ -3147,7 +3343,7 @@ try_statement
                ArrayList s = new ArrayList ();
                
                foreach (Catch cc in (ArrayList) $3) {
-                       if (cc.Type == null)
+                       if (cc.IsGeneral)
                                g = cc;
                        else
                                s.Add (cc);
@@ -3156,21 +3352,24 @@ try_statement
                // Now s contains the list of specific catch clauses
                // and g contains the general one.
                
-               $$ = new Try ((Block) $2, s, g, null);
+               $$ = new Try ((Block) $2, s, g, null, lexer.Location);
        }
        | TRY block opt_catch_clauses FINALLY block
          {
                Catch g = null;
                ArrayList s = new ArrayList ();
-               
-               foreach (Catch cc in (ArrayList) $3) {
-                       if (cc.Type == null)
-                               g = cc;
-                       else
-                               s.Add (cc);
+               ArrayList catch_list = (ArrayList) $3;
+
+               if (catch_list != null){
+                       foreach (Catch cc in catch_list) {
+                               if (cc.IsGeneral)
+                                       g = cc;
+                               else
+                                       s.Add (cc);
+                       }
                }
 
-               $$ = new Try ((Block) $2, s, g, (Block) $5);
+               $$ = new Try ((Block) $2, s, g, (Block) $5, lexer.Location);
          }
        | TRY block error 
          {
@@ -3208,11 +3407,12 @@ opt_identifier
 catch_clause 
        : CATCH opt_catch_args 
        {
-               string type = null, id = null;
+               Expression type = null;
+               string id = null;
                
                if ($2 != null) {
                        DictionaryEntry cc = (DictionaryEntry) $2;
-                       type = (string) cc.Key;
+                       type = (Expression) cc.Key;
                        id   = (string) cc.Value;
 
                        if (id != null){
@@ -3225,19 +3425,21 @@ catch_clause
                                current_block = new Block (current_block);
                                Block b = declare_local_variables (type, one, loc);
                                current_block = b;
-
-                               
                        }
                }
        } block {
-               string type = null, id = null;
+               Expression type = null;
+               string id = null;
 
                if ($2 != null){
                        DictionaryEntry cc = (DictionaryEntry) $2;
-                       type = (string) cc.Key;
+                       type = (Expression) cc.Key;
                        id   = (string) cc.Value;
 
                        if ($1 != null){
+                               //
+                               // FIXME: I can change this for an assignment.
+                               //
                                while (current_block != (Block) $1)
                                        current_block = current_block.Parent;
                        }
@@ -3288,25 +3490,62 @@ unsafe_statement
 
 fixed_statement
        : FIXED OPEN_PARENS 
-         // FIXME: pointer_type fixed_pointer_declarators 
-         CLOSE_PARENS embedded_statement
+         type fixed_pointer_declarators 
+         CLOSE_PARENS 
          {
-               // $$ = new Fixed ((string) $3, $4, (Statement) $6, lexer.Location);
+               Block assign_block = new Block (current_block, Block.Flags.Implicit);
+               ArrayList list = (ArrayList) $4;
+               Expression type = (Expression) $3;
+               Location l = lexer.Location;
+               int top = list.Count;
+
+               for (int i = 0; i < top; i++){
+                       Pair p = (Pair) list [i];
+                       VariableInfo v;
+
+                       v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
+                       if (v == null)
+                               continue;
+                       v.ReadOnly = true;
+                       p.First = v;
+                       list [i] = p;
+               }
+               current_block.AddStatement (assign_block);
+               current_block = assign_block;
+               oob_stack.Push (assign_block);
+               oob_stack.Push (l);
+         }
+         embedded_statement 
+         {
+               Location l = (Location) oob_stack.Pop ();
+               Block assign_block = (Block) oob_stack.Pop ();
+
+               ArrayList list = (ArrayList) $4;
+               int top = list.Count;
+
+               $$ = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
          }
        ;
 
 fixed_pointer_declarators
-       : fixed_pointer_declarator
+       : fixed_pointer_declarator      { 
+               ArrayList declarators = new ArrayList (); 
+               declarators.Add ($1);
+               $$ = declarators;
+         }
        | fixed_pointer_declarators COMMA fixed_pointer_declarator
+         {
+               ArrayList declarators = (ArrayList) $1;
+               declarators.Add ($3);
+               $$ = declarators;
+         }
        ;
 
 fixed_pointer_declarator
-       : IDENTIFIER EQUALS fixed_pointer_initializer
-       ;
-
-fixed_pointer_initializer
-       : BITWISE_AND variable_reference
-       | expression
+       : IDENTIFIER ASSIGN expression
+         {     
+               $$ = new Pair ($1, $3);
+         }
        ;
 
 lock_statement
@@ -3332,42 +3571,33 @@ using_statement
                        DictionaryEntry de = (DictionaryEntry) $3;
                        Location l = lexer.Location;
 
-                       string type = (string) de.Key;
+                       Expression type = (Expression) de.Key;
                        ArrayList var_declarators = (ArrayList) de.Value;
 
-                       foreach (VariableDeclaration decl in var_declarators){
-                               if (!current_block.AddVariable (type, decl.identifier, current_local_parameters,
-                                                               decl.Location)){
-                                       Report.Error (128, decl.Location, 
-                                       "A local variable `" + decl.identifier + "' is already" +
-                                       "defined in this scope");
-                               }
-                       }
-
                        ArrayList vars = new ArrayList ();
 
                        foreach (VariableDeclaration decl in var_declarators){
 
+                               VariableInfo vi = current_block.AddVariable (
+                                       type, decl.identifier, 
+                                       current_local_parameters, decl.Location);
+                               if (vi == null)
+                                       continue;
+                               vi.ReadOnly = true;
+
                                Expression expr;
                                if (decl.expression_or_array_initializer is Expression){
                                        expr = (Expression) decl.expression_or_array_initializer;
-                                       
                                } else {
-
                                        ArrayList init = (ArrayList) decl.expression_or_array_initializer;
                                        
-                                       string base_type = type.Substring (0, type.IndexOf ("["));
-                                       string rank = type.Substring (type.IndexOf ("["));
-                                       
-                                       expr = new ArrayCreation (base_type, rank, init, decl.Location);
+                                       expr = new ArrayCreation (type, "", init, decl.Location);
                                }
 
                                LocalVariableReference var;
-                               VariableInfo vi;
 
-                               var = new LocalVariableReference (assign_block, decl.identifier, l);
-                               vi = var.VariableInfo;
-                               vi.ReadOnly = true;
+                               // Get a writable reference to this read-only variable.
+                               var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
 
                                // This is so that it is not a warning on using variables
                                vi.Used = true;
@@ -3375,7 +3605,7 @@ using_statement
                                vars.Add (new DictionaryEntry (var, expr));                             
 
                                // Assign a = new Assign (var, expr, decl.Location);
-                               // assign_block.AddStatement (new StatementExpression (a));
+                               // assign_block.AddStatement (new StatementExpression (a, lexer.Location));
                        }
                        $3 = new DictionaryEntry (type, vars);
                 }
@@ -3405,11 +3635,18 @@ public class VariableDeclaration {
        public string identifier;
        public object expression_or_array_initializer;
        public Location Location;
+       public Attributes OptAttributes;
 
-       public VariableDeclaration (string id, object eoai, Location l){
+       public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs)
+       {
                this.identifier = id;
                this.expression_or_array_initializer = eoai;
                this.Location = l;
+               this.OptAttributes = opt_attrs;
+       }
+
+       public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
+       {
        }
 }
 
@@ -3418,11 +3655,11 @@ public class VariableDeclaration {
 // </summary>
 
 public class IndexerDeclaration {
-       public string type;
+       public Expression type;
        public string interface_type;
        public Parameters param_list;
 
-       public IndexerDeclaration (string type, string interface_type, Parameters param_list)
+       public IndexerDeclaration (Expression type, string interface_type, Parameters param_list)
        {
                this.type = type;
                this.interface_type = interface_type;
@@ -3436,15 +3673,13 @@ public class IndexerDeclaration {
 
 public class OperatorDeclaration {
        public Operator.OpType optype;
-       public string ret_type;
-       public string arg1type;
-       public string arg1name;
-       public string arg2type;
-       public string arg2name;
+       public Expression ret_type, arg1type, arg2type;
+       public string arg1name, arg2name;
        public Location location;
 
-       public OperatorDeclaration (Operator.OpType op, string ret_type, string arg1type, string arg1name,
-                                   string arg2type, string arg2name, Location location)
+       public OperatorDeclaration (Operator.OpType op, Expression ret_type, 
+                                   Expression arg1type, string arg1name,
+                                   Expression arg2type, string arg2name, Location location)
        {
                optype = op;
                this.ret_type = ret_type;
@@ -3457,6 +3692,15 @@ public class OperatorDeclaration {
 
 }
 
+void Error_ExpectingTypeName (Location l, Expression expr)
+{
+       if (expr is Invocation){
+               Report.Error (1002, l, "; expected");
+       } else {
+               Report.Error (-1, l, "Invalid Type definition");
+       }
+}
+
 // <summary>
 //   Given the @class_name name, it creates a fully qualified name
 //   based on the containing declaration space
@@ -3481,16 +3725,14 @@ MakeName (string class_name)
 //   in the current declaration space
 // </summary>
 void 
-CheckDef (AdditionResult result, string name)
+CheckDef (AdditionResult result, string name, Location l)
 {
        if (result == AdditionResult.Success)
                return;
 
-       Location l = lexer.Location;
-       
        switch (result){
        case AdditionResult.NameExists:
-               Report.Error (102, l, "The namespace `" + current_container.Name + 
+               Report.Error (102, l, "The container `" + current_container.Name + 
                                 "' already contains a definition for `"+
                                 name + "'");
                break;
@@ -3518,34 +3760,11 @@ CheckDef (AdditionResult result, string name)
 }
 
 void 
-CheckDef (bool result, string name)
+CheckDef (bool result, string name, Location l)
 {
        if (result)
                return;
-       CheckDef (AdditionResult.NameExists, name);
-}
-
-Expression
-SimpleLookup (string name, Location loc)
-{
-       //
-       // we need to check against current_block not being null
-       // as `expression' is allowed in argument_lists, which 
-       // do not exist inside a block.  
-       //
-       if (current_block != null){
-               if (current_block.IsVariableDefined (name))
-                       return new LocalVariableReference (current_block, name, loc);
-       }
-
-       if (current_local_parameters != null){
-               int idx;
-               Parameter par = current_local_parameters.GetParameterByName (name, out idx);
-               if (par != null)
-                       return new ParameterReference (current_local_parameters, idx, name);
-       }
-
-       return null;
+       CheckDef (AdditionResult.NameExists, name, l);
 }
 
 Expression DecomposeQI (string name, Location loc)
@@ -3553,16 +3772,14 @@ Expression DecomposeQI (string name, Location loc)
        Expression o;
 
        if (name.IndexOf ('.') == -1){
-               o = SimpleLookup (name, loc);
-               if (o == null)
-                       return new SimpleName (name, loc);
-               return o;
+               return new SimpleName (name, loc);
        } else {
                int pos = name.LastIndexOf (".");
                string left = name.Substring (0, pos);
                string right = name.Substring (pos + 1);
 
                o = DecomposeQI (left, loc);
+
                return new MemberAccess (o, right, loc);
        }
 }
@@ -3573,6 +3790,7 @@ Expression DecomposeQI (string name, Location loc)
 //  This is necessary because local_variable_type admits primary_expression
 //  as the type of the variable. So we do some extra checking
 // </summary>
+#if false
 string GetQualifiedIdentifier (Expression expr)
 {
        if (expr is SimpleName)
@@ -3583,8 +3801,9 @@ string GetQualifiedIdentifier (Expression expr)
                throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
        
 }
+#endif
 
-Block declare_local_variables (string type, ArrayList variable_declarators, Location loc)
+Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
 {
        Block implicit_block;
        ArrayList inits = null;
@@ -3604,22 +3823,20 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca
        //
        // int j = 1;  int k = j + 1;
        //
-       if (current_block.Used)
-               implicit_block = new Block (current_block, true);
-       else
+       if (current_block.Used) {
+               implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
+               implicit_block.AddChildVariableNames (current_block);
+       } else
                implicit_block = current_block;
 
        foreach (VariableDeclaration decl in variable_declarators){
 
-               if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location)) {
+               if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
                        if (decl.expression_or_array_initializer != null){
                                if (inits == null)
                                        inits = new ArrayList ();
                                inits.Add (decl);
                        }
-               } else {
-                       Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
-                                        "' is already defined in this scope");
                }
        }
 
@@ -3636,11 +3853,7 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca
                } else {
                        ArrayList init = (ArrayList) decl.expression_or_array_initializer;
                        
-                       string base_type = type.Substring (0, type.IndexOf ("["));
-                       string rank = type.Substring (type.IndexOf ("["));
-
-                       expr = new ArrayCreation (base_type, rank, init, decl.Location);
-                       
+                       expr = new ArrayCreation (type, "", init, decl.Location);
                }
 
                LocalVariableReference var;
@@ -3648,25 +3861,23 @@ Block declare_local_variables (string type, ArrayList variable_declarators, Loca
 
                assign = new Assign (var, expr, decl.Location);
 
-               implicit_block.AddStatement (new StatementExpression (assign));
+               implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
        }
        
        return implicit_block;
 }
 
-Block declare_local_constant (string type, VariableDeclaration decl)
+Block declare_local_constant (Expression type, VariableDeclaration decl)
 {
        Block implicit_block;
 
        if (current_block.Used)
-               implicit_block = new Block (current_block, true);
+               implicit_block = new Block (current_block, Block.Flags.Implicit);
        else
                implicit_block = current_block;
 
        if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
                                          current_local_parameters, decl.Location))){
-               Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
-                             "' is already defined in this scope");
        }
        
        return implicit_block;
@@ -3681,7 +3892,7 @@ void CheckAttributeTarget (string a)
                
        default :
                Location l = lexer.Location;
-               Report.Error (658, l, "Invalid attribute target");
+               Report.Error (658, l, "`" + a + "' is an invalid attribute target");
                break;
        }
 
@@ -3763,42 +3974,35 @@ public Tokenizer Lexer {
        }
 }                 
 
-public CSharpParser (string name, System.IO.Stream input, ArrayList defines)
+public CSharpParser (StreamReader reader, SourceFile file, ArrayList defines)
 {
-       current_namespace = new Namespace (null, "");
-       this.name = name;
-       this.input = input;
+       current_namespace = new Namespace (null, file, "");
+       this.name = file.Name;
+       this.file = file;
        current_container = RootContext.Tree.Types;
        current_container.Namespace = current_namespace;
        oob_stack = new Stack ();
+       switch_stack = new Stack ();
 
-       lexer = new Tokenizer (input, name, defines);
+       lexer = new Tokenizer (reader, file, defines);
 }
 
-public override int parse ()
+public override void parse ()
 {
-       StringBuilder value = new StringBuilder ();
-
-       global_errors = 0;
        try {
                if (yacc_verbose_flag)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
                else
                        yyparse (lexer);
+               Tokenizer tokenizer = lexer as Tokenizer;
+               tokenizer.cleanup ();           
        } catch (Exception e){
-               // Console.WriteLine ("Fatal error: " + name);
-               // Console.WriteLine (lexer.location);
-
-               // 
                // Please do not remove this, it is used during debugging
                // of the grammar
                //
-               Console.WriteLine (lexer.location + "  : Parsing error ");
+               Report.Error (-25, lexer.Location, ": Parsing error ");
                Console.WriteLine (e);
-               global_errors++;
        }
-       
-       return global_errors;
 }
 
 /* end end end */