2003-04-28 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / cs-parser.jay
index a5c4cd0cf3bcbeb4173650c27c4ca0da87c3b208..005def9fa45a8608bce2ffa6a55904997d37358b 100755 (executable)
 //       great spot to put an `error' because you can reproduce it with this input:
 //      "public X { }"
 //
+// 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
@@ -30,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.  
@@ -68,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
@@ -159,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,6 +268,7 @@ compilation_unit
         : outer_declarations opt_EOF
         | outer_declarations attribute_sections opt_EOF
         | attribute_sections opt_EOF
+       | opt_EOF /* allow empty files */
         ;
        
 opt_EOF
@@ -304,11 +324,14 @@ namespace_declaration
                if (attrs != null) {
                        foreach (AttributeSection asec in attrs.AttributeSections)
                                if (asec.Target == "assembly")
-                                       RootContext.AddGlobalAttribute (
-                                               current_container, asec, lexer.Location);
+                                       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, name, (string) $3);
+               current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3);
        } 
          namespace_body opt_semicolon
          { 
@@ -386,7 +409,9 @@ namespace_member_declaration
                }
                current_namespace.DeclarationFound = true;
          }
-       | namespace_declaration
+       | namespace_declaration {
+               current_namespace.DeclarationFound = true;
+         }
        ;
 
 type_declaration
@@ -417,10 +442,11 @@ attribute_sections
           {
                AttributeSection sect = (AttributeSection) $1;
 
-               if (sect.Target == "assembly")
-                       RootContext.AddGlobalAttribute (current_container, sect, lexer.Location);
-                 
-               $$ = new Attributes ((AttributeSection) $1, lexer.Location);
+               if (sect.Target == "assembly") 
+                       RootContext.AddGlobalAttributeSection (current_container, sect);
+               
+
+               $$ = new Attributes ((AttributeSection) $1);
           }
        | attribute_sections attribute_section
          {
@@ -428,11 +454,11 @@ attribute_sections
                AttributeSection sect = (AttributeSection) $2;
 
                if (sect.Target == "assembly")
-                       RootContext.AddGlobalAttribute (current_container, sect, lexer.Location);
+                       RootContext.AddGlobalAttributeSection (current_container, sect);
 
                if ($1 != null) {
                        attrs = (Attributes) $1;
-                       attrs.AddAttribute (sect);
+                       attrs.AddAttributeSection (sect);
                }
                
                $$ = attrs;
@@ -440,7 +466,7 @@ attribute_sections
        ;
 
 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;
                
@@ -449,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);
          }
@@ -790,11 +816,13 @@ variable_initializer
        ;
 
 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){
@@ -811,10 +839,11 @@ method_declaration
                        }
                }
 
-               method.Block = (Block) $2;
+               method.Block = (Block) $3;
                CheckDef (current_container.AddMethod (method), method.Name, method.Location);
 
                current_local_parameters = null;
+               iterator_container = null;
          }
        ;
 
@@ -871,7 +900,7 @@ method_body
        ;
 
 opt_formal_parameter_list
-       : /* empty */                   { $$ = Parameters.GetEmptyReadOnlyParameters (); }
+       : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
        | formal_parameter_list
        ;
 
@@ -933,8 +962,8 @@ 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
@@ -1372,29 +1401,39 @@ constructor_declaration
          { 
                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) {
-                               Report.Error (
-                                       515, c.Location, 
-                                       "Access modifiers are not allowed on static constructors");
-                       }
-
-                       if (c.Initializer != null){
-                               Report.Error (
-                                       514, c.Location, 
-                                       "Static constructors can not have an explicit this or base " +
-                                       "constructor invocations");
+               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.Parameters.Empty){
-                               Report.Error (
-                                       132, c.Location, "Static constructors should not have parameters");
-                       }
-               } 
-               
                CheckDef (current_container.AddConstructor (c), c.Name, c.Location);
 
                current_local_parameters = null;
@@ -1429,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);
          }
        ;
 
@@ -1541,6 +1580,10 @@ add_accessor_declaration
                $$ = 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
@@ -1561,6 +1604,10 @@ remove_accessor_declaration
                $$ = 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
@@ -1808,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
@@ -1959,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);
          }
@@ -2019,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);
          }
        ;
 
@@ -2051,7 +2108,7 @@ expression_list
 this_access
        : THIS
          {
-               $$ = new This (lexer.Location);
+               $$ = new This (current_block, lexer.Location);
          }
        ;
 
@@ -2123,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
@@ -2216,14 +2269,14 @@ sizeof_expression
 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);
          }
        ;
 
@@ -2246,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);
          }
@@ -2639,7 +2696,8 @@ class_base
 block
        : OPEN_BRACE 
          {
-               current_block = new Block (current_block, lexer.Location, Location.Null);
+               current_block = new Block (current_block, current_local_parameters,
+                                          lexer.Location, Location.Null);
          } 
          opt_statement_list CLOSE_BRACE 
          { 
@@ -2664,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;
                }
@@ -2705,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;
@@ -2719,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 ((Expression) 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 ((Expression) de.Key, (VariableDeclaration) de.Value);
+                       $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
+               }
          }
        ;
 
@@ -2758,20 +2820,20 @@ 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");
-                       $$ = TypeManager.system_object_expr;
+               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
-               // 
-               if ((string) $2 == "")
-                       $$ = $1;
-               else
-                       $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
          }
        | builtin_types opt_rank_specifier
          {
@@ -2786,13 +2848,14 @@ 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";
-               }
-               
-               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+               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
          {
@@ -2811,24 +2874,33 @@ local_variable_pointer_type
 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
        {
-               Expression t;
+               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);
+                       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;
          }
        ;
 
@@ -2907,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 ();
          }
        ;
 
@@ -2952,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);
          }
        ;
 
@@ -3016,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, lexer.Location);
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new Do ((Statement) $2, (Expression) $6, l);
          }
        ;
 
@@ -3041,25 +3121,24 @@ for_statement
 
                                vi = current_block.AddVariable (
                                        type, decl.identifier, current_local_parameters, decl.Location);
-                               if (vi == null){
-                                       Report.Error (128, decl.Location, 
-                                                     "A local variable `" + decl.identifier + 
-                                                     "' is already defined in this scope");
+                               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 {
-                                       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;
-                                               expr = new ArrayCreation (type, "", init, decl.Location);
-                                       }
-                                       
-                                       LocalVariableReference var;
-                                       var = new LocalVariableReference (
-                                                                         assign_block, decl.identifier, l);
+                                       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, lexer.Location));
@@ -3119,7 +3198,7 @@ statement_expression_list
        : statement_expression  
          {
                // CHANGE: was `null'
-               Block b = new Block (current_block, true);   
+               Block b = new Block (current_block, Block.Flags.Implicit);   
 
                b.AddStatement ((Statement) $1);
                $$ = b;
@@ -3142,20 +3221,18 @@ foreach_statement
          {
                oob_stack.Push (current_block);
 
-               Block foreach_block = new Block (current_block, true);
-               LocalVariableReference v;
+               Block foreach_block = new Block (current_block, Block.Flags.Implicit);
+               LocalVariableReference v = null;
                Location l = lexer.Location;
                VariableInfo vi;
 
                vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l);
-               vi.ReadOnly = true;
-               if (vi == null){
-                       Report.Error (
-                               128, l, "A local variable `" + (string) $4 + "' is already "+
-                               "defined in this scope");
-               }
+               if (vi != null) {
+                       vi.ReadOnly = true;
 
-               v = new LocalVariableReference (foreach_block, (string) $4, l);
+                       // 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 (v);
@@ -3170,8 +3247,10 @@ foreach_statement
 
                current_block = prev_block;
 
-               Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l);
-               foreach_block.AddStatement (f);
+               if (v != null) {
+                       Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l);
+                       foreach_block.AddStatement (f);
+               }
 
                $$ = foreach_block;
          }
@@ -3183,6 +3262,7 @@ jump_statement
        | goto_statement
        | return_statement
        | throw_statement
+       | yield_statement
        ;
 
 break_statement
@@ -3228,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
@@ -3240,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);
@@ -3249,7 +3352,7 @@ 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
          {
@@ -3259,14 +3362,14 @@ try_statement
 
                if (catch_list != null){
                        foreach (Catch cc in catch_list) {
-                               if (cc.Type == null)
+                               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 
          {
@@ -3387,10 +3490,10 @@ unsafe_statement
 
 fixed_statement
        : FIXED OPEN_PARENS 
-         pointer_type fixed_pointer_declarators 
+         type fixed_pointer_declarators 
          CLOSE_PARENS 
          {
-               Block assign_block = new Block (current_block, true);
+               Block assign_block = new Block (current_block, Block.Flags.Implicit);
                ArrayList list = (ArrayList) $4;
                Expression type = (Expression) $3;
                Location l = lexer.Location;
@@ -3401,11 +3504,8 @@ fixed_statement
                        VariableInfo v;
 
                        v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
-                       if (v == null){
-                               Report.Error (
-                                       128, l, "A local variable `" + (string) p.First + "' is already "+
-                                       "defined in this scope");
-                       }
+                       if (v == null)
+                               continue;
                        v.ReadOnly = true;
                        p.First = v;
                        list [i] = p;
@@ -3474,20 +3574,17 @@ using_statement
                        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) == null){
-                                       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;
@@ -3498,11 +3595,9 @@ using_statement
                                }
 
                                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;
@@ -3597,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
@@ -3663,45 +3767,19 @@ CheckDef (bool result, string name, Location l)
        CheckDef (AdditionResult.NameExists, name, l);
 }
 
-//
-// This routine should be removed soon.  I am in the process of making
-// changes to never keep anything but SimpleNames during parsing, as
-// that breaks some kinds of code (documented in the ChangeLog).
-//
-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_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;
-}
-
 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);
        }
 }
@@ -3712,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)
@@ -3722,6 +3801,7 @@ string GetQualifiedIdentifier (Expression expr)
                throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
        
 }
+#endif
 
 Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
 {
@@ -3743,9 +3823,10 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators,
        //
        // int j = 1;  int k = j + 1;
        //
-       if (current_block.Used)
-               implicit_block = new Block (current_block, true, loc, Location.Null);
-       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){
@@ -3756,9 +3837,6 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators,
                                        inits = new ArrayList ();
                                inits.Add (decl);
                        }
-               } else {
-                       Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
-                                        "' is already defined in this scope");
                }
        }
 
@@ -3794,14 +3872,12 @@ 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;
@@ -3898,16 +3974,17 @@ 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 void parse ()
@@ -3917,11 +3994,13 @@ public override void parse ()
                        yyparse (lexer, new yydebug.yyDebugSimple ());
                else
                        yyparse (lexer);
+               Tokenizer tokenizer = lexer as Tokenizer;
+               tokenizer.cleanup ();           
        } catch (Exception e){
                // 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);
        }
 }