84a2f5b3d13c87047b4a607a157af2ae11ea53b6
[mono.git] / mcs / mcs / cs-parser.jay
1 %{
2 //
3 // cs-parser.jay: The Parser for the C# compiler
4 //
5 // Authors: Miguel de Icaza (miguel@gnu.org)
6 //          Ravi Pratap     (ravi@ximian.com)
7 //          Marek Safar         (marek.safar@gmail.com)
8 //
9 // Licensed under the terms of the GNU GPL
10 //
11 // (C) 2001 Ximian, Inc (http://www.ximian.com)
12 // (C) 2004 Novell, Inc
13 //
14 // TODO:
15 //   (1) Figure out why error productions dont work.  `type-declaration' is a
16 //       great spot to put an `error' because you can reproduce it with this input:
17 //       "public X { }"
18 //
19 // Possible optimization:
20 //   Run memory profiler with parsing only, and consider dropping 
21 //   arraylists where not needed.   Some pieces can use linked lists.
22
23
24 using System.Text;
25 using System.IO;
26 using System;
27
28 namespace Mono.CSharp
29 {
30         using System.Collections;
31
32         /// <summary>
33         ///    The C# Parser
34         /// </summary>
35         public class CSharpParser {
36                 NamespaceEntry  current_namespace;
37                 TypeContainer   current_container;
38                 DeclSpace       current_class;
39         
40                 /// <summary>
41                 ///   Current block is used to add statements as we find
42                 ///   them.  
43                 /// </summary>
44                 Block      current_block;
45
46                 Delegate   current_delegate;
47                 
48                 GenericMethod current_generic_method;
49                 AnonymousMethodExpression current_anonymous_method;
50
51                 /// <summary>
52                 ///   This is used by the unary_expression code to resolve
53                 ///   a name against a parameter.  
54                 /// </summary>
55                 
56                 // FIXME: This is very ugly and it's very hard to reset it correctly
57                 // on all places, especially when some parameters are autogenerated.
58                 Parameters current_local_parameters;
59
60                 /// <summary>
61                 ///   Using during property parsing to describe the implicit
62                 ///   value parameter that is passed to the "set" and "get"accesor
63                 ///   methods (properties and indexers).
64                 /// </summary>
65                 FullNamedExpression implicit_value_parameter_type;
66                 Parameters indexer_parameters;
67
68                 /// <summary>
69                 ///   Hack to help create non-typed array initializer
70                 /// </summary>
71                 public static FullNamedExpression current_array_type;
72                 FullNamedExpression pushed_current_array_type;
73
74                 /// <summary>
75                 ///   Used to determine if we are parsing the get/set pair
76                 ///   of an indexer or a property
77                 /// </summmary>
78                 bool parsing_indexer;
79
80                 bool parsing_anonymous_method;
81
82                 ///
83                 /// An out-of-band stack.
84                 ///
85                 static Stack oob_stack;
86
87                 ///
88                 /// Switch stack.
89                 ///
90                 Stack switch_stack;
91
92                 ///
93                 /// Controls the verbosity of the errors produced by the parser
94                 ///
95                 static public int yacc_verbose_flag;
96
97                 /// 
98                 /// Used by the interactive shell, flags whether EOF was reached
99                 /// and an error was produced
100                 ///
101                 public bool UnexpectedEOF;
102
103                 ///
104                 /// The current file.
105                 ///
106                 CompilationUnit file;
107
108                 ///
109                 /// Temporary Xml documentation cache.
110                 /// For enum types, we need one more temporary store.
111                 ///
112                 string tmpComment;
113                 string enumTypeComment;
114                         
115                 /// Current attribute target
116                 string current_attr_target;
117                 
118                 /// assembly and module attribute definitions are enabled
119                 bool global_attrs_enabled = true;
120                 bool has_get, has_set;
121                 bool parameter_modifiers_not_allowed;
122                 bool params_modifiers_not_allowed;
123                 bool arglist_allowed;
124
125
126                 /// When using the interactive parser, this holds the
127                 /// resulting expression
128                 public object InteractiveResult;
129
130                 //
131                 // Keeps track of global data changes to undo on parser error
132                 //
133                 public Undo undo;
134
135                 // A counter to create new class names in interactive mode
136                 static int class_count;
137 %}
138
139 %token EOF
140 %token NONE   /* This token is never returned by our lexer */
141 %token ERROR            // This is used not by the parser, but by the tokenizer.
142                         // do not remove.
143
144 /*
145  *These are the C# keywords
146  */
147 %token FIRST_KEYWORD
148 %token ABSTRACT 
149 %token AS
150 %token ADD
151 %token ASSEMBLY
152 %token BASE     
153 %token BOOL     
154 %token BREAK    
155 %token BYTE     
156 %token CASE     
157 %token CATCH    
158 %token CHAR     
159 %token CHECKED  
160 %token CLASS    
161 %token CONST    
162 %token CONTINUE 
163 %token DECIMAL  
164 %token DEFAULT  
165 %token DELEGATE 
166 %token DO       
167 %token DOUBLE   
168 %token ELSE     
169 %token ENUM     
170 %token EVENT    
171 %token EXPLICIT 
172 %token EXTERN   
173 %token FALSE    
174 %token FINALLY  
175 %token FIXED    
176 %token FLOAT    
177 %token FOR      
178 %token FOREACH  
179 %token GOTO     
180 %token IF       
181 %token IMPLICIT 
182 %token IN       
183 %token INT      
184 %token INTERFACE
185 %token INTERNAL 
186 %token IS       
187 %token LOCK     
188 %token LONG     
189 %token NAMESPACE
190 %token NEW      
191 %token NULL     
192 %token OBJECT   
193 %token OPERATOR 
194 %token OUT      
195 %token OVERRIDE 
196 %token PARAMS   
197 %token PRIVATE  
198 %token PROTECTED
199 %token PUBLIC   
200 %token READONLY 
201 %token REF      
202 %token RETURN   
203 %token REMOVE
204 %token SBYTE    
205 %token SEALED   
206 %token SHORT    
207 %token SIZEOF   
208 %token STACKALLOC
209 %token STATIC   
210 %token STRING   
211 %token STRUCT   
212 %token SWITCH   
213 %token THIS     
214 %token THROW    
215 %token TRUE     
216 %token TRY      
217 %token TYPEOF   
218 %token UINT     
219 %token ULONG    
220 %token UNCHECKED
221 %token UNSAFE   
222 %token USHORT   
223 %token USING    
224 %token VIRTUAL  
225 %token VOID     
226 %token VOLATILE
227 %token WHERE
228 %token WHILE    
229 %token ARGLIST
230 %token PARTIAL
231 %token ARROW
232 %token QUERY_FIRST_TOKEN
233 %token FROM
234 %token JOIN
235 %token ON
236 %token EQUALS
237 %token SELECT
238 %token GROUP
239 %token BY
240 %token LET
241 %token ORDERBY
242 %token ASCENDING
243 %token DESCENDING
244 %token INTO
245 %token QUERY_LAST_TOKEN
246
247 /* C# keywords which are not really keywords */
248 %token GET           "get"
249 %token SET           "set"
250
251 %left LAST_KEYWORD
252
253 /* C# single character operators/punctuation. */
254 %token OPEN_BRACE    "{"
255 %token CLOSE_BRACE   "}"
256 %token OPEN_BRACKET  "["
257 %token CLOSE_BRACKET "]"
258 %token OPEN_PARENS   "("
259 %token CLOSE_PARENS  ")"
260 %token DOT           "."
261 %token COMMA         ","
262 %token COLON         ":"
263 %token SEMICOLON     ";"
264 %token TILDE         "~"
265
266 %token PLUS           "+"
267 %token MINUS          "-"
268 %token BANG           "!"
269 %token ASSIGN         "="
270 %token OP_LT          "<"
271 %token OP_GENERICS_LT "<"
272 %token OP_GT          ">"
273 %token OP_GENERICS_GT ">"
274 %token BITWISE_AND    "&"
275 %token BITWISE_OR     "|"
276 %token STAR           "*"
277 %token PERCENT        "%"
278 %token DIV            "/"
279 %token CARRET         "^"
280 %token INTERR         "?"
281
282 /* C# multi-character operators. */
283 %token DOUBLE_COLON           "::"
284 %token OP_INC                 "++"
285 %token OP_DEC                 "--"
286 %token OP_SHIFT_LEFT          "<<"
287 %token OP_SHIFT_RIGHT         ">>"
288 %token OP_LE                  "<="
289 %token OP_GE                  ">="
290 %token OP_EQ                  "=="
291 %token OP_NE                  "!="
292 %token OP_AND                 "&&"
293 %token OP_OR                  "||"
294 %token OP_MULT_ASSIGN         "*="
295 %token OP_DIV_ASSIGN          "/="
296 %token OP_MOD_ASSIGN          "%="
297 %token OP_ADD_ASSIGN          "+="
298 %token OP_SUB_ASSIGN          "-="
299 %token OP_SHIFT_LEFT_ASSIGN   "<<="
300 %token OP_SHIFT_RIGHT_ASSIGN  ">>="
301 %token OP_AND_ASSIGN          "&="
302 %token OP_XOR_ASSIGN          "^="
303 %token OP_OR_ASSIGN           "|="
304 %token OP_PTR                 "->"
305 %token OP_COALESCING          "??"
306
307 /* Numbers */
308 %token LITERAL_INTEGER           "int literal"
309 %token LITERAL_FLOAT             "float literal"
310 %token LITERAL_DOUBLE            "double literal"
311 %token LITERAL_DECIMAL           "decimal literal"
312 %token LITERAL_CHARACTER         "character literal"
313 %token LITERAL_STRING            "string literal"
314
315 %token IDENTIFIER
316 %token OPEN_PARENS_LAMBDA
317 %token CLOSE_PARENS_CAST
318 %token CLOSE_PARENS_NO_CAST
319 %token CLOSE_PARENS_OPEN_PARENS
320 %token CLOSE_PARENS_MINUS
321 %token DEFAULT_OPEN_PARENS
322 %token GENERIC_DIMENSION
323 %token DEFAULT_COLON
324
325 // Make the parser go into eval mode parsing (statements and compilation units).
326 %token EVAL_STATEMENT_PARSER
327 %token EVAL_COMPILATION_UNIT_PARSER
328 %token EVAL_USING_DECLARATIONS_UNIT_PARSER
329
330 /* Add precedence rules to solve dangling else s/r conflict */
331 %nonassoc LOWPREC
332 %nonassoc IF
333 %nonassoc ELSE
334 %right ASSIGN
335 %left OP_OR
336 %left OP_AND
337 %left BITWISE_OR
338 %left BITWISE_AND
339 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
340 %left PLUS MINUS
341 %left STAR DIV PERCENT
342 %right BANG CARRET UMINUS
343 %nonassoc OP_INC OP_DEC
344 %left OPEN_PARENS
345 %left OPEN_BRACKET OPEN_BRACE
346 %left DOT
347 %nonassoc HIGHPREC
348
349 %start compilation_unit
350 %%
351
352 compilation_unit
353         : outer_declarations opt_EOF
354         | outer_declarations global_attributes opt_EOF
355         | global_attributes opt_EOF
356         | opt_EOF /* allow empty files */
357         | interactive_parsing opt_EOF
358         ;
359
360 opt_EOF
361         : /* empty */
362           {
363                 Lexer.check_incorrect_doc_comment ();
364           }
365         | EOF
366           {
367                 Lexer.check_incorrect_doc_comment ();
368           }
369         ;
370
371 outer_declarations
372         : outer_declaration
373         | outer_declarations outer_declaration
374         ;
375  
376 outer_declaration
377         : extern_alias_directive
378         | using_directive 
379         | namespace_member_declaration
380         ;
381
382 extern_alias_directives
383         : extern_alias_directive
384         | extern_alias_directives extern_alias_directive;
385
386 extern_alias_directive
387         : EXTERN IDENTIFIER IDENTIFIER SEMICOLON
388           {
389                 LocatedToken lt = (LocatedToken) $2;
390                 string s = lt.Value;
391                 if (s != "alias"){
392                         Report.Error (1003, lt.Location, "'alias' expected");
393                 } else if (RootContext.Version == LanguageVersion.ISO_1) {
394                         Report.FeatureIsNotAvailable (lt.Location, "external alias");
395                 } else {
396                         lt = (LocatedToken) $3; 
397                         current_namespace.AddUsingExternalAlias (lt.Value, lt.Location);
398                 }
399           }
400         ;
401  
402 using_directives
403         : using_directive 
404         | using_directives using_directive
405         ;
406
407 using_directive
408         : using_alias_directive
409           {
410                 if (RootContext.Documentation != null)
411                         Lexer.doc_state = XmlCommentState.Allowed;
412           }
413         | using_namespace_directive
414           {
415                 if (RootContext.Documentation != null)
416                         Lexer.doc_state = XmlCommentState.Allowed;
417           }
418         ;
419
420 using_alias_directive
421         : USING IDENTIFIER ASSIGN 
422           namespace_or_type_name SEMICOLON
423           {
424                 LocatedToken lt = (LocatedToken) $2;
425                 current_namespace.AddUsingAlias (lt.Value, (MemberName) $4, (Location) $1);
426           }
427         | USING error {
428                 CheckIdentifierToken (yyToken, GetLocation ($2));
429                 $$ = null;
430           }
431         ;
432
433 using_namespace_directive
434         : USING namespace_name SEMICOLON 
435           {
436                 current_namespace.AddUsing ((MemberName) $2, (Location) $1);
437           }
438         ;
439
440 //
441 // Strictly speaking, namespaces don't have attributes but
442 // we parse global attributes along with namespace declarations and then
443 // detach them
444 // 
445 namespace_declaration
446         : opt_attributes NAMESPACE qualified_identifier
447           {
448                 MemberName name = (MemberName) $3;
449
450                 if ($1 != null) {
451                         Report.Error(1671, name.Location, "A namespace declaration cannot have modifiers or attributes");
452                 }
453
454                 current_namespace = new NamespaceEntry (
455                         current_namespace, file, name.GetName ());
456                 current_class = current_namespace.SlaveDeclSpace;
457                 current_container = current_class.PartialContainer;
458           } 
459           namespace_body opt_semicolon
460           { 
461                 current_namespace = current_namespace.Parent;
462                 current_class = current_namespace.SlaveDeclSpace;
463                 current_container = current_class.PartialContainer;
464           }
465         ;
466
467 qualified_identifier
468         : IDENTIFIER
469           {
470                 LocatedToken lt = (LocatedToken) $1;
471                 $$ = new MemberName (lt.Value, lt.Location);
472           }
473         | qualified_identifier DOT IDENTIFIER
474           {
475                 LocatedToken lt = (LocatedToken) $3;
476                 $$ = new MemberName ((MemberName) $1, lt.Value, lt.Location);           
477           }
478         | error
479           {
480                 syntax_error (lexer.Location, "`.' expected");
481           }
482         ;
483
484 opt_semicolon
485         : /* empty */
486         | SEMICOLON
487         ;
488
489 opt_comma
490         : /* empty */
491         | COMMA
492         ;
493
494 namespace_name
495         : namespace_or_type_name {
496                 MemberName name = (MemberName) $1;
497
498                 if (name.TypeArguments != null)
499                         syntax_error (lexer.Location, "namespace name expected");
500
501                 $$ = name;
502           }
503         ;
504
505 namespace_body
506         : OPEN_BRACE
507           {
508                 if (RootContext.Documentation != null)
509                         Lexer.doc_state = XmlCommentState.Allowed;
510           }
511           namespace_body_body
512         ;
513         
514 namespace_body_body
515         : opt_extern_alias_directives
516           opt_using_directives
517           opt_namespace_member_declarations
518           CLOSE_BRACE
519         | error
520           {
521                 Report.Error (1518, lexer.Location, "Expected `class', `delegate', `enum', `interface', or `struct'");
522           }
523           CLOSE_BRACE
524         | opt_extern_alias_directives
525           opt_using_directives
526           opt_namespace_member_declarations
527           EOF
528           {
529                 Report.Error (1513, lexer.Location, "} expected");
530           }
531         ;
532
533 opt_using_directives
534         : /* empty */
535         | using_directives
536         ;
537
538 opt_extern_alias_directives
539         : /* empty */
540         | extern_alias_directives
541         ;
542
543 opt_namespace_member_declarations
544         : /* empty */
545         | namespace_member_declarations
546         ;
547
548 namespace_member_declarations
549         : namespace_member_declaration
550         | namespace_member_declarations namespace_member_declaration
551         ;
552
553 namespace_member_declaration
554         : type_declaration
555           {
556                 if ($1 != null) {
557                         DeclSpace ds = (DeclSpace)$1;
558
559                         if ((ds.ModFlags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
560                                 Report.Error (1527, ds.Location, 
561                                 "Namespace elements cannot be explicitly declared as private, protected or protected internal");
562                         }
563                 }
564                 current_namespace.DeclarationFound = true;
565           }
566         | namespace_declaration {
567                 current_namespace.DeclarationFound = true;
568           }
569
570         | field_declaration {
571                 Report.Error (116, ((MemberCore) $1).Location, "A namespace can only contain types and namespace declarations");
572           }
573         | method_declaration {
574                 Report.Error (116, ((MemberCore) $1).Location, "A namespace can only contain types and namespace declarations");
575           }
576         ;
577
578 type_declaration
579         : class_declaration             
580         | struct_declaration            
581         | interface_declaration         
582         | enum_declaration              
583         | delegate_declaration
584 //
585 // Enable this when we have handled all errors, because this acts as a generic fallback
586 //
587 //      | error {
588 //              Console.WriteLine ("Token=" + yyToken);
589 //              Report.Error (1518, GetLocation ($1), "Expected class, struct, interface, enum or delegate");
590 //        }
591         ;
592
593 //
594 // Attributes 17.2
595 //
596
597 global_attributes
598         : attribute_sections
599 {
600         if ($1 != null) {
601                 Attributes attrs = (Attributes)$1;
602                 if (global_attrs_enabled) {
603                         CodeGen.Assembly.AddAttributes (attrs.Attrs);
604                 } else {
605                         foreach (Attribute a in attrs.Attrs) {
606                                 Report.Error (1730, a.Location, "Assembly and module attributes must precede all other elements except using clauses and extern alias declarations");
607                         }
608                 }
609         }
610
611         $$ = $1;
612 }
613
614 opt_attributes
615         : /* empty */ 
616           {
617                 global_attrs_enabled = false;
618                 $$ = null;
619       }
620         | attribute_sections
621           { 
622                 global_attrs_enabled = false;
623                 $$ = $1;
624           }
625     ;
626  
627
628 attribute_sections
629         : attribute_section
630           {
631                 if (current_attr_target != String.Empty) {
632                         ArrayList sect = (ArrayList) $1;
633
634                         if (global_attrs_enabled) {
635                                 if (current_attr_target == "module") {
636                                         CodeGen.Module.AddAttributes (sect);
637                                         $$ = null;
638                                 } else if (current_attr_target != null && current_attr_target.Length > 0) {
639                                         CodeGen.Assembly.AddAttributes (sect);
640                                         $$ = null;
641                                 } else {
642                                         $$ = new Attributes (sect);
643                                 }
644                                 if ($$ == null) {
645                                         if (RootContext.Documentation != null) {
646                                                 Lexer.check_incorrect_doc_comment ();
647                                                 Lexer.doc_state =
648                                                         XmlCommentState.Allowed;
649                                         }
650                                 }
651                         } else {
652                                 $$ = new Attributes (sect);
653                         }               
654                 }
655                 else
656                         $$ = null;
657                 current_attr_target = null;
658           }
659         | attribute_sections attribute_section
660           {
661                 if (current_attr_target != String.Empty) {
662                         Attributes attrs = $1 as Attributes;
663                         ArrayList sect = (ArrayList) $2;
664
665                         if (global_attrs_enabled) {
666                                 if (current_attr_target == "module") {
667                                         CodeGen.Module.AddAttributes (sect);
668                                         $$ = null;
669                                 } else if (current_attr_target == "assembly") {
670                                         CodeGen.Assembly.AddAttributes (sect);
671                                         $$ = null;
672                                 } else {
673                                         if (attrs == null)
674                                                 attrs = new Attributes (sect);
675                                         else
676                                                 attrs.AddAttributes (sect);                     
677                                 }
678                         } else {
679                                 if (attrs == null)
680                                         attrs = new Attributes (sect);
681                                 else
682                                         attrs.AddAttributes (sect);
683                         }               
684                         $$ = attrs;
685                 }
686                 else
687                         $$ = null;
688                 current_attr_target = null;
689           }
690         ;
691
692 attribute_section
693         : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
694           {
695                 $$ = $3;
696           }
697         | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
698           {
699                 $$ = $2;
700           }
701         ;
702  
703 attribute_target_specifier
704         : attribute_target COLON
705           {
706                 current_attr_target = (string)$1;
707                 $$ = $1;
708           }
709         ;
710
711 attribute_target
712         : IDENTIFIER
713           {
714                 LocatedToken lt = (LocatedToken) $1;
715                 $$ = CheckAttributeTarget (lt.Value, lt.Location);
716           }
717         | EVENT  { $$ = "event"; }
718         | RETURN { $$ = "return"; }
719         | error
720           {
721                 string name = yyNames [yyToken].ToLower ();
722                 $$ = CheckAttributeTarget (name, GetLocation ($1));
723           }
724         ;
725
726 attribute_list
727         : attribute
728           {
729                 ArrayList attrs = new ArrayList (4);
730                 attrs.Add ($1);
731
732                 $$ = attrs;
733                
734           }
735         | attribute_list COMMA attribute
736           {
737                 ArrayList attrs = (ArrayList) $1;
738                 attrs.Add ($3);
739
740                 $$ = attrs;
741           }
742         ;
743
744 attribute
745         : attribute_name opt_attribute_arguments
746           {
747                 MemberName mname = (MemberName) $1;
748                 if (mname.IsGeneric) {
749                         Report.Error (404, lexer.Location,
750                                       "'<' unexpected: attributes cannot be generic");
751                 }
752
753                 object [] arguments = (object []) $2;
754                 MemberName left = mname.Left;
755                 string identifier = mname.Name;
756
757                 Expression left_expr = left == null ? null : left.GetTypeExpression ();
758
759                 if (current_attr_target == String.Empty)
760                         $$ = null;
761                 else if (global_attrs_enabled && (current_attr_target == "assembly" || current_attr_target == "module"))
762                         // FIXME: supply "nameEscaped" parameter here.
763                         $$ = new GlobalAttribute (current_namespace, current_attr_target,
764                                                   left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location));
765                 else
766                         $$ = new Attribute (current_attr_target, left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location));
767           }
768         ;
769
770 attribute_name
771         : namespace_or_type_name  { /* reserved attribute name or identifier: 17.4 */ }
772         ;
773
774 opt_attribute_arguments
775         : /* empty */   { $$ = null; }
776         | OPEN_PARENS attribute_arguments CLOSE_PARENS
777           {
778                 $$ = $2;
779           }
780         ;
781
782
783 attribute_arguments
784         : opt_positional_argument_list
785           {
786                 if ($1 == null)
787                         $$ = null;
788                 else {
789                         $$ = new object [] { $1, null };
790                 }
791           }
792     | positional_argument_list COMMA named_argument_list
793           {
794                 $$ = new object[] { $1, $3 };
795           }
796     | named_argument_list
797           {
798                 $$ = new object [] { null, $1 };
799           }
800     ;
801
802
803 opt_positional_argument_list
804         : /* empty */           { $$ = null; } 
805         | positional_argument_list
806         ;
807
808 positional_argument_list
809         : expression
810           {
811                 ArrayList args = new ArrayList (4);
812                 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
813
814                 $$ = args;
815           }
816         | positional_argument_list COMMA expression
817          {
818                 ArrayList args = (ArrayList) $1;
819                 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
820
821                 $$ = args;
822          }
823         ;
824
825 named_argument_list
826         : named_argument
827           {
828                 ArrayList args = new ArrayList (4);
829                 args.Add ($1);
830
831                 $$ = args;
832           }
833         | named_argument_list COMMA named_argument
834           {       
835                 ArrayList args = (ArrayList) $1;
836                 args.Add ($3);
837
838                 $$ = args;
839           }
840           | named_argument_list COMMA expression
841             {
842                   Report.Error (1016, ((Expression) $3).Location, "Named attribute argument expected");
843                   $$ = null;
844                 }
845         ;
846
847 named_argument
848         : IDENTIFIER ASSIGN expression
849           {
850                 // FIXME: keep location
851                 $$ = new DictionaryEntry (
852                         ((LocatedToken) $1).Value, 
853                         new Argument ((Expression) $3, Argument.AType.Expression));
854           }
855         ;
856
857                   
858 class_body
859         :  OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
860         ;
861
862 opt_class_member_declarations
863         : /* empty */
864         | class_member_declarations
865         ;
866
867 class_member_declarations
868         : class_member_declaration
869         | class_member_declarations 
870           class_member_declaration
871         ;
872
873 class_member_declaration
874         : constant_declaration                  // done
875         | field_declaration                     // done
876         | method_declaration                    // done
877         | property_declaration                  // done
878         | event_declaration                     // done
879         | indexer_declaration                   // done
880         | operator_declaration                  // done
881         | constructor_declaration               // done
882         | destructor_declaration                // done
883         | type_declaration
884         ;
885
886 struct_declaration
887         : opt_attributes
888           opt_modifiers
889           opt_partial
890           STRUCT
891           {
892                 lexer.ConstraintsParsing = true;
893           }
894           type_name
895           { 
896                 MemberName name = MakeName ((MemberName) $6);
897                 push_current_class (new Struct (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3);
898           }
899           opt_class_base
900           opt_type_parameter_constraints_clauses
901           {
902                 lexer.ConstraintsParsing = false;
903
904                 current_class.SetParameterInfo ((ArrayList) $9);
905
906                 if (RootContext.Documentation != null)
907                         current_container.DocComment = Lexer.consume_doc_comment ();
908           }
909           struct_body
910           {
911                 if (RootContext.Documentation != null)
912                         Lexer.doc_state = XmlCommentState.Allowed;
913           }
914           opt_semicolon
915           {
916                 $$ = pop_current_class ();
917           }
918         | opt_attributes opt_modifiers opt_partial STRUCT error {
919                 CheckIdentifierToken (yyToken, GetLocation ($5));
920           }
921         ;
922
923 struct_body
924         : OPEN_BRACE
925           {
926                 if (RootContext.Documentation != null)
927                         Lexer.doc_state = XmlCommentState.Allowed;
928           }
929           opt_struct_member_declarations CLOSE_BRACE
930         ;
931
932 opt_struct_member_declarations
933         : /* empty */
934         | struct_member_declarations
935         ;
936
937 struct_member_declarations
938         : struct_member_declaration
939         | struct_member_declarations struct_member_declaration
940         ;
941
942 struct_member_declaration
943         : constant_declaration
944         | field_declaration
945         | method_declaration
946         | property_declaration
947         | event_declaration
948         | indexer_declaration
949         | operator_declaration
950         | constructor_declaration
951         | type_declaration
952
953         /*
954          * This is only included so we can flag error 575: 
955          * destructors only allowed on class types
956          */
957         | destructor_declaration 
958         ;
959
960 constant_declaration
961         : opt_attributes 
962           opt_modifiers
963           CONST
964           type
965           constant_declarators
966           SEMICOLON
967           {
968                 int modflags = (int) $2;
969                 foreach (VariableDeclaration constant in (ArrayList) $5){
970                         Location l = constant.Location;
971                         if ((modflags & Modifiers.STATIC) != 0) {
972                                 Report.Error (504, l, "The constant `{0}' cannot be marked static", current_container.GetSignatureForError () + '.' + (string) constant.identifier);
973                                 continue;
974                         }
975
976                         Const c = new Const (
977                                 current_class, (FullNamedExpression) $4, (string) constant.identifier, 
978                                 (Expression) constant.expression_or_array_initializer, modflags, 
979                                 (Attributes) $1, l);
980
981                         if (RootContext.Documentation != null) {
982                                 c.DocComment = Lexer.consume_doc_comment ();
983                                 Lexer.doc_state = XmlCommentState.Allowed;
984                         }
985                         current_container.AddConstant (c);
986                 }
987           }
988         ;
989
990 constant_declarators
991         : constant_declarator 
992           {
993                 ArrayList constants = new ArrayList (4);
994                 if ($1 != null)
995                         constants.Add ($1);
996                 $$ = constants;
997           }
998         | constant_declarators COMMA constant_declarator
999           {
1000                 if ($3 != null) {
1001                         ArrayList constants = (ArrayList) $1;
1002                         constants.Add ($3);
1003                 }
1004           }
1005         ;
1006
1007 constant_declarator
1008         : IDENTIFIER ASSIGN constant_expression
1009           {
1010                 $$ = new VariableDeclaration ((LocatedToken) $1, $3);
1011           }
1012         | IDENTIFIER
1013           {
1014                 // A const field requires a value to be provided
1015                 Report.Error (145, ((LocatedToken) $1).Location, "A const field requires a value to be provided");
1016                 $$ = null;
1017           }
1018         ;
1019
1020 field_declaration
1021         : opt_attributes
1022           opt_modifiers
1023           type 
1024           variable_declarators
1025           SEMICOLON
1026           { 
1027                 FullNamedExpression type = (FullNamedExpression) $3;
1028                 int mod = (int) $2;
1029
1030                 current_array_type = null;
1031
1032                 foreach (VariableDeclaration var in (ArrayList) $4){
1033                         Field field = new Field (current_class, type, mod, var.identifier, 
1034                                                  (Attributes) $1, var.Location);
1035
1036                         field.Initializer = var.expression_or_array_initializer;
1037
1038                         if (RootContext.Documentation != null) {
1039                                 field.DocComment = Lexer.consume_doc_comment ();
1040                                 Lexer.doc_state = XmlCommentState.Allowed;
1041                         }
1042                         current_container.AddField (field);
1043                         $$ = field; // FIXME: might be better if it points to the top item
1044                 }
1045           }
1046         | opt_attributes
1047           opt_modifiers
1048           FIXED
1049           type 
1050           fixed_variable_declarators
1051           SEMICOLON
1052           { 
1053                         FullNamedExpression type = (FullNamedExpression) $4;
1054                         int mod = (int) $2;
1055
1056                         current_array_type = null;
1057
1058                         foreach (VariableDeclaration var in (ArrayList) $5) {
1059                                 FixedField field = new FixedField (current_class, type, mod, var.identifier,
1060                                         (Expression)var.expression_or_array_initializer, (Attributes) $1, var.Location);
1061
1062                                 if (RootContext.Documentation != null) {
1063                                         field.DocComment = Lexer.consume_doc_comment ();
1064                                         Lexer.doc_state = XmlCommentState.Allowed;
1065                                 }
1066                                 current_container.AddField (field);
1067                                 $$ = field; // FIXME: might be better if it points to the top item
1068                         }
1069           }
1070         | opt_attributes
1071           opt_modifiers
1072           FIXED
1073           type 
1074           error
1075           {
1076                 Report.Error (1641, GetLocation ($4), "A fixed size buffer field must have the array size specifier after the field name");
1077           }
1078         | opt_attributes
1079           opt_modifiers
1080           VOID  
1081           variable_declarators
1082           SEMICOLON {
1083                 current_array_type = null;
1084                 Report.Error (670, (Location) $3, "Fields cannot have void type");
1085           }
1086         ;
1087
1088 fixed_variable_declarators
1089         : fixed_variable_declarator
1090           {
1091                 ArrayList decl = new ArrayList (2);
1092                 decl.Add ($1);
1093                 $$ = decl;
1094           }
1095         | fixed_variable_declarators COMMA fixed_variable_declarator
1096           {
1097                 ArrayList decls = (ArrayList) $1;
1098                 decls.Add ($3);
1099                 $$ = $1;
1100           }
1101         ;
1102
1103 fixed_variable_declarator
1104         : IDENTIFIER OPEN_BRACKET expression CLOSE_BRACKET
1105           {
1106                 $$ = new VariableDeclaration ((LocatedToken) $1, $3);
1107           }
1108         | IDENTIFIER OPEN_BRACKET CLOSE_BRACKET
1109           {
1110                 Report.Error (443, lexer.Location, "Value or constant expected");
1111                 $$ = new VariableDeclaration ((LocatedToken) $1, null);
1112           }
1113         ;
1114
1115 variable_declarators
1116         : variable_declarator 
1117           {
1118                 ArrayList decl = new ArrayList (4);
1119                 if ($1 != null)
1120                         decl.Add ($1);
1121                 $$ = decl;
1122           }
1123         | variable_declarators COMMA variable_declarator
1124           {
1125                 ArrayList decls = (ArrayList) $1;
1126                 decls.Add ($3);
1127                 $$ = $1;
1128           }
1129         ;
1130
1131 variable_declarator
1132         : IDENTIFIER ASSIGN variable_initializer
1133           {
1134                 $$ = new VariableDeclaration ((LocatedToken) $1, $3);
1135           }
1136         | IDENTIFIER
1137           {
1138                 $$ = new VariableDeclaration ((LocatedToken) $1, null);
1139           }
1140         | IDENTIFIER OPEN_BRACKET opt_expression CLOSE_BRACKET
1141           {
1142                 Report.Error (650, ((LocatedToken) $1).Location, "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. " +
1143                         "To declare a fixed size buffer field, use the fixed keyword before the field type");
1144                 $$ = null;
1145           }
1146         ;
1147
1148 variable_initializer
1149         : expression
1150           {
1151                 $$ = $1;
1152           }
1153         | array_initializer
1154           {
1155                 $$ = $1;
1156           }
1157         | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
1158           {
1159                 $$ = new StackAlloc ((Expression) $2, (Expression) $4, (Location) $1);
1160           }
1161         | ARGLIST
1162           {
1163                 $$ = new ArglistAccess ((Location) $1);
1164           }
1165         | STACKALLOC type
1166           {
1167                 Report.Error (1575, (Location) $1, "A stackalloc expression requires [] after type");
1168                 $$ = null;
1169           }
1170         ;
1171
1172 method_declaration
1173         : method_header {
1174                 if (RootContext.Documentation != null)
1175                         Lexer.doc_state = XmlCommentState.NotAllowed;
1176           }
1177           method_body
1178           {
1179                 Method method = (Method) $1;
1180                 method.Block = (ToplevelBlock) $3;
1181                 current_container.AddMethod (method);
1182                 
1183                 if (current_container.Kind == Kind.Interface && method.Block != null) {
1184                         Report.Error (531, method.Location, "`{0}': interface members cannot have a definition", method.GetSignatureForError ());
1185                 }
1186
1187                 current_generic_method = null;
1188                 current_local_parameters = null;
1189
1190                 if (RootContext.Documentation != null)
1191                         Lexer.doc_state = XmlCommentState.Allowed;
1192           }
1193         ;
1194
1195 opt_error_modifier
1196         : /* empty */
1197         | modifiers 
1198           {
1199                 int m = (int) $1;
1200                 int i = 1;
1201
1202                 while (m != 0){
1203                         if ((i & m) != 0){
1204                                 Report.Error (1585, lexer.Location,
1205                                         "Member modifier `{0}' must precede the member type and name",
1206                                         Modifiers.Name (i));
1207                         }
1208                         m &= ~i;
1209                         i = i << 1;
1210                 }
1211           }
1212         ;
1213
1214 method_header
1215         : opt_attributes
1216           opt_modifiers
1217           type member_name
1218           OPEN_PARENS
1219           {
1220                 arglist_allowed = true;
1221           }
1222           opt_formal_parameter_list CLOSE_PARENS 
1223           {
1224                 lexer.ConstraintsParsing = true;
1225           }
1226           opt_type_parameter_constraints_clauses
1227           {
1228                 lexer.ConstraintsParsing = false;
1229                 arglist_allowed = false;
1230                 MemberName name = (MemberName) $4;
1231                 current_local_parameters = (Parameters) $7;
1232
1233                 if ($10 != null && name.TypeArguments == null)
1234                         Report.Error (80, lexer.Location,
1235                                       "Constraints are not allowed on non-generic declarations");
1236
1237                 Method method;
1238
1239                 GenericMethod generic = null;
1240                 if (name.TypeArguments != null) {
1241                         generic = new GenericMethod (current_namespace, current_class, name,
1242                                                      (FullNamedExpression) $3, current_local_parameters);
1243
1244                         generic.SetParameterInfo ((ArrayList) $10);
1245                 }
1246
1247                 method = new Method (current_class, generic, (FullNamedExpression) $3, (int) $2,
1248                                      name, current_local_parameters, (Attributes) $1);
1249
1250                 current_generic_method = generic;
1251
1252                 if (RootContext.Documentation != null)
1253                         method.DocComment = Lexer.consume_doc_comment ();
1254
1255                 $$ = method;
1256           }
1257         | opt_attributes
1258           opt_modifiers
1259           VOID member_name
1260           OPEN_PARENS
1261           {
1262                 arglist_allowed = true;
1263           }       
1264           opt_formal_parameter_list CLOSE_PARENS
1265           {
1266                 lexer.ConstraintsParsing = true;
1267           }
1268           opt_type_parameter_constraints_clauses
1269           {
1270                 lexer.ConstraintsParsing = false;
1271                 arglist_allowed = false;
1272
1273                 MemberName name = (MemberName) $4;
1274                 current_local_parameters = (Parameters) $7;
1275
1276                 if ($10 != null && name.TypeArguments == null)
1277                         Report.Error (80, lexer.Location,
1278                                       "Constraints are not allowed on non-generic declarations");
1279
1280                 Method method;
1281                 GenericMethod generic = null;
1282                 if (name.TypeArguments != null) {
1283                         generic = new GenericMethod (current_namespace, current_class, name,
1284                                                      TypeManager.system_void_expr, current_local_parameters);
1285
1286                         generic.SetParameterInfo ((ArrayList) $10);
1287                 }
1288
1289                 method = new Method (current_class, generic, TypeManager.system_void_expr,
1290                                      (int) $2, name, current_local_parameters, (Attributes) $1);
1291
1292                 current_generic_method = generic;
1293
1294                 if (RootContext.Documentation != null)
1295                         method.DocComment = Lexer.consume_doc_comment ();
1296
1297                 $$ = method;
1298         }
1299         | opt_attributes
1300           opt_modifiers
1301           PARTIAL
1302           VOID member_name
1303           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
1304           {
1305                 lexer.ConstraintsParsing = true;
1306           }
1307           opt_type_parameter_constraints_clauses
1308           {
1309                 lexer.ConstraintsParsing = false;
1310
1311                 MemberName name = (MemberName) $5;
1312                 current_local_parameters = (Parameters) $7;
1313
1314                 if ($9 != null && name.TypeArguments == null)
1315                         Report.Error (80, lexer.Location,
1316                                       "Constraints are not allowed on non-generic declarations");
1317
1318                 Method method;
1319                 GenericMethod generic = null;
1320                 if (name.TypeArguments != null) {
1321                         generic = new GenericMethod (current_namespace, current_class, name,
1322                                                      TypeManager.system_void_expr, current_local_parameters);
1323
1324                         generic.SetParameterInfo ((ArrayList) $10);
1325                 }
1326
1327                 int modifiers = (int) $2;
1328
1329
1330                 const int invalid_partial_mod = Modifiers.Accessibility | Modifiers.ABSTRACT | Modifiers.EXTERN |
1331                         Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.SEALED | Modifiers.VIRTUAL;
1332
1333                 if ((modifiers & invalid_partial_mod) != 0) {
1334                         Report.Error (750, name.Location, "A partial method cannot define access modifier or " +
1335                         "any of abstract, extern, new, override, sealed, or virtual modifiers");
1336                         modifiers &= ~invalid_partial_mod;
1337                 }
1338
1339                 if ((current_class.ModFlags & Modifiers.PARTIAL) == 0) {
1340                         Report.Error (751, name.Location, "A partial method must be declared within a " +
1341                         "partial class or partial struct");
1342                 }
1343
1344                 modifiers |= Modifiers.PARTIAL | Modifiers.PRIVATE;
1345                 
1346                 method = new Method (current_class, generic, TypeManager.system_void_expr,
1347                                      modifiers, name, current_local_parameters, (Attributes) $1);
1348
1349                 current_generic_method = generic;
1350
1351                 if (RootContext.Documentation != null)
1352                         method.DocComment = Lexer.consume_doc_comment ();
1353
1354                 $$ = method;
1355           }
1356         | opt_attributes
1357           opt_modifiers
1358           type 
1359           modifiers member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1360           {
1361                 MemberName name = (MemberName) $5;
1362                 Report.Error (1585, name.Location, 
1363                         "Member modifier `{0}' must precede the member type and name", Modifiers.Name ((int) $4));
1364
1365                 Method method = new Method (current_class, null, TypeManager.system_void_expr,
1366                                             0, name, (Parameters) $7, (Attributes) $1);
1367
1368                 current_local_parameters = (Parameters) $7;
1369
1370                 if (RootContext.Documentation != null)
1371                         method.DocComment = Lexer.consume_doc_comment ();
1372
1373                 $$ = null;
1374           }
1375         ;
1376
1377 method_body
1378         : block
1379         | SEMICOLON             { $$ = null; }
1380         ;
1381
1382 opt_formal_parameter_list
1383         : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
1384         | formal_parameter_list
1385         ;
1386         
1387 opt_parameter_list_no_mod
1388         : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
1389         | 
1390           {
1391                 parameter_modifiers_not_allowed = true;
1392           }
1393           formal_parameter_list
1394           {
1395                 parameter_modifiers_not_allowed = false;
1396                 $$ = $2;
1397           }
1398         ;
1399
1400 formal_parameter_list
1401         : fixed_parameters              
1402           { 
1403                 ArrayList pars_list = (ArrayList) $1;
1404
1405                 Parameter [] pars = new Parameter [pars_list.Count];
1406                 pars_list.CopyTo (pars);
1407
1408                 $$ = new Parameters (pars); 
1409           } 
1410         | fixed_parameters COMMA parameter_array
1411           {
1412                 ArrayList pars_list = (ArrayList) $1;
1413                 pars_list.Add ($3);
1414
1415                 Parameter [] pars = new Parameter [pars_list.Count];
1416                 pars_list.CopyTo (pars);
1417
1418                 $$ = new Parameters (pars); 
1419           }
1420         | fixed_parameters COMMA arglist_modifier
1421           {
1422                 ArrayList pars_list = (ArrayList) $1;
1423                 pars_list.Add (new ArglistParameter (GetLocation ($3)));
1424
1425                 Parameter [] pars = new Parameter [pars_list.Count];
1426                 pars_list.CopyTo (pars);
1427
1428                 $$ = new Parameters (pars, true);
1429           }
1430         | parameter_array COMMA error
1431           {
1432                 if ($1 != null)
1433                         Report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list");
1434                 $$ = null;
1435           }
1436         | fixed_parameters COMMA parameter_array COMMA error
1437           {
1438                 if ($3 != null)
1439                         Report.Error (231, ((Parameter) $3).Location, "A params parameter must be the last parameter in a formal parameter list");
1440                 $$ = null;
1441           }
1442         | arglist_modifier COMMA error
1443           {
1444                 Report.Error (257, (Location) $1, "An __arglist parameter must be the last parameter in a formal parameter list");
1445                 $$ = null;
1446           }
1447         | fixed_parameters COMMA ARGLIST COMMA error 
1448           {
1449                 Report.Error (257, (Location) $3, "An __arglist parameter must be the last parameter in a formal parameter list");
1450                 $$ = null;
1451           }
1452         | parameter_array 
1453           {
1454                 $$ = new Parameters (new Parameter[] { (Parameter) $1 } );
1455           }
1456         | arglist_modifier
1457           {
1458                 $$ = new Parameters (new Parameter [] { new ArglistParameter ((Location) $1) }, true);
1459           }
1460         ;
1461
1462 fixed_parameters
1463         : fixed_parameter       
1464           {
1465                 ArrayList pars = new ArrayList (4);
1466
1467                 pars.Add ($1);
1468                 $$ = pars;
1469           }
1470         | fixed_parameters COMMA fixed_parameter
1471           {
1472                 ArrayList pars = (ArrayList) $1;
1473                 Parameter p = (Parameter)$3;
1474                 if (p != null) {
1475                         if (p.HasExtensionMethodModifier)
1476                                 Report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter");
1477                         pars.Add (p);
1478                 }
1479                 $$ = $1;
1480           }
1481         ;
1482
1483 fixed_parameter
1484         : opt_attributes
1485           opt_parameter_modifier
1486           type
1487           IDENTIFIER
1488           {
1489                 LocatedToken lt = (LocatedToken) $4;
1490                 $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
1491           }
1492         | opt_attributes
1493           opt_parameter_modifier
1494           type
1495           IDENTIFIER OPEN_BRACKET CLOSE_BRACKET
1496           {
1497                 LocatedToken lt = (LocatedToken) $4;
1498                 Report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name");
1499                 $$ = null;
1500           }
1501         | opt_attributes
1502           opt_parameter_modifier
1503           type
1504           {
1505                 Report.Error (1001, GetLocation ($3), "Identifier expected");
1506                 $$ = null;
1507           }
1508         | opt_attributes
1509           opt_parameter_modifier
1510           type
1511           error {
1512                 CheckIdentifierToken (yyToken, GetLocation ($4));
1513                 $$ = null;
1514           }
1515         | opt_attributes
1516           opt_parameter_modifier
1517           type
1518           IDENTIFIER
1519           ASSIGN
1520           constant_expression
1521            {
1522                 LocatedToken lt = (LocatedToken) $4;
1523                 Report.Error (241, lt.Location, "Default parameter specifiers are not permitted");
1524                  $$ = null;
1525            }
1526         ;
1527
1528 opt_parameter_modifier
1529         : /* empty */           { $$ = Parameter.Modifier.NONE; }
1530         | parameter_modifiers
1531         ;
1532
1533 parameter_modifiers
1534         : parameter_modifier
1535           {
1536                 $$ = $1;
1537           }
1538         | parameter_modifiers parameter_modifier
1539           {
1540                 Parameter.Modifier p2 = (Parameter.Modifier)$2;
1541                 Parameter.Modifier mod = (Parameter.Modifier)$1 | p2;
1542                 if (((Parameter.Modifier)$1 & p2) == p2) {
1543                         Error_DuplicateParameterModifier (lexer.Location, p2);
1544                 } else {
1545                         switch (mod & ~Parameter.Modifier.This) {
1546                                 case Parameter.Modifier.REF:
1547                                         Report.Error (1101, lexer.Location, "The parameter modifiers `this' and `ref' cannot be used altogether");
1548                                         break;
1549                                 case Parameter.Modifier.OUT:
1550                                         Report.Error (1102, lexer.Location, "The parameter modifiers `this' and `out' cannot be used altogether");
1551                                         break;
1552                                 default:
1553                                         Report.Error (1108, lexer.Location, "A parameter cannot have specified more than one modifier");
1554                                         break;
1555                         }
1556                 }
1557                 $$ = mod;
1558           }
1559         ;
1560
1561 parameter_modifier
1562         : REF
1563           {
1564                 if (parameter_modifiers_not_allowed)
1565                         Error_ParameterModifierNotValid ("ref", (Location)$1);
1566                         
1567                 $$ = Parameter.Modifier.REF;
1568           }
1569         | OUT
1570           {
1571                 if (parameter_modifiers_not_allowed)
1572                         Error_ParameterModifierNotValid ("out", (Location)$1);
1573           
1574                 $$ = Parameter.Modifier.OUT;
1575           }
1576         | THIS
1577           {
1578                 if (parameter_modifiers_not_allowed)
1579                         Error_ParameterModifierNotValid ("this", (Location)$1);
1580
1581                 if (RootContext.Version <= LanguageVersion.ISO_2)
1582                         Report.FeatureIsNotAvailable (GetLocation ($1), "extension methods");
1583                                 
1584                 $$ = Parameter.Modifier.This;
1585           }
1586         ;
1587
1588 parameter_array
1589         : opt_attributes params_modifier type IDENTIFIER
1590           { 
1591                 LocatedToken lt = (LocatedToken) $4;
1592                 $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location);
1593           }
1594         | opt_attributes params_modifier type error {
1595                 CheckIdentifierToken (yyToken, GetLocation ($4));
1596                 $$ = null;
1597           }
1598         ;
1599         
1600 params_modifier
1601         : PARAMS
1602           {
1603                 if (params_modifiers_not_allowed)
1604                         Report.Error (1670, ((Location) $1), "The `params' modifier is not allowed in current context");
1605           }
1606         | PARAMS parameter_modifier
1607           {
1608                 Parameter.Modifier mod = (Parameter.Modifier)$2;
1609                 if ((mod & Parameter.Modifier.This) != 0) {
1610                         Report.Error (1104, (Location)$1, "The parameter modifiers `this' and `params' cannot be used altogether");
1611                 } else {
1612                         Report.Error (1611, (Location)$1, "The params parameter cannot be declared as ref or out");
1613                 }         
1614           }
1615         | PARAMS params_modifier
1616           {
1617                 Error_DuplicateParameterModifier ((Location)$1, Parameter.Modifier.PARAMS);
1618           }
1619         ;
1620         
1621 arglist_modifier
1622         : ARGLIST
1623           {
1624                 if (!arglist_allowed)
1625                         Report.Error (1669, (Location) $1, "__arglist is not valid in this context");
1626           }
1627         ;
1628         
1629 property_declaration
1630         : opt_attributes
1631           opt_modifiers
1632           type
1633           namespace_or_type_name
1634           {
1635                 if (RootContext.Documentation != null)
1636                         tmpComment = Lexer.consume_doc_comment ();
1637           }
1638           OPEN_BRACE 
1639           {
1640                 implicit_value_parameter_type = (FullNamedExpression) $3;
1641
1642                 lexer.PropertyParsing = true;
1643           }
1644           accessor_declarations 
1645           {
1646                 lexer.PropertyParsing = false;
1647                 has_get = has_set = false;
1648           }
1649           CLOSE_BRACE
1650           { 
1651                 Property prop;
1652                 Accessors accessors = (Accessors) $8;
1653                 Accessor get_block = accessors != null ? accessors.get_or_add : null;
1654                 Accessor set_block = accessors != null ? accessors.set_or_remove : null;
1655                 bool order = accessors != null ? accessors.declared_in_reverse : false;
1656
1657                 MemberName name = (MemberName) $4;
1658                 FullNamedExpression ptype = (FullNamedExpression) $3;
1659
1660                 if (name.TypeArguments != null)
1661                         syntax_error (lexer.Location, "a property can't have type arguments");
1662
1663                 prop = new Property (current_class, ptype, (int) $2,
1664                                      name, (Attributes) $1, get_block, set_block, order, current_block);
1665
1666                 if (ptype == TypeManager.system_void_expr)
1667                         Report.Error (547, ptype.Location, "`{0}': property return type cannot be `void'", prop.GetSignatureForError ());
1668                         
1669                 if (accessors == null)
1670                         Report.Error (548, prop.Location, "`{0}': property or indexer must have at least one accessor", prop.GetSignatureForError ());
1671
1672                 if (current_container.Kind == Kind.Interface) {
1673                         if (prop.Get.Block != null)
1674                                 Report.Error (531, prop.Location, "`{0}.get': interface members cannot have a definition", prop.GetSignatureForError ());
1675
1676                         if (prop.Set.Block != null)
1677                                 Report.Error (531, prop.Location, "`{0}.set': interface members cannot have a definition", prop.GetSignatureForError ());
1678                 }
1679
1680                 current_container.AddProperty (prop);
1681                 implicit_value_parameter_type = null;
1682
1683                 if (RootContext.Documentation != null)
1684                         prop.DocComment = ConsumeStoredComment ();
1685
1686           }
1687         ;
1688         
1689 accessor_declarations
1690         : get_accessor_declaration
1691          {
1692                 $$ = new Accessors ((Accessor) $1, null);
1693          }
1694         | get_accessor_declaration accessor_declarations
1695          { 
1696                 Accessors accessors = (Accessors) $2;
1697                 accessors.get_or_add = (Accessor) $1;
1698                 $$ = accessors;
1699          }
1700         | set_accessor_declaration
1701          {
1702                 $$ = new Accessors (null, (Accessor) $1);
1703          }
1704         | set_accessor_declaration accessor_declarations
1705          { 
1706                 Accessors accessors = (Accessors) $2;
1707                 accessors.set_or_remove = (Accessor) $1;
1708                 accessors.declared_in_reverse = true;
1709                 $$ = accessors;
1710          }
1711         | error
1712           {
1713                 Report.Error (1014, GetLocation ($1), "A get or set accessor expected");
1714                 $$ = null;
1715           }
1716         ;
1717
1718 get_accessor_declaration
1719         : opt_attributes opt_modifiers GET
1720           {
1721                 // If this is not the case, then current_local_parameters has already
1722                 // been set in indexer_declaration
1723                 if (parsing_indexer == false)
1724                         current_local_parameters = null;
1725                 else 
1726                         current_local_parameters = indexer_parameters;
1727                 lexer.PropertyParsing = false;
1728           }
1729           accessor_body
1730           {
1731                 if (has_get) {
1732                         Report.Error (1007, (Location) $3, "Property accessor already defined");
1733                         break;
1734                 }
1735                 Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, current_local_parameters, (Location) $3);
1736                 has_get = true;
1737                 current_local_parameters = null;
1738                 lexer.PropertyParsing = true;
1739
1740                 if (RootContext.Documentation != null)
1741                         if (Lexer.doc_state == XmlCommentState.Error)
1742                                 Lexer.doc_state = XmlCommentState.NotAllowed;
1743
1744                 $$ = accessor;
1745           }
1746         ;
1747
1748 set_accessor_declaration
1749         : opt_attributes opt_modifiers SET 
1750           {
1751                 Parameter implicit_value_parameter = new Parameter (
1752                         implicit_value_parameter_type, "value", 
1753                         Parameter.Modifier.NONE, null, (Location) $3);
1754
1755                 if (!parsing_indexer) {
1756                         current_local_parameters = new Parameters (new Parameter [] { implicit_value_parameter });
1757                 } else {
1758                         current_local_parameters = Parameters.MergeGenerated (
1759                                 indexer_parameters, true, implicit_value_parameter, null);
1760                 }
1761                 
1762                 lexer.PropertyParsing = false;
1763           }
1764           accessor_body
1765           {
1766                 if (has_set) {
1767                         Report.Error (1007, ((LocatedToken) $3).Location, "Property accessor already defined");
1768                         break;
1769                 }
1770                 Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, current_local_parameters, (Location) $3);
1771                 has_set = true;
1772                 current_local_parameters = null;
1773                 lexer.PropertyParsing = true;
1774
1775                 if (RootContext.Documentation != null
1776                         && Lexer.doc_state == XmlCommentState.Error)
1777                         Lexer.doc_state = XmlCommentState.NotAllowed;
1778
1779                 $$ = accessor;
1780           }
1781         ;
1782
1783 accessor_body
1784         : block 
1785         | SEMICOLON             { $$ = null; }
1786         ;
1787
1788 interface_declaration
1789         : opt_attributes
1790           opt_modifiers
1791           opt_partial
1792           INTERFACE
1793           {
1794                 lexer.ConstraintsParsing = true;
1795           }
1796           type_name
1797           {
1798                 MemberName name = MakeName ((MemberName) $6);
1799                 push_current_class (new Interface (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3);
1800           }
1801           opt_class_base
1802           opt_type_parameter_constraints_clauses
1803           {
1804                 lexer.ConstraintsParsing = false;
1805
1806                 current_class.SetParameterInfo ((ArrayList) $9);
1807
1808                 if (RootContext.Documentation != null) {
1809                         current_container.DocComment = Lexer.consume_doc_comment ();
1810                         Lexer.doc_state = XmlCommentState.Allowed;
1811                 }
1812           }
1813           interface_body
1814           {
1815                 if (RootContext.Documentation != null)
1816                         Lexer.doc_state = XmlCommentState.Allowed;
1817           }
1818           opt_semicolon 
1819           {
1820                 $$ = pop_current_class ();
1821           }
1822         | opt_attributes opt_modifiers opt_partial INTERFACE error {
1823                 CheckIdentifierToken (yyToken, GetLocation ($5));
1824           }
1825         ;
1826
1827 interface_body
1828         : OPEN_BRACE
1829           opt_interface_member_declarations
1830           CLOSE_BRACE
1831         ;
1832
1833 opt_interface_member_declarations
1834         : /* empty */
1835         | interface_member_declarations
1836         ;
1837
1838 interface_member_declarations
1839         : interface_member_declaration
1840         | interface_member_declarations interface_member_declaration
1841         ;
1842
1843 interface_member_declaration
1844         : constant_declaration
1845           {
1846                 Report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
1847           }
1848         | field_declaration
1849           {
1850                 Report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
1851           }
1852         | method_declaration
1853         | property_declaration
1854         | event_declaration
1855         | indexer_declaration
1856         | operator_declaration
1857           {
1858                 Report.Error (567, GetLocation ($1), "Interfaces cannot contain operators");
1859           }
1860         | constructor_declaration
1861           {
1862                 Report.Error (526, GetLocation ($1), "Interfaces cannot contain contructors");
1863           }
1864         | type_declaration
1865           {
1866                 Report.Error (524, GetLocation ($1), "Interfaces cannot declare classes, structs, interfaces, delegates, or enumerations");
1867           }
1868         ;
1869
1870 operator_declaration
1871         : opt_attributes opt_modifiers operator_declarator 
1872           {
1873           }
1874           operator_body
1875           {
1876                 if ($3 == null)
1877                         break;
1878
1879                 OperatorDeclaration decl = (OperatorDeclaration) $3;
1880                 Operator op = new Operator (
1881                         current_class, decl.optype, decl.ret_type, (int) $2, 
1882                         current_local_parameters,
1883                         (ToplevelBlock) $5, (Attributes) $1, decl.location);
1884
1885                 if (RootContext.Documentation != null) {
1886                         op.DocComment = tmpComment;
1887                         Lexer.doc_state = XmlCommentState.Allowed;
1888                 }
1889
1890                 // Note again, checking is done in semantic analysis
1891                 current_container.AddOperator (op);
1892
1893                 current_local_parameters = null;
1894           }
1895         ;
1896
1897 operator_body 
1898         : block
1899         | SEMICOLON { $$ = null; }
1900         ; 
1901
1902 operator_declarator
1903         : type OPERATOR overloadable_operator OPEN_PARENS
1904           {
1905                 params_modifiers_not_allowed = true;
1906           }
1907           opt_parameter_list_no_mod CLOSE_PARENS
1908           {
1909                 params_modifiers_not_allowed = false;
1910
1911                 Location loc = (Location) $2;
1912                 Operator.OpType op = (Operator.OpType) $3;
1913                 current_local_parameters = (Parameters)$6;
1914                 
1915                 int p_count = current_local_parameters.Count;
1916                 if (p_count == 1) {
1917                         if (op == Operator.OpType.Addition)
1918                                 op = Operator.OpType.UnaryPlus;
1919                         else if (op == Operator.OpType.Subtraction)
1920                                 op = Operator.OpType.UnaryNegation;
1921                 }
1922                 
1923                 if (IsUnaryOperator (op)) {
1924                         if (p_count == 2) {
1925                                 Report.Error (1020, loc, "Overloadable binary operator expected");
1926                         } else if (p_count != 1) {
1927                                 Report.Error (1535, loc, "Overloaded unary operator `{0}' takes one parameter",
1928                                         Operator.GetName (op));
1929                         }
1930                 } else {
1931                         if (p_count > 2) {
1932                                 Report.Error (1534, loc, "Overloaded binary operator `{0}' takes two parameters",
1933                                         Operator.GetName (op));
1934                         } else if (p_count != 2) {
1935                                 Report.Error (1019, loc, "Overloadable unary operator expected");
1936                         }
1937                 }
1938                 
1939                 if (RootContext.Documentation != null) {
1940                         tmpComment = Lexer.consume_doc_comment ();
1941                         Lexer.doc_state = XmlCommentState.NotAllowed;
1942                 }
1943
1944                 $$ = new OperatorDeclaration (op, (FullNamedExpression) $1, loc);
1945           }
1946         | conversion_operator_declarator
1947         ;
1948
1949 overloadable_operator
1950 // Unary operators:
1951         : BANG   { $$ = Operator.OpType.LogicalNot; }
1952         | TILDE  { $$ = Operator.OpType.OnesComplement; }  
1953         | OP_INC { $$ = Operator.OpType.Increment; }
1954         | OP_DEC { $$ = Operator.OpType.Decrement; }
1955         | TRUE   { $$ = Operator.OpType.True; }
1956         | FALSE  { $$ = Operator.OpType.False; }
1957 // Unary and binary:
1958         | PLUS { $$ = Operator.OpType.Addition; }
1959         | MINUS { $$ = Operator.OpType.Subtraction; }
1960 // Binary:
1961         | STAR { $$ = Operator.OpType.Multiply; }
1962         | DIV {  $$ = Operator.OpType.Division; }
1963         | PERCENT { $$ = Operator.OpType.Modulus; }
1964         | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
1965         | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
1966         | CARRET { $$ = Operator.OpType.ExclusiveOr; }
1967         | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
1968         | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
1969         | OP_EQ { $$ = Operator.OpType.Equality; }
1970         | OP_NE { $$ = Operator.OpType.Inequality; }
1971         | OP_GT { $$ = Operator.OpType.GreaterThan; }
1972         | OP_LT { $$ = Operator.OpType.LessThan; }
1973         | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
1974         | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
1975         ;
1976
1977 conversion_operator_declarator
1978         : IMPLICIT OPERATOR type OPEN_PARENS
1979           {
1980                 params_modifiers_not_allowed = true;
1981           }
1982           opt_parameter_list_no_mod CLOSE_PARENS
1983           {
1984                 params_modifiers_not_allowed = false;
1985
1986                 Location loc = (Location) $2;
1987                 current_local_parameters = (Parameters)$6;  
1988                   
1989                 if (RootContext.Documentation != null) {
1990                         tmpComment = Lexer.consume_doc_comment ();
1991                         Lexer.doc_state = XmlCommentState.NotAllowed;
1992                 }
1993
1994                 $$ = new OperatorDeclaration (Operator.OpType.Implicit, (FullNamedExpression) $3, loc);
1995           }
1996         | EXPLICIT OPERATOR type OPEN_PARENS
1997           {
1998                 params_modifiers_not_allowed = true;
1999           }
2000           opt_parameter_list_no_mod CLOSE_PARENS
2001           {
2002                 params_modifiers_not_allowed = false;
2003                 
2004                 Location loc = (Location) $2;
2005                 current_local_parameters = (Parameters)$6;  
2006                   
2007                 if (RootContext.Documentation != null) {
2008                         tmpComment = Lexer.consume_doc_comment ();
2009                         Lexer.doc_state = XmlCommentState.NotAllowed;
2010                 }
2011
2012                 $$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc);
2013           }
2014         | IMPLICIT error 
2015           {
2016                 syntax_error ((Location) $1, "'operator' expected");
2017           }
2018         | EXPLICIT error 
2019           {
2020                 syntax_error ((Location) $1, "'operator' expected");
2021           }
2022         ;
2023
2024 constructor_declaration
2025         : opt_attributes
2026           opt_modifiers
2027           constructor_declarator
2028           constructor_body
2029           { 
2030                 Constructor c = (Constructor) $3;
2031                 c.Block = (ToplevelBlock) $4;
2032                 c.OptAttributes = (Attributes) $1;
2033                 int mods = (int) $2;
2034                 
2035                 if (RootContext.Documentation != null)
2036                         c.DocComment = ConsumeStoredComment ();
2037
2038                 if ((mods & Modifiers.STATIC) != 0 && c.Name == current_container.MemberName.Name) {
2039                         if ((mods & Modifiers.Accessibility) != 0){
2040                                 Report.Error (515, c.Location,
2041                                         "`{0}': static constructor cannot have an access modifier",
2042                                         c.GetSignatureForError ());
2043                         }
2044         
2045                         if (c.Initializer != null){
2046                                 Report.Error (514, c.Location,
2047                                         "`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
2048                                         c.GetSignatureForError ());
2049                         }
2050                 }
2051
2052                 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, mods, Modifiers.PRIVATE, c.Location);
2053                 current_container.AddConstructor (c);
2054
2055                 current_local_parameters = null;
2056                 if (RootContext.Documentation != null)
2057                         Lexer.doc_state = XmlCommentState.Allowed;
2058           }
2059         ;
2060
2061 constructor_declarator
2062         : constructor_header
2063           {
2064                 $$ = $1;
2065           }
2066         | constructor_header constructor_initializer
2067           {
2068                 ((Constructor)$1).Initializer = (ConstructorInitializer) $2;
2069                 $$ = $1;
2070           }
2071         ;
2072
2073 constructor_header
2074         : IDENTIFIER
2075           {
2076                 if (RootContext.Documentation != null) {
2077                         tmpComment = Lexer.consume_doc_comment ();
2078                         Lexer.doc_state = XmlCommentState.Allowed;
2079                 }
2080           }
2081           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2082           {
2083                 LocatedToken lt = (LocatedToken) $1;
2084                 current_local_parameters = (Parameters) $4;
2085                 current_block = new ToplevelBlock (null, current_local_parameters, null, lt.Location);
2086
2087                 $$ = new Constructor (current_class, lt.Value, 0, current_local_parameters,
2088                                       null, lt.Location);
2089           }
2090         ;
2091
2092 constructor_body
2093         : block_prepared
2094         | SEMICOLON             { current_block = null; $$ = null; }
2095         ;
2096
2097 constructor_initializer
2098         : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
2099           {
2100                 $$ = new ConstructorBaseInitializer ((ArrayList) $4, (Location) $2);
2101           }
2102         | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
2103           {
2104                 $$ = new ConstructorThisInitializer ((ArrayList) $4, (Location) $2);
2105           }
2106         | COLON error {
2107                 Report.Error (1018, (Location) $1, "Keyword this or base expected");
2108                 $$ = null;
2109           }
2110         ;
2111
2112 destructor_declaration
2113         : opt_attributes opt_modifiers TILDE 
2114           {
2115                 if (RootContext.Documentation != null) {
2116                         tmpComment = Lexer.consume_doc_comment ();
2117                         Lexer.doc_state = XmlCommentState.NotAllowed;
2118                 }
2119           }
2120           IDENTIFIER OPEN_PARENS CLOSE_PARENS block
2121           {
2122                 LocatedToken lt = (LocatedToken) $5;
2123                 if (lt.Value != current_container.MemberName.Name){
2124                         Report.Error (574, lt.Location, "Name of destructor must match name of class");
2125                 } else if (current_container.Kind != Kind.Class){
2126                         Report.Error (575, lt.Location, "Only class types can contain destructor");
2127                 } else {
2128                         Method d = new Destructor (
2129                                 current_class, TypeManager.system_void_expr, (int) $2, "Finalize", 
2130                                 Parameters.EmptyReadOnlyParameters, (Attributes) $1, lt.Location);
2131                         if (RootContext.Documentation != null)
2132                                 d.DocComment = ConsumeStoredComment ();
2133                   
2134                         d.Block = (ToplevelBlock) $8;
2135                         current_container.AddMethod (d);
2136                 }
2137           }
2138         ;
2139
2140 event_declaration
2141         : opt_attributes
2142           opt_modifiers
2143           EVENT type variable_declarators SEMICOLON
2144           {
2145                 current_array_type = null;
2146                 foreach (VariableDeclaration var in (ArrayList) $5) {
2147
2148                         MemberName name = new MemberName (var.identifier,
2149                                 var.Location);
2150
2151                         EventField e = new EventField (
2152                                 current_class, (FullNamedExpression) $4, (int) $2, name,
2153                                 (Attributes) $1);
2154                                 
2155                         if (var.expression_or_array_initializer != null) {
2156                                 if (current_container.Kind == Kind.Interface) {
2157                                         Report.Error (68, e.Location, "`{0}': event in interface cannot have initializer", e.GetSignatureForError ());
2158                                 }
2159
2160                                 e.Initializer = var.expression_or_array_initializer;
2161                         }
2162
2163                         current_container.AddEvent (e);
2164
2165                         if (RootContext.Documentation != null) {
2166                                 e.DocComment = Lexer.consume_doc_comment ();
2167                                 Lexer.doc_state = XmlCommentState.Allowed;
2168                         }
2169                 }
2170           }
2171         | opt_attributes
2172           opt_modifiers
2173           EVENT type namespace_or_type_name
2174           OPEN_BRACE
2175           {
2176                 implicit_value_parameter_type = (FullNamedExpression) $4;  
2177                 current_local_parameters = new Parameters (
2178                         new Parameter (implicit_value_parameter_type, "value", 
2179                         Parameter.Modifier.NONE, null, GetLocation ($3)));
2180
2181                 lexer.EventParsing = true;
2182           }
2183           event_accessor_declarations
2184           {
2185                 lexer.EventParsing = false;  
2186           }
2187           CLOSE_BRACE
2188           {
2189                 MemberName name = (MemberName) $5;
2190                 
2191                 if (current_container.Kind == Kind.Interface) {
2192                         Report.Error (69, (Location) $3, "Event in interface cannot have add or remove accessors");
2193                 }
2194
2195                 if ($8 == null){
2196                         Report.Error (65, (Location) $3, "`{0}.{1}': event property must have both add and remove accessors",
2197                                 current_container.Name, name.GetSignatureForError ());
2198                         $$ = null;
2199                 } else {
2200                         Accessors accessors = (Accessors) $8;
2201                         
2202                         if (name.TypeArguments != null)
2203                                 syntax_error (lexer.Location, "an event can't have type arguments");
2204
2205                         if (accessors.get_or_add == null || accessors.set_or_remove == null)
2206                                 // CS0073 is already reported, so no CS0065 here.
2207                                 $$ = null;
2208                         else {
2209                                 Event e = new EventProperty (
2210                                         current_class, (FullNamedExpression) $4, (int) $2, name,
2211                                         (Attributes) $1, accessors.get_or_add, accessors.set_or_remove);
2212                                 if (RootContext.Documentation != null) {
2213                                         e.DocComment = Lexer.consume_doc_comment ();
2214                                         Lexer.doc_state = XmlCommentState.Allowed;
2215                                 }
2216
2217                                 current_container.AddEvent (e);
2218                                 implicit_value_parameter_type = null;
2219                         }
2220                 }
2221                 current_local_parameters = null;
2222           }
2223         | opt_attributes opt_modifiers EVENT type namespace_or_type_name error {
2224                 MemberName mn = (MemberName) $5;
2225
2226                 if (mn.Left != null)
2227                         Report.Error (71, mn.Location, "An explicit interface implementation of an event must use property syntax");
2228                 else 
2229                         Report.Error (71, mn.Location, "Event declaration should use property syntax");
2230
2231                 if (RootContext.Documentation != null)
2232                         Lexer.doc_state = XmlCommentState.Allowed;
2233           }
2234         ;
2235
2236 event_accessor_declarations
2237         : add_accessor_declaration remove_accessor_declaration
2238           {
2239                 $$ = new Accessors ((Accessor) $1, (Accessor) $2);
2240           }
2241         | remove_accessor_declaration add_accessor_declaration
2242           {
2243                 Accessors accessors = new Accessors ((Accessor) $2, (Accessor) $1);
2244                 accessors.declared_in_reverse = true;
2245                 $$ = accessors;
2246           }     
2247         | add_accessor_declaration  { $$ = null; } 
2248         | remove_accessor_declaration { $$ = null; } 
2249         | error
2250           { 
2251                 Report.Error (1055, GetLocation ($1), "An add or remove accessor expected");
2252                 $$ = null;
2253           }
2254         | { $$ = null; }
2255         ;
2256
2257 add_accessor_declaration
2258         : opt_attributes ADD
2259           {
2260                 lexer.EventParsing = false;
2261           }
2262           block
2263           {
2264                 Accessor accessor = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, null, (Location) $2);
2265                 lexer.EventParsing = true;
2266                 $$ = accessor;
2267           }
2268         | opt_attributes ADD error {
2269                 Report.Error (73, (Location) $2, "An add or remove accessor must have a body");
2270                 $$ = null;
2271           }
2272         | opt_attributes modifiers ADD {
2273                 Report.Error (1609, (Location) $3, "Modifiers cannot be placed on event accessor declarations");
2274                 $$ = null;
2275           }
2276         ;
2277
2278 remove_accessor_declaration
2279         : opt_attributes REMOVE
2280           {
2281                 lexer.EventParsing = false;
2282           }
2283           block
2284           {
2285                 $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, null, (Location) $2);
2286                 lexer.EventParsing = true;
2287           }
2288         | opt_attributes REMOVE error {
2289                 Report.Error (73, (Location) $2, "An add or remove accessor must have a body");
2290                 $$ = null;
2291           }
2292         | opt_attributes modifiers REMOVE {
2293                 Report.Error (1609, (Location) $3, "Modifiers cannot be placed on event accessor declarations");
2294                 $$ = null;
2295           }
2296         ;
2297
2298 indexer_declaration
2299         : opt_attributes opt_modifiers indexer_declarator 
2300           OPEN_BRACE
2301           {
2302                 IndexerDeclaration decl = (IndexerDeclaration) $3;
2303
2304                 implicit_value_parameter_type = decl.type;
2305                 
2306                 lexer.PropertyParsing = true;
2307                 parsing_indexer  = true;
2308                 
2309                 indexer_parameters = decl.param_list;
2310           }
2311           accessor_declarations 
2312           {
2313                   lexer.PropertyParsing = false;
2314                   has_get = has_set = false;
2315                   parsing_indexer  = false;
2316           }
2317           CLOSE_BRACE
2318           { 
2319                 // The signature is computed from the signature of the indexer.  Look
2320                 // at section 3.6 on the spec
2321                 Indexer indexer;
2322                 IndexerDeclaration decl = (IndexerDeclaration) $3;
2323                 Location loc = decl.location;
2324                 Accessors accessors = (Accessors) $6;
2325                 Accessor get_block = accessors != null ? accessors.get_or_add : null;
2326                 Accessor set_block = accessors != null ? accessors.set_or_remove : null;
2327                 bool order = accessors != null ? accessors.declared_in_reverse : false;
2328
2329                 MemberName name;
2330                 if (decl.interface_type != null)
2331                         name = new MemberName (decl.interface_type, TypeContainer.DefaultIndexerName, loc);
2332                 else
2333                         name = new MemberName (TypeContainer.DefaultIndexerName, loc);
2334
2335                 indexer = new Indexer (current_class, decl.type, name,
2336                                        (int) $2, decl.param_list, (Attributes) $1,
2337                                        get_block, set_block, order);
2338                                        
2339                 if (decl.type == TypeManager.system_void_expr)
2340                         Report.Error (620, loc, "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ());
2341                         
2342                 if (accessors == null)
2343                         Report.Error (548, indexer.Location, "`{0}': property or indexer must have at least one accessor", indexer.GetSignatureForError ());
2344
2345                 if (current_container.Kind == Kind.Interface) {
2346                         if (indexer.Get.Block != null)
2347                                 Report.Error (531, indexer.Location, "`{0}.get': interface members cannot have a definition", indexer.GetSignatureForError ());
2348
2349                         if (indexer.Set.Block != null)
2350                                 Report.Error (531, indexer.Location, "`{0}.set': interface members cannot have a definition", indexer.GetSignatureForError ());
2351                 }
2352
2353                 if (RootContext.Documentation != null)
2354                         indexer.DocComment = ConsumeStoredComment ();
2355
2356                 current_container.AddIndexer (indexer);
2357                 
2358                 current_local_parameters = null;
2359                 implicit_value_parameter_type = null;
2360                 indexer_parameters = null;
2361           }
2362         ;
2363
2364 indexer_declarator
2365         : type THIS OPEN_BRACKET opt_parameter_list_no_mod CLOSE_BRACKET
2366           {
2367                 Parameters pars = (Parameters) $4;
2368                 if (pars.IsEmpty){
2369                         Report.Error (1551, (Location) $2, "Indexers must have at least one parameter");
2370                 }
2371                 if (RootContext.Documentation != null) {
2372                         tmpComment = Lexer.consume_doc_comment ();
2373                         Lexer.doc_state = XmlCommentState.Allowed;
2374                 }
2375
2376                 $$ = new IndexerDeclaration ((FullNamedExpression) $1, null, pars, (Location) $2);
2377           }
2378         | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
2379           {
2380                 Parameters pars = (Parameters) $6;
2381                 if (pars.IsEmpty){
2382                         Report.Error (1551, (Location) $4, "Indexers must have at least one parameter");
2383                 }
2384
2385                 MemberName name = (MemberName) $2;
2386                 $$ = new IndexerDeclaration ((FullNamedExpression) $1, name, pars, (Location) $4);
2387
2388                 if (RootContext.Documentation != null) {
2389                         tmpComment = Lexer.consume_doc_comment ();
2390                         Lexer.doc_state = XmlCommentState.Allowed;
2391                 }
2392           }
2393         ;
2394
2395 enum_declaration
2396         : opt_attributes
2397           opt_modifiers
2398           ENUM type_name
2399           opt_enum_base {
2400                 if (RootContext.Documentation != null)
2401                         enumTypeComment = Lexer.consume_doc_comment ();
2402           }
2403           enum_body
2404           opt_semicolon
2405           {
2406                 MemberName name = (MemberName) $4;
2407                 if (name.IsGeneric) {
2408                         Report.Error (1675, name.Location, "Enums cannot have type parameters");
2409                 }
2410
2411                 name = MakeName (name);
2412                 Enum e = new Enum (current_namespace, current_class, (TypeExpr) $5, (int) $2,
2413                                    name, (Attributes) $1);
2414                 
2415                 if (RootContext.Documentation != null)
2416                         e.DocComment = enumTypeComment;
2417
2418
2419                 EnumMember em = null;
2420                 foreach (VariableDeclaration ev in (ArrayList) $7) {
2421                         em = new EnumMember (
2422                                 e, em, ev.identifier, (Expression) ev.expression_or_array_initializer,
2423                                 ev.OptAttributes, ev.Location);
2424
2425 //                      if (RootContext.Documentation != null)
2426                                 em.DocComment = ev.DocComment;
2427
2428                         e.AddEnumMember (em);
2429                 }
2430                 if (RootContext.EvalMode)
2431                         undo.AddTypeContainer (current_container, e);
2432
2433                 current_container.AddTypeContainer (e);
2434
2435                 $$ = e;
2436
2437           }
2438         ;
2439
2440 opt_enum_base
2441         : /* empty */           { $$ = TypeManager.system_int32_expr; }
2442         | COLON type
2443          {
2444                 if ($2 != TypeManager.system_int32_expr && $2 != TypeManager.system_uint32_expr &&
2445                         $2 != TypeManager.system_int64_expr && $2 != TypeManager.system_uint64_expr &&
2446                         $2 != TypeManager.system_int16_expr && $2 != TypeManager.system_uint16_expr &&
2447                         $2 != TypeManager.system_byte_expr && $2 != TypeManager.system_sbyte_expr)
2448                         Enum.Error_1008 (GetLocation ($2));
2449          
2450                 $$ = $2;
2451          }
2452         | COLON error
2453          {
2454                 Error_TypeExpected (lexer.Location);
2455          }
2456         ;
2457
2458 enum_body
2459         : OPEN_BRACE
2460           {
2461                 if (RootContext.Documentation != null)
2462                         Lexer.doc_state = XmlCommentState.Allowed;
2463           }
2464           opt_enum_member_declarations
2465           {
2466                 // here will be evaluated after CLOSE_BLACE is consumed.
2467                 if (RootContext.Documentation != null)
2468                         Lexer.doc_state = XmlCommentState.Allowed;
2469           }
2470           CLOSE_BRACE
2471           {
2472                 $$ = $3;
2473           }
2474         ;
2475
2476 opt_enum_member_declarations
2477         : /* empty */                   { $$ = new ArrayList (4); }
2478         | enum_member_declarations opt_comma { $$ = $1; }
2479         ;
2480
2481 enum_member_declarations
2482         : enum_member_declaration 
2483           {
2484                 ArrayList l = new ArrayList (4);
2485
2486                 l.Add ($1);
2487                 $$ = l;
2488           }
2489         | enum_member_declarations COMMA enum_member_declaration
2490           {
2491                 ArrayList l = (ArrayList) $1;
2492
2493                 l.Add ($3);
2494
2495                 $$ = l;
2496           }
2497         ;
2498
2499 enum_member_declaration
2500         : opt_attributes IDENTIFIER 
2501           {
2502                 VariableDeclaration vd = new VariableDeclaration (
2503                         (LocatedToken) $2, null, (Attributes) $1);
2504
2505                 if (RootContext.Documentation != null) {
2506                         vd.DocComment = Lexer.consume_doc_comment ();
2507                         Lexer.doc_state = XmlCommentState.Allowed;
2508                 }
2509
2510                 $$ = vd;
2511           }
2512         | opt_attributes IDENTIFIER
2513           {
2514                 if (RootContext.Documentation != null) {
2515                         tmpComment = Lexer.consume_doc_comment ();
2516                         Lexer.doc_state = XmlCommentState.NotAllowed;
2517                 }
2518           }
2519           ASSIGN constant_expression
2520           { 
2521                 VariableDeclaration vd = new VariableDeclaration (
2522                         (LocatedToken) $2, $5, (Attributes) $1);
2523
2524                 if (RootContext.Documentation != null)
2525                         vd.DocComment = ConsumeStoredComment ();
2526
2527                 $$ = vd;
2528           }
2529         ;
2530
2531 delegate_declaration
2532         : opt_attributes
2533           opt_modifiers
2534           DELEGATE
2535           type type_name
2536           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2537           {
2538                 MemberName name = MakeName ((MemberName) $5);
2539                 Parameters p = (Parameters) $7;
2540
2541                 Delegate del = new Delegate (current_namespace, current_class, (FullNamedExpression) $4,
2542                                              (int) $2, name, p, (Attributes) $1);
2543
2544                 if (RootContext.Documentation != null) {
2545                         del.DocComment = Lexer.consume_doc_comment ();
2546                         Lexer.doc_state = XmlCommentState.Allowed;
2547                 }
2548
2549                 current_container.AddDelegate (del);
2550                 current_delegate = del;
2551                 lexer.ConstraintsParsing = true;
2552           }
2553           opt_type_parameter_constraints_clauses
2554           {
2555                 lexer.ConstraintsParsing = false;
2556           }
2557           SEMICOLON
2558           {
2559                 current_delegate.SetParameterInfo ((ArrayList) $10);
2560                 $$ = current_delegate;
2561
2562                 current_delegate = null;
2563           }
2564         ;
2565
2566 opt_nullable
2567         : /* empty */
2568           {
2569                 lexer.CheckNullable (false);
2570                 $$ = false;
2571           }
2572         | INTERR
2573           {
2574                 // FIXME: A hack with parsing conditional operator as nullable type
2575                 //if (RootContext.Version < LanguageVersion.ISO_2)
2576                 //      Report.FeatureIsNotAvailable (lexer.Location, "nullable types");
2577                         
2578                 lexer.CheckNullable (true);
2579                 $$ = true;
2580           }
2581         ;
2582
2583 namespace_or_type_name
2584         : IDENTIFIER opt_type_argument_list
2585           {
2586                 LocatedToken lt = (LocatedToken) $1;
2587                 $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location);
2588           }
2589         | IDENTIFIER DOUBLE_COLON IDENTIFIER opt_type_argument_list {
2590                 LocatedToken lt1 = (LocatedToken) $1;
2591                 LocatedToken lt2 = (LocatedToken) $3;
2592                 if (RootContext.Version == LanguageVersion.ISO_1)
2593                         Report.FeatureIsNotAvailable (lt1.Location, "namespace alias qualifier");
2594                 
2595                 $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $4, lt1.Location);
2596           }
2597         | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list {
2598                 LocatedToken lt = (LocatedToken) $3;
2599                 $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location);
2600           }
2601         ;
2602
2603 member_name
2604         : IDENTIFIER opt_type_parameter_list
2605           {
2606                 LocatedToken lt = (LocatedToken) $1;
2607                 $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location);
2608           }
2609         | namespace_or_type_name DOT IDENTIFIER opt_type_parameter_list 
2610           {
2611                 LocatedToken lt = (LocatedToken) $3;
2612                 $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location);
2613           }
2614         ;
2615
2616 type_name
2617         : IDENTIFIER opt_type_parameter_list
2618           {
2619                 LocatedToken lt = (LocatedToken) $1;
2620                 $$ = new MemberName (lt.Value, (TypeArguments)$2, lt.Location);   
2621           }
2622         ;
2623
2624 //
2625 // Generics arguments  (any type, without attributes)
2626 //
2627
2628 opt_type_argument_list
2629         : /* empty */                { $$ = null; } 
2630         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2631           {
2632                 if (RootContext.Version < LanguageVersion.ISO_2)
2633                         Report.FeatureIsNotAvailable (GetLocation ($1), "generics");      
2634           
2635                 $$ = $2;
2636           }
2637         | OP_GENERICS_LT error
2638           {
2639                 Error_TypeExpected (lexer.Location);
2640           }
2641         ;
2642
2643 //
2644 // Generics parameters (identifiers only, with attributes), used in type, method declarations
2645 //
2646
2647 opt_type_parameter_list
2648         : /* empty */                { $$ = null; } 
2649         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2650           {
2651                 if (RootContext.Version < LanguageVersion.ISO_2)
2652                         Report.FeatureIsNotAvailable (GetLocation ($1), "generics");
2653           
2654                 $$ = $2;
2655           }
2656         | OP_GENERICS_LT error
2657           {
2658                 Error_TypeExpected (lexer.Location);
2659           }
2660         ;
2661
2662 type_arguments
2663         : type_argument
2664           {
2665                 TypeArguments type_args = new TypeArguments (lexer.Location);
2666                 type_args.Add ((Expression) $1);
2667                 $$ = type_args;
2668           }
2669         | type_arguments COMMA type_argument
2670           {
2671                 TypeArguments type_args = (TypeArguments) $1;
2672                 type_args.Add ((Expression) $3);
2673                 $$ = type_args;
2674           }       
2675         ;
2676
2677 type_argument
2678         : type
2679           {
2680                 $$ = $1;
2681           }
2682         | attribute_sections type
2683           {
2684                 SimpleName sn = $2 as SimpleName;
2685                 if (sn == null)
2686                         Error_TypeExpected (GetLocation ($2));
2687                 else
2688                         $2 = new TypeParameterName (sn.Name, (Attributes) $1, lexer.Location);
2689                 $$ = $2;          
2690           }
2691         ;
2692         
2693 /* 
2694  * Before you think of adding a return_type, notice that we have been
2695  * using two rules in the places where it matters (one rule using type
2696  * and another identical one that uses VOID as the return type).  This
2697  * gets rid of a shift/reduce couple
2698  */
2699 type
2700         : namespace_or_type_name opt_nullable
2701           {
2702                 MemberName name = (MemberName) $1;
2703
2704                 if ((bool) $2) {
2705                         $$ = new ComposedCast (name.GetTypeExpression (), "?", lexer.Location);
2706                 } else {
2707                         if (name.Left == null && name.Name == "var" &&
2708                             (RootContext.Version > LanguageVersion.ISO_2 || RootContext.Version == LanguageVersion.Default_MCS))
2709                                 $$ = new VarExpr (name.Location);
2710                         else
2711                                 $$ = name.GetTypeExpression ();
2712                 }
2713           }
2714         | builtin_types opt_nullable
2715           {
2716                 if ((bool) $2)
2717                         $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location);
2718           }
2719         | array_type
2720         | pointer_type
2721         ;
2722
2723 pointer_type
2724         : type STAR
2725           {
2726                 //
2727                 // Note that here only unmanaged types are allowed but we
2728                 // can't perform checks during this phase - we do it during
2729                 // semantic analysis.
2730                 //
2731                 $$ = new ComposedCast ((FullNamedExpression) $1, "*", Lexer.Location);
2732           }
2733         | VOID STAR
2734           {
2735                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1);
2736           }
2737         ;
2738
2739 non_expression_type
2740         : builtin_types opt_nullable
2741           {
2742                 if ((bool) $2)
2743                         $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location);
2744           }
2745         | non_expression_type rank_specifier
2746           {
2747                 Location loc = GetLocation ($1);
2748                 if (loc.IsNull)
2749                         loc = lexer.Location;
2750                 $$ = new ComposedCast ((FullNamedExpression) $1, (string) $2, loc);
2751           }
2752         | non_expression_type STAR
2753           {
2754                 Location loc = GetLocation ($1);
2755                 if (loc.IsNull)
2756                         loc = lexer.Location;
2757                 $$ = new ComposedCast ((FullNamedExpression) $1, "*", loc);
2758           }
2759         
2760         //
2761         // We need this because the parser will happily go and reduce IDENTIFIER STAR
2762         // through this different path
2763         //
2764         | multiplicative_expression STAR 
2765           {
2766                 FullNamedExpression e = $1 as FullNamedExpression;
2767                 if (e != null)
2768                         $$ = new ComposedCast (e, "*");
2769                 else
2770                         Error_TypeExpected (GetLocation ($1));
2771           }
2772         ;
2773
2774 type_list
2775         : base_type_name
2776           {
2777                 ArrayList types = new ArrayList (2);
2778                 types.Add ($1);
2779                 $$ = types;
2780           }
2781         | type_list COMMA base_type_name
2782           {
2783                 ArrayList types = (ArrayList) $1;
2784                 types.Add ($3);
2785                 $$ = types;
2786           }
2787         ;
2788
2789 base_type_name
2790         : type
2791           {
2792                 if ($1 is ComposedCast)
2793                         Report.Error (1521, GetLocation ($1), "Invalid base type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
2794                 $$ = $1;
2795           }
2796         | error
2797           {
2798                 Error_TypeExpected (lexer.Location);
2799           }
2800         ;
2801         
2802 /*
2803  * replaces all the productions for isolating the various
2804  * simple types, but we need this to reuse it easily in local_variable_type
2805  */
2806 builtin_types
2807         : OBJECT        { $$ = TypeManager.system_object_expr; }
2808         | STRING        { $$ = TypeManager.system_string_expr; }
2809         | BOOL          { $$ = TypeManager.system_boolean_expr; }
2810         | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
2811         | FLOAT         { $$ = TypeManager.system_single_expr; }
2812         | DOUBLE        { $$ = TypeManager.system_double_expr; }
2813         | VOID          { $$ = TypeManager.system_void_expr; }  
2814         | integral_type
2815         ;
2816
2817 integral_type
2818         : SBYTE         { $$ = TypeManager.system_sbyte_expr; }
2819         | BYTE          { $$ = TypeManager.system_byte_expr; }
2820         | SHORT         { $$ = TypeManager.system_int16_expr; }
2821         | USHORT        { $$ = TypeManager.system_uint16_expr; }
2822         | INT           { $$ = TypeManager.system_int32_expr; }
2823         | UINT          { $$ = TypeManager.system_uint32_expr; }
2824         | LONG          { $$ = TypeManager.system_int64_expr; }
2825         | ULONG         { $$ = TypeManager.system_uint64_expr; }
2826         | CHAR          { $$ = TypeManager.system_char_expr; }
2827         ;
2828
2829 array_type
2830         : type rank_specifiers
2831           {
2832                 string rank_specifiers = (string) $2;
2833                 $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, rank_specifiers);
2834           }
2835         ;
2836
2837 //
2838 // Expressions, section 7.5
2839 //
2840 primary_expression
2841         : literal
2842           {
2843                 // 7.5.1: Literals
2844           }
2845         | type_name
2846           {
2847                 MemberName mn = (MemberName) $1;
2848                 $$ = mn.GetTypeExpression ();
2849           }
2850         | IDENTIFIER DOUBLE_COLON IDENTIFIER opt_type_argument_list
2851           {
2852                 LocatedToken lt1 = (LocatedToken) $1;
2853                 LocatedToken lt2 = (LocatedToken) $3;
2854                 if (RootContext.Version == LanguageVersion.ISO_1)
2855                         Report.FeatureIsNotAvailable (lt1.Location, "namespace alias qualifier");
2856
2857                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $4, lt1.Location);
2858           }
2859         | parenthesized_expression
2860         | default_value_expression
2861         | member_access
2862         | invocation_expression
2863         | element_access
2864         | this_access
2865         | base_access
2866         | post_increment_expression
2867         | post_decrement_expression
2868         | new_expression
2869         | typeof_expression
2870         | sizeof_expression
2871         | checked_expression
2872         | unchecked_expression
2873         | pointer_member_access
2874         | anonymous_method_expression
2875         ;
2876
2877 literal
2878         : boolean_literal
2879         | integer_literal
2880         | real_literal
2881         | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value, lexer.Location); }
2882         | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value, lexer.Location); } 
2883         | NULL                  { $$ = new NullLiteral (lexer.Location); }
2884         ;
2885
2886 real_literal
2887         : LITERAL_FLOAT         { $$ = new FloatLiteral ((float) lexer.Value, lexer.Location); }
2888         | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value, lexer.Location); }
2889         | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value, lexer.Location); }
2890         ;
2891
2892 integer_literal
2893         : LITERAL_INTEGER       { 
2894                 object v = lexer.Value;
2895
2896                 if (v is int){
2897                         $$ = new IntLiteral ((int) v, lexer.Location);
2898                 } else if (v is uint)
2899                         $$ = new UIntLiteral ((UInt32) v, lexer.Location);
2900                 else if (v is long)
2901                         $$ = new LongLiteral ((Int64) v, lexer.Location);
2902                 else if (v is ulong)
2903                         $$ = new ULongLiteral ((UInt64) v, lexer.Location);
2904                 else
2905                         Console.WriteLine ("OOPS.  Unexpected result from scanner");
2906           }
2907         ;
2908
2909 boolean_literal
2910         : TRUE                  { $$ = new BoolLiteral (true, lexer.Location); }
2911         | FALSE                 { $$ = new BoolLiteral (false, lexer.Location); }
2912         ;
2913
2914 parenthesized_expression_0
2915         : OPEN_PARENS expression CLOSE_PARENS
2916           {
2917                 $$ = $2;
2918                 lexer.Deambiguate_CloseParens ($$);
2919                 // After this, the next token returned is one of
2920                 // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST (CLOSE_PARENS), CLOSE_PARENS_OPEN_PARENS
2921                 // or CLOSE_PARENS_MINUS.
2922           }
2923         | OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); }
2924         ;
2925
2926 parenthesized_expression
2927         : parenthesized_expression_0 CLOSE_PARENS_NO_CAST
2928           {
2929                 $$ = $1;
2930           }  
2931         | parenthesized_expression_0 CLOSE_PARENS
2932           {
2933                 $$ = $1;
2934           }       
2935         | parenthesized_expression_0 CLOSE_PARENS_MINUS
2936           {
2937                 // If a parenthesized expression is followed by a minus, we need to wrap
2938                 // the expression inside a ParenthesizedExpression for the CS0075 check
2939                 // in Binary.DoResolve().
2940                 $$ = new ParenthesizedExpression ((Expression) $1);
2941           }
2942         ;
2943
2944 member_access
2945         : primary_expression DOT IDENTIFIER opt_type_argument_list
2946           {
2947                 LocatedToken lt = (LocatedToken) $3;
2948                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
2949           }
2950         | predefined_type DOT IDENTIFIER opt_type_argument_list
2951           {
2952                 LocatedToken lt = (LocatedToken) $3;
2953                 // TODO: Location is wrong as some predefined types doesn't hold a location
2954                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
2955           }
2956         ;
2957
2958 predefined_type
2959         : builtin_types
2960         ;
2961
2962 invocation_expression
2963         : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
2964           {
2965                 if ($1 == null)
2966                         Report.Error (1, (Location) $2, "Parse error");
2967                 else
2968                         $$ = new Invocation ((Expression) $1, (ArrayList) $3);
2969           }
2970         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS
2971           {
2972                 $$ = new Invocation ((Expression) $1, new ArrayList ());
2973           }
2974         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression
2975           {
2976                 $$ = new InvocationOrCast ((Expression) $1, (Expression) $3);
2977           }
2978         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS non_simple_argument CLOSE_PARENS
2979           {
2980                 ArrayList args = new ArrayList (1);
2981                 args.Add ($4);
2982                 $$ = new Invocation ((Expression) $1, args);
2983           }
2984         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS argument_list COMMA argument CLOSE_PARENS
2985           {
2986                 ArrayList args = ((ArrayList) $4);
2987                 args.Add ($6);
2988                 $$ = new Invocation ((Expression) $1, args);
2989           }
2990         ;
2991
2992 opt_object_or_collection_initializer
2993         : /* empty */           { $$ = null; }
2994         | object_or_collection_initializer
2995         ;
2996
2997 object_or_collection_initializer
2998         : OPEN_BRACE opt_member_initializer_list CLOSE_BRACE
2999           {
3000                 if ($2 == null)
3001                   $$ = CollectionOrObjectInitializers.Empty;
3002                 else
3003                   $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1));
3004           }
3005         | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE
3006           {
3007                 $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1));
3008           }
3009         ;
3010
3011 opt_member_initializer_list
3012         : /* empty */           { $$ = null; }
3013         | member_initializer_list
3014         {
3015                 $$ = $1;
3016         }
3017         ;
3018
3019 member_initializer_list
3020         : member_initializer
3021           {
3022                 ArrayList a = new ArrayList ();
3023                 a.Add ($1);
3024                 $$ = a;
3025           }
3026         | member_initializer_list COMMA member_initializer
3027           {
3028                 ArrayList a = (ArrayList)$1;
3029                 a.Add ($3);
3030                 $$ = a;
3031           }
3032         ;
3033
3034 member_initializer
3035         : IDENTIFIER ASSIGN initializer_value
3036           {
3037                 LocatedToken lt = $1 as LocatedToken;
3038                 $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
3039           }
3040         | non_assignment_expression
3041           {
3042                 $$ = new CollectionElementInitializer ((Expression)$1);
3043           }
3044         | OPEN_BRACE expression_list CLOSE_BRACE
3045           {
3046                 $$ = new CollectionElementInitializer ((ArrayList)$2, GetLocation ($1));
3047           }
3048         | OPEN_BRACE CLOSE_BRACE
3049           {
3050                 Report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
3051           }       
3052         ;
3053
3054 initializer_value
3055         : expression
3056         | object_or_collection_initializer
3057         ;
3058
3059 opt_argument_list
3060         : /* empty */           { $$ = null; }
3061         | argument_list
3062         ;
3063
3064 argument_list
3065         : argument
3066           { 
3067                 ArrayList list = new ArrayList (4);
3068                 list.Add ($1);
3069                 $$ = list;
3070           }
3071         | argument_list COMMA argument
3072           {
3073                 ArrayList list = (ArrayList) $1;
3074                 list.Add ($3);
3075                 $$ = list;
3076           }
3077         | argument_list COMMA
3078           {
3079                 Report.Error (839, GetLocation ($2), "An argument is missing");
3080                 $$ = null;
3081           }
3082         | COMMA argument
3083           {
3084                 Report.Error (839, GetLocation ($1), "An argument is missing");
3085                 $$ = null;
3086           }
3087         | argument_list error {
3088                 CheckToken (1026, yyToken, "Expected `,' or `)'", GetLocation ($2));
3089                 $$ = null;
3090           }
3091         ;
3092
3093 argument
3094         : expression
3095           {
3096                 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3097           }
3098         | non_simple_argument
3099           {
3100                 $$ = $1;
3101           }
3102         ;
3103
3104 non_simple_argument
3105         : REF variable_reference 
3106           { 
3107                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3108           }
3109         | OUT variable_reference 
3110           { 
3111                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
3112           }
3113         | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
3114           {
3115                 ArrayList list = (ArrayList) $3;
3116                 Argument[] args = new Argument [list.Count];
3117                 list.CopyTo (args, 0);
3118
3119                 Expression expr = new Arglist (args, (Location) $1);
3120                 $$ = new Argument (expr, Argument.AType.Expression);
3121           }
3122         | ARGLIST OPEN_PARENS CLOSE_PARENS
3123           {
3124                 $$ = new Argument (new Arglist ((Location) $1), Argument.AType.Expression);
3125           }       
3126         | ARGLIST
3127           {
3128                 $$ = new Argument (new ArglistAccess ((Location) $1), Argument.AType.ArgList);
3129           }
3130         ;
3131
3132 variable_reference
3133         : expression { note ("section 5.4"); $$ = $1; }
3134         ;
3135
3136 element_access
3137         : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET 
3138           {
3139                 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3);
3140           }
3141         | primary_expression rank_specifiers
3142           {
3143                 // So the super-trick is that primary_expression
3144                 // can only be either a SimpleName or a MemberAccess. 
3145                 // The MemberAccess case arises when you have a fully qualified type-name like :
3146                 // Foo.Bar.Blah i;
3147                 // SimpleName is when you have
3148                 // Blah i;
3149                   
3150                 Expression expr = (Expression) $1;  
3151                 if (expr is ComposedCast){
3152                         $$ = new ComposedCast ((ComposedCast)expr, (string) $2);
3153                 } else if (expr is ATypeNameExpression){
3154                         //
3155                         // So we extract the string corresponding to the SimpleName
3156                         // or MemberAccess
3157                         // 
3158                         $$ = new ComposedCast ((ATypeNameExpression)expr, (string) $2);
3159                 } else {
3160                         Error_ExpectingTypeName (expr);
3161                         $$ = TypeManager.system_object_expr;
3162                 }
3163                 
3164                 current_array_type = (FullNamedExpression)$$;
3165           }
3166         ;
3167
3168 expression_list
3169         : expression
3170           {
3171                 ArrayList list = new ArrayList (4);
3172                 list.Add ($1);
3173                 $$ = list;
3174           }
3175         | expression_list COMMA expression
3176           {
3177                 ArrayList list = (ArrayList) $1;
3178                 list.Add ($3);
3179                 $$ = list;
3180           }
3181         ;
3182
3183 this_access
3184         : THIS
3185           {
3186                 $$ = new This (current_block, (Location) $1);
3187           }
3188         ;
3189
3190 base_access
3191         : BASE DOT IDENTIFIER opt_type_argument_list
3192           {
3193                 LocatedToken lt = (LocatedToken) $3;
3194                 $$ = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location);
3195           }
3196         | BASE OPEN_BRACKET expression_list CLOSE_BRACKET
3197           {
3198                 $$ = new BaseIndexerAccess ((ArrayList) $3, (Location) $1);
3199           }
3200         | BASE error {
3201                 Report.Error (175, (Location) $1, "Use of keyword `base' is not valid in this context");
3202                 $$ = null;
3203           }
3204         ;
3205
3206 post_increment_expression
3207         : primary_expression OP_INC
3208           {
3209                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement,
3210                                        (Expression) $1, (Location) $2);
3211           }
3212         ;
3213
3214 post_decrement_expression
3215         : primary_expression OP_DEC
3216           {
3217                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement,
3218                                        (Expression) $1, (Location) $2);
3219           }
3220         ;
3221
3222 new_expression
3223         : object_or_delegate_creation_expression
3224         | array_creation_expression
3225         | anonymous_type_expression
3226         ;
3227
3228 object_or_delegate_creation_expression
3229         : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer
3230           {
3231                 if ($6 != null) {
3232                         if (RootContext.Version <= LanguageVersion.ISO_2)
3233                                 Report.FeatureIsNotAvailable (GetLocation ($1), "object initializers");
3234                                 
3235                         $$ = new NewInitialize ((Expression) $2, (ArrayList) $4, (CollectionOrObjectInitializers) $6, (Location) $1);
3236                 }
3237                 else
3238                         $$ = new New ((Expression) $2, (ArrayList) $4, (Location) $1);
3239           }
3240         | NEW type object_or_collection_initializer
3241           {
3242                 if (RootContext.Version <= LanguageVersion.ISO_2)
3243                         Report.FeatureIsNotAvailable (GetLocation ($1), "collection initializers");
3244           
3245                 $$ = new NewInitialize ((Expression) $2, null, (CollectionOrObjectInitializers) $3, (Location) $1);
3246           }
3247         ;
3248
3249 array_creation_expression
3250         : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET 
3251           opt_rank_specifier
3252           opt_array_initializer
3253           {
3254                 $$ = new ArrayCreation ((FullNamedExpression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, (Location) $1);
3255           }
3256         | NEW type rank_specifiers array_initializer
3257           {
3258                 $$ = new ArrayCreation ((FullNamedExpression) $2, (string) $3, (ArrayList) $4, (Location) $1);
3259           }
3260         | NEW rank_specifiers array_initializer
3261           {
3262                 $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayList) $3, (Location) $1);
3263           }
3264         | NEW error
3265           {
3266                 Report.Error (1031, (Location) $1, "Type expected");
3267                 $$ = null;
3268           }          
3269         | NEW type error 
3270           {
3271                 Report.Error (1526, (Location) $1, "A new expression requires () or [] after type");
3272                 $$ = null;
3273           }
3274         ;
3275
3276 anonymous_type_expression
3277         : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
3278           {
3279                 if (RootContext.Version <= LanguageVersion.ISO_2)
3280                         Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
3281
3282                 $$ = new AnonymousTypeDeclaration ((ArrayList) $3, current_container, GetLocation ($1));
3283           }
3284         ;
3285
3286 anonymous_type_parameters_opt_comma
3287         : anonymous_type_parameters_opt
3288         | anonymous_type_parameters COMMA
3289         ;
3290
3291 anonymous_type_parameters_opt
3292         : { $$ = null; }
3293         | anonymous_type_parameters
3294         ;
3295
3296 anonymous_type_parameters
3297         : anonymous_type_parameter
3298           {
3299                 ArrayList a = new ArrayList (4);
3300                 a.Add ($1);
3301                 $$ = a;
3302           }
3303         | anonymous_type_parameters COMMA anonymous_type_parameter
3304           {
3305                 ArrayList a = (ArrayList) $1;
3306                 a.Add ($3);
3307                 $$ = a;
3308           }
3309         ;
3310
3311 anonymous_type_parameter
3312         : IDENTIFIER ASSIGN variable_initializer
3313           {
3314                 LocatedToken lt = (LocatedToken)$1;
3315                 $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
3316           }
3317         | IDENTIFIER
3318           {
3319                 LocatedToken lt = (LocatedToken)$1;
3320                 $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
3321                         lt.Value, lt.Location);
3322           }
3323         | BASE DOT IDENTIFIER opt_type_argument_list
3324           {
3325                 LocatedToken lt = (LocatedToken) $3;
3326                 BaseAccess ba = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location);
3327                 $$ = new AnonymousTypeParameter (ba, lt.Value, lt.Location);            
3328           }       
3329         | member_access
3330           {
3331                 MemberAccess ma = (MemberAccess) $1;
3332                 $$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
3333           }
3334         | error
3335           {
3336                 Report.Error (746, lexer.Location, "Invalid anonymous type member declarator. " +
3337                 "Anonymous type members must be a member assignment, simple name or member access expression");
3338           }
3339         ;
3340
3341 opt_rank_specifier
3342         : /* empty */
3343           {
3344                   $$ = "";
3345           }
3346         | rank_specifiers
3347           {
3348                         $$ = $1;
3349           }
3350         ;
3351
3352 opt_rank_specifier_or_nullable
3353         : /* empty */
3354           {
3355                 $$ = string.Empty;
3356           }
3357         | INTERR
3358           {
3359                 if (RootContext.Version < LanguageVersion.ISO_2)
3360                         Report.FeatureIsNotAvailable (lexer.Location, "nullable types");
3361
3362                 $$ = "?";
3363           }
3364         | opt_nullable rank_specifiers
3365           {
3366                 if ((bool) $1)
3367                         $$ = "?" + $2;
3368                 else
3369                         $$ = $2;
3370           }
3371         ;
3372
3373 rank_specifiers
3374         : rank_specifier opt_rank_specifier
3375           {
3376                   $$ = (string) $2 + (string) $1;
3377           }
3378         ;
3379
3380 rank_specifier
3381         : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
3382           {
3383                 $$ = "[" + (string) $2 + "]";
3384           }
3385         ;
3386
3387 opt_dim_separators
3388         : /* empty */
3389           {
3390                 $$ = "";
3391           }
3392         | dim_separators
3393           {
3394                   $$ = $1;
3395           }               
3396         ;
3397
3398 dim_separators
3399         : COMMA
3400           {
3401                 $$ = ",";
3402           }
3403         | dim_separators COMMA
3404           {
3405                 $$ = (string) $1 + ",";
3406           }
3407         ;
3408
3409 opt_array_initializer
3410         : /* empty */
3411           {
3412                 $$ = null;
3413           }
3414         | array_initializer
3415           {
3416                 $$ = $1;
3417           }
3418         ;
3419
3420 array_initializer
3421         : OPEN_BRACE CLOSE_BRACE
3422           {
3423                 ArrayList list = new ArrayList (4);
3424                 $$ = list;
3425           }
3426         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
3427           {
3428                 $$ = (ArrayList) $2;
3429           }
3430         ;
3431
3432 variable_initializer_list
3433         : variable_initializer
3434           {
3435                 ArrayList list = new ArrayList (4);
3436                 list.Add ($1);
3437                 $$ = list;
3438           }
3439         | variable_initializer_list COMMA variable_initializer
3440           {
3441                 ArrayList list = (ArrayList) $1;
3442                 list.Add ($3);
3443                 $$ = list;
3444           }
3445         ;
3446
3447 typeof_expression
3448         : TYPEOF
3449       {
3450                 pushed_current_array_type = current_array_type;
3451                 lexer.TypeOfParsing = true;
3452           }
3453           OPEN_PARENS typeof_type_expression CLOSE_PARENS
3454           {
3455                 lexer.TypeOfParsing = false;
3456                 Expression type = (Expression)$4;
3457                 if (type == TypeManager.system_void_expr)
3458                         $$ = new TypeOfVoid ((Location) $1);
3459                 else
3460                         $$ = new TypeOf (type, (Location) $1);
3461                 current_array_type = pushed_current_array_type;
3462           }
3463         ;
3464         
3465 typeof_type_expression
3466         : type
3467           {
3468                 $$ = $1;
3469           }
3470         | unbound_type_name
3471           {
3472                 $$ = new UnboundTypeExpression ((MemberName)$1, lexer.Location);
3473           }
3474         | error
3475          {
3476                 Error_TypeExpected (lexer.Location);
3477          }
3478         ;
3479         
3480 unbound_type_name
3481         : IDENTIFIER GENERIC_DIMENSION
3482           {
3483                 if (RootContext.Version < LanguageVersion.ISO_2)
3484                         Report.FeatureIsNotAvailable (lexer.Location, "generics");
3485           
3486                 LocatedToken lt = (LocatedToken) $1;
3487                 TypeArguments ta = new TypeArguments ((int)$2, lt.Location);
3488
3489                 $$ = new MemberName (lt.Value, ta, lt.Location);
3490           }
3491         | IDENTIFIER DOUBLE_COLON IDENTIFIER GENERIC_DIMENSION
3492           {
3493                 LocatedToken lt = (LocatedToken) $1;
3494                 MemberName left = new MemberName (lt.Value, lt.Location);
3495                 lt = (LocatedToken) $3;
3496                 TypeArguments ta = new TypeArguments ((int)$4, lt.Location);
3497                 
3498                 if (RootContext.Version == LanguageVersion.ISO_1)
3499                         Report.FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
3500                 
3501                 $$ = new MemberName (left, lt.Value, ta, lt.Location);
3502           }
3503         | unbound_type_name DOT IDENTIFIER GENERIC_DIMENSION
3504           {
3505                 LocatedToken lt = (LocatedToken) $3;
3506                 TypeArguments ta = new TypeArguments ((int)$4, lt.Location);
3507                 
3508                 $$ = new MemberName ((MemberName)$1, lt.Value, ta, lt.Location);
3509           }
3510         | namespace_or_type_name DOT IDENTIFIER GENERIC_DIMENSION
3511           {
3512                 LocatedToken lt = (LocatedToken) $3;
3513                 TypeArguments ta = new TypeArguments ((int)$4, lt.Location);
3514                 
3515                 $$ = new MemberName ((MemberName)$1, lt.Value, ta, lt.Location);
3516           }
3517         ;
3518
3519
3520 sizeof_expression
3521         : SIZEOF OPEN_PARENS type CLOSE_PARENS { 
3522                 $$ = new SizeOf ((Expression) $3, (Location) $1);
3523           }
3524         ;
3525
3526 checked_expression
3527         : CHECKED OPEN_PARENS expression CLOSE_PARENS
3528           {
3529                 $$ = new CheckedExpr ((Expression) $3, (Location) $1);
3530           }
3531         ;
3532
3533 unchecked_expression
3534         : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
3535           {
3536                 $$ = new UnCheckedExpr ((Expression) $3, (Location) $1);
3537           }
3538         ;
3539
3540 pointer_member_access 
3541         : primary_expression OP_PTR IDENTIFIER
3542           {
3543                 Expression deref;
3544                 LocatedToken lt = (LocatedToken) $3;
3545
3546                 deref = new Indirection ((Expression) $1, lt.Location);
3547                 $$ = new MemberAccess (deref, lt.Value);
3548           }
3549         ;
3550
3551 anonymous_method_expression
3552         : DELEGATE opt_anonymous_method_signature
3553           {
3554                 start_anonymous (false, (Parameters) $2, (Location) $1);
3555           }
3556           block
3557           {
3558                 $$ = end_anonymous ((ToplevelBlock) $4, (Location) $1);
3559         }
3560         ;
3561
3562 opt_anonymous_method_signature
3563         : /* empty */                   { $$ = null; } 
3564         | anonymous_method_signature
3565         ;
3566
3567 anonymous_method_signature
3568         : OPEN_PARENS
3569           {
3570                 params_modifiers_not_allowed = true; 
3571           }
3572           opt_formal_parameter_list CLOSE_PARENS
3573           {
3574                 params_modifiers_not_allowed = false;
3575                 $$ = $3;
3576           }
3577         ;
3578
3579 default_value_expression
3580         : DEFAULT_OPEN_PARENS type CLOSE_PARENS
3581           {
3582                 if (RootContext.Version < LanguageVersion.ISO_2)
3583                         Report.FeatureIsNotAvailable (lexer.Location, "default value expression");
3584
3585                 $$ = new DefaultValueExpression ((Expression) $2, lexer.Location);
3586           }
3587         ;
3588
3589 unary_expression
3590         : primary_expression
3591         | BANG prefixed_unary_expression
3592           {
3593                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, (Location) $1);
3594           }
3595         | TILDE prefixed_unary_expression
3596           {
3597                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, (Location) $1);
3598           }
3599         | cast_expression
3600         ;
3601
3602 cast_list
3603         : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression
3604           {
3605                 $$ = new Cast ((Expression) $1, (Expression) $3);
3606           }
3607         | parenthesized_expression_0 CLOSE_PARENS_NO_CAST default_value_expression
3608           {
3609                 $$ = new Cast ((Expression) $1, (Expression) $3);
3610           }
3611         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression
3612           {
3613                 $$ = new Cast ((Expression) $1, (Expression) $3);
3614           }     
3615         ;
3616
3617 cast_expression
3618         : cast_list
3619         | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
3620           {
3621                 // TODO: wrong location
3622                 $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
3623           }
3624         ;
3625
3626         //
3627         // The idea to split this out is from Rhys' grammar
3628         // to solve the problem with casts.
3629         //
3630 prefixed_unary_expression
3631         : unary_expression
3632         | PLUS prefixed_unary_expression
3633           { 
3634                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, (Location) $1);
3635           } 
3636         | MINUS prefixed_unary_expression 
3637           { 
3638                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, (Location) $1);
3639           }
3640         | OP_INC prefixed_unary_expression 
3641           {
3642                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
3643                                        (Expression) $2, (Location) $1);
3644           }
3645         | OP_DEC prefixed_unary_expression 
3646           {
3647                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
3648                                        (Expression) $2, (Location) $1);
3649           }
3650         | STAR prefixed_unary_expression
3651           {
3652                 $$ = new Indirection ((Expression) $2, (Location) $1);
3653           }
3654         | BITWISE_AND prefixed_unary_expression
3655           {
3656                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, (Location) $1);
3657           }
3658         ;
3659
3660 multiplicative_expression
3661         : prefixed_unary_expression
3662         | multiplicative_expression STAR prefixed_unary_expression
3663           {
3664                 $$ = new Binary (Binary.Operator.Multiply, 
3665                                  (Expression) $1, (Expression) $3);
3666           }
3667         | multiplicative_expression DIV prefixed_unary_expression
3668           {
3669                 $$ = new Binary (Binary.Operator.Division, 
3670                                  (Expression) $1, (Expression) $3);
3671           }
3672         | multiplicative_expression PERCENT prefixed_unary_expression 
3673           {
3674                 $$ = new Binary (Binary.Operator.Modulus, 
3675                                  (Expression) $1, (Expression) $3);
3676           }
3677         ;
3678
3679 additive_expression
3680         : multiplicative_expression
3681         | additive_expression PLUS multiplicative_expression 
3682           {
3683                 $$ = new Binary (Binary.Operator.Addition, 
3684                                  (Expression) $1, (Expression) $3);
3685           }
3686         | additive_expression MINUS multiplicative_expression
3687           {
3688                 $$ = new Binary (Binary.Operator.Subtraction, 
3689                                  (Expression) $1, (Expression) $3);
3690           }
3691         ;
3692
3693 shift_expression
3694         : additive_expression
3695         | shift_expression OP_SHIFT_LEFT additive_expression
3696           {
3697                 $$ = new Binary (Binary.Operator.LeftShift, 
3698                                  (Expression) $1, (Expression) $3);
3699           }
3700         | shift_expression OP_SHIFT_RIGHT additive_expression
3701           {
3702                 $$ = new Binary (Binary.Operator.RightShift, 
3703                                  (Expression) $1, (Expression) $3);
3704           }
3705         ; 
3706
3707 opt_error
3708         : /* empty */
3709           {
3710                 $$ = false;
3711           }
3712         | error
3713           {
3714                 lexer.PutbackNullable ();
3715                 $$ = true;
3716           }
3717         ;
3718
3719 nullable_type_or_conditional
3720         : type opt_error
3721           {
3722                 if (((bool) $2) && ($1 is ComposedCast))
3723                         $$ = ((ComposedCast) $1).RemoveNullable ();
3724                 else
3725                         $$ = $1;
3726           }
3727         ;
3728
3729 relational_expression
3730         : shift_expression
3731         | relational_expression OP_LT shift_expression
3732           {
3733                 $$ = new Binary (Binary.Operator.LessThan, 
3734                                  (Expression) $1, (Expression) $3);
3735           }
3736         | relational_expression OP_GT shift_expression
3737           {
3738                 $$ = new Binary (Binary.Operator.GreaterThan, 
3739                                  (Expression) $1, (Expression) $3);
3740           }
3741         | relational_expression OP_LE shift_expression
3742           {
3743                 $$ = new Binary (Binary.Operator.LessThanOrEqual, 
3744                                  (Expression) $1, (Expression) $3);
3745           }
3746         | relational_expression OP_GE shift_expression
3747           {
3748                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
3749                                  (Expression) $1, (Expression) $3);
3750           }
3751         | relational_expression IS
3752           {
3753                 yyErrorFlag = 3;
3754           } nullable_type_or_conditional
3755           {
3756                 $$ = new Is ((Expression) $1, (Expression) $4, (Location) $2);
3757           }
3758         | relational_expression AS
3759           {
3760                 yyErrorFlag = 3;
3761           } nullable_type_or_conditional
3762           {
3763                 $$ = new As ((Expression) $1, (Expression) $4, (Location) $2);
3764           }
3765         ;
3766
3767 equality_expression
3768         : relational_expression
3769         | equality_expression OP_EQ relational_expression
3770           {
3771                 $$ = new Binary (Binary.Operator.Equality, 
3772                                  (Expression) $1, (Expression) $3);
3773           }
3774         | equality_expression OP_NE relational_expression
3775           {
3776                 $$ = new Binary (Binary.Operator.Inequality, 
3777                                  (Expression) $1, (Expression) $3);
3778           }
3779         ; 
3780
3781 and_expression
3782         : equality_expression
3783         | and_expression BITWISE_AND equality_expression
3784           {
3785                 $$ = new Binary (Binary.Operator.BitwiseAnd, 
3786                                  (Expression) $1, (Expression) $3);
3787           }
3788         ;
3789
3790 exclusive_or_expression
3791         : and_expression
3792         | exclusive_or_expression CARRET and_expression
3793           {
3794                 $$ = new Binary (Binary.Operator.ExclusiveOr, 
3795                                  (Expression) $1, (Expression) $3);
3796           }
3797         ;
3798
3799 inclusive_or_expression
3800         : exclusive_or_expression
3801         | inclusive_or_expression BITWISE_OR exclusive_or_expression
3802           {
3803                 $$ = new Binary (Binary.Operator.BitwiseOr, 
3804                                  (Expression) $1, (Expression) $3);
3805           }
3806         ;
3807
3808 conditional_and_expression
3809         : inclusive_or_expression
3810         | conditional_and_expression OP_AND inclusive_or_expression
3811           {
3812                 $$ = new Binary (Binary.Operator.LogicalAnd, 
3813                                  (Expression) $1, (Expression) $3);
3814           }
3815         ;
3816
3817 conditional_or_expression
3818         : conditional_and_expression
3819         | conditional_or_expression OP_OR conditional_and_expression
3820           {
3821                 $$ = new Binary (Binary.Operator.LogicalOr, 
3822                                  (Expression) $1, (Expression) $3);
3823           }
3824         ;
3825
3826 conditional_expression
3827         : conditional_or_expression
3828         | conditional_or_expression INTERR expression COLON expression 
3829           {
3830                 $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5);
3831           }
3832         | conditional_or_expression OP_COALESCING expression
3833           {
3834                 if (RootContext.Version < LanguageVersion.ISO_2)
3835                         Report.FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
3836                         
3837                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, lexer.Location);
3838           }
3839         // We'll be resolved into a `parenthesized_expression_0' later on.
3840         | conditional_or_expression INTERR CLOSE_PARENS
3841           {
3842                 $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location);
3843                 lexer.PutbackCloseParens ();
3844           }
3845         ;
3846
3847 assignment_expression
3848         : prefixed_unary_expression ASSIGN expression
3849           {
3850                 $$ = new SimpleAssign ((Expression) $1, (Expression) $3);
3851           }
3852         | prefixed_unary_expression OP_MULT_ASSIGN expression
3853           {
3854                 $$ = new CompoundAssign (
3855                         Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
3856           }
3857         | prefixed_unary_expression OP_DIV_ASSIGN expression
3858           {
3859                 $$ = new CompoundAssign (
3860                         Binary.Operator.Division, (Expression) $1, (Expression) $3);
3861           }
3862         | prefixed_unary_expression OP_MOD_ASSIGN expression
3863           {
3864                 $$ = new CompoundAssign (
3865                         Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
3866           }
3867         | prefixed_unary_expression OP_ADD_ASSIGN expression
3868           {
3869                 $$ = new CompoundAssign (
3870                         Binary.Operator.Addition, (Expression) $1, (Expression) $3);
3871           }
3872         | prefixed_unary_expression OP_SUB_ASSIGN expression
3873           {
3874                 $$ = new CompoundAssign (
3875                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
3876           }
3877         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
3878           {
3879                 $$ = new CompoundAssign (
3880                         Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
3881           }
3882         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
3883           {
3884                 $$ = new CompoundAssign (
3885                         Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
3886           }
3887         | prefixed_unary_expression OP_AND_ASSIGN expression
3888           {
3889                 $$ = new CompoundAssign (
3890                         Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
3891           }
3892         | prefixed_unary_expression OP_OR_ASSIGN expression
3893           {
3894                 $$ = new CompoundAssign (
3895                         Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
3896           }
3897         | prefixed_unary_expression OP_XOR_ASSIGN expression
3898           {
3899                 $$ = new CompoundAssign (
3900                         Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
3901           }
3902         ;
3903
3904 lambda_parameter_list
3905         : lambda_parameter
3906           {
3907                 ArrayList pars = new ArrayList (4);
3908                 pars.Add ($1);
3909
3910                 $$ = pars;
3911           }
3912         | lambda_parameter_list COMMA lambda_parameter
3913           {
3914                 ArrayList pars = (ArrayList) $1;
3915                 Parameter p = (Parameter)$3;
3916                 if (pars[0].GetType () != p.GetType ()) {
3917                         Report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
3918                 }
3919                 
3920                 pars.Add (p);
3921                 $$ = pars;
3922           }
3923         ;
3924
3925 lambda_parameter
3926         : parameter_modifier type IDENTIFIER
3927           {
3928                 LocatedToken lt = (LocatedToken) $3;
3929
3930                 $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
3931           }
3932         | type IDENTIFIER
3933           {
3934                 LocatedToken lt = (LocatedToken) $2;
3935
3936                 $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
3937           }
3938         | IDENTIFIER
3939           {
3940                 LocatedToken lt = (LocatedToken) $1;
3941                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
3942           }
3943         ;
3944
3945 opt_lambda_parameter_list
3946         : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
3947         | lambda_parameter_list         { 
3948                 ArrayList pars_list = (ArrayList) $1;
3949                 $$ = new Parameters ((Parameter[])pars_list.ToArray (typeof (Parameter)));
3950           }
3951         ;
3952
3953 lambda_expression_body
3954         : {
3955                 start_block (lexer.Location);
3956           }
3957           expression 
3958           {
3959                 Block b = end_block (lexer.Location);
3960                 b.AddStatement (new ContextualReturn ((Expression) $2));
3961                 $$ = b;
3962           } 
3963         | block { 
3964                 $$ = $1; 
3965           } 
3966         ;
3967
3968 lambda_expression
3969         : IDENTIFIER ARROW 
3970           {
3971                 LocatedToken lt = (LocatedToken) $1;
3972                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
3973                 start_anonymous (true, new Parameters (p), (Location) $2);
3974           }
3975           lambda_expression_body
3976           {
3977                 $$ = end_anonymous ((ToplevelBlock) $4, (Location) $2);
3978           }
3979         | OPEN_PARENS_LAMBDA opt_lambda_parameter_list CLOSE_PARENS ARROW 
3980           {
3981                 start_anonymous (true, (Parameters) $2, (Location) $4);
3982           }
3983           lambda_expression_body 
3984           {
3985                 $$ = end_anonymous ((ToplevelBlock) $6, (Location) $4);
3986           }
3987         ;
3988
3989 expression
3990         : assignment_expression
3991         | non_assignment_expression
3992         ;
3993         
3994 non_assignment_expression
3995         : conditional_expression
3996         | lambda_expression
3997         | query_expression
3998         ;
3999
4000 constant_expression
4001         : expression
4002         ;
4003
4004 boolean_expression
4005         : expression
4006         ;
4007
4008 //
4009 // 10 classes
4010 //
4011 class_declaration
4012         : opt_attributes
4013           opt_modifiers
4014           opt_partial
4015           CLASS
4016           {
4017                 lexer.ConstraintsParsing = true;
4018           }
4019           type_name
4020           {
4021                 MemberName name = MakeName ((MemberName) $6);
4022                 push_current_class (new Class (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3);
4023           }
4024           opt_class_base
4025           opt_type_parameter_constraints_clauses
4026           {
4027                 lexer.ConstraintsParsing = false;
4028
4029                 current_class.SetParameterInfo ((ArrayList) $9);
4030
4031                 if (RootContext.Documentation != null) {
4032                         current_container.DocComment = Lexer.consume_doc_comment ();
4033                         Lexer.doc_state = XmlCommentState.Allowed;
4034                 }
4035           }
4036           class_body
4037           {
4038                 if (RootContext.Documentation != null)
4039                         Lexer.doc_state = XmlCommentState.Allowed;
4040           }
4041           opt_semicolon 
4042           {
4043                 $$ = pop_current_class ();
4044           }
4045         ;       
4046
4047 opt_partial
4048         : /* empty */
4049           { $$ = null; }
4050         | PARTIAL
4051           { $$ = $1; } // location
4052         ;
4053
4054 opt_modifiers
4055         : /* empty */           { $$ = (int) 0; }
4056         | modifiers
4057         ;
4058
4059 modifiers
4060         : modifier
4061         | modifiers modifier
4062           { 
4063                 int m1 = (int) $1;
4064                 int m2 = (int) $2;
4065
4066                 if ((m1 & m2) != 0) {
4067                         Location l = lexer.Location;
4068                         Report.Error (1004, l, "Duplicate `{0}' modifier", Modifiers.Name (m2));
4069                 }
4070                 $$ = (int) (m1 | m2);
4071           }
4072         ;
4073
4074 modifier
4075         : NEW                   { $$ = Modifiers.NEW; }
4076         | PUBLIC                { $$ = Modifiers.PUBLIC; }
4077         | PROTECTED             { $$ = Modifiers.PROTECTED; }
4078         | INTERNAL              { $$ = Modifiers.INTERNAL; }
4079         | PRIVATE               { $$ = Modifiers.PRIVATE; }
4080         | ABSTRACT              { $$ = Modifiers.ABSTRACT; }
4081         | SEALED                { $$ = Modifiers.SEALED; }
4082         | STATIC                { $$ = Modifiers.STATIC; }
4083         | READONLY              { $$ = Modifiers.READONLY; }
4084         | VIRTUAL               { $$ = Modifiers.VIRTUAL; }
4085         | OVERRIDE              { $$ = Modifiers.OVERRIDE; }
4086         | EXTERN                { $$ = Modifiers.EXTERN; }
4087         | VOLATILE              { $$ = Modifiers.VOLATILE; }
4088         | UNSAFE                { $$ = Modifiers.UNSAFE; }
4089         ;
4090
4091 opt_class_base
4092         : /* empty */
4093         | class_base
4094         ;
4095
4096 class_base
4097         : COLON type_list       { current_container.AddBasesForPart (current_class, (ArrayList) $2); }
4098         ;
4099
4100 opt_type_parameter_constraints_clauses
4101         : /* empty */           { $$ = null; }
4102         | type_parameter_constraints_clauses 
4103           { $$ = $1; }
4104         ;
4105
4106 type_parameter_constraints_clauses
4107         : type_parameter_constraints_clause {
4108                 ArrayList constraints = new ArrayList (1);
4109                 constraints.Add ($1);
4110                 $$ = constraints;
4111           }
4112         | type_parameter_constraints_clauses type_parameter_constraints_clause {
4113                 ArrayList constraints = (ArrayList) $1;
4114                 Constraints new_constraint = (Constraints)$2;
4115
4116                 foreach (Constraints c in constraints) {
4117                         if (new_constraint.TypeParameter == c.TypeParameter) {
4118                                 Report.Error (409, new_constraint.Location, "A constraint clause has already been specified for type parameter `{0}'",
4119                                         new_constraint.TypeParameter);
4120                         }
4121                 }
4122
4123                 constraints.Add (new_constraint);
4124                 $$ = constraints;
4125           }
4126         ; 
4127
4128 type_parameter_constraints_clause
4129         : WHERE IDENTIFIER COLON type_parameter_constraints {
4130                 LocatedToken lt = (LocatedToken) $2;
4131                 $$ = new Constraints (lt.Value, (ArrayList) $4, lt.Location);
4132           }
4133         ; 
4134
4135 type_parameter_constraints
4136         : type_parameter_constraint {
4137                 ArrayList constraints = new ArrayList (1);
4138                 constraints.Add ($1);
4139                 $$ = constraints;
4140           }
4141         | type_parameter_constraints COMMA type_parameter_constraint {
4142                 ArrayList constraints = (ArrayList) $1;
4143
4144                 constraints.Add ($3);
4145                 $$ = constraints;
4146           }
4147         ;
4148
4149 type_parameter_constraint
4150         : type
4151         | NEW OPEN_PARENS CLOSE_PARENS {
4152                 $$ = SpecialConstraint.Constructor;
4153           }
4154         | CLASS {
4155                 $$ = SpecialConstraint.ReferenceType;
4156           }
4157         | STRUCT {
4158                 $$ = SpecialConstraint.ValueType;
4159           }
4160         ;
4161
4162 //
4163 // Statements (8.2)
4164 //
4165
4166 //
4167 // A block is "contained" on the following places:
4168 //      method_body
4169 //      property_declaration as part of the accessor body (get/set)
4170 //      operator_declaration
4171 //      constructor_declaration
4172 //      destructor_declaration
4173 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
4174 //      
4175 block
4176         : OPEN_BRACE  
4177           {
4178                 ++lexer.parsing_block;
4179                 start_block ((Location) $1);
4180           } 
4181           opt_statement_list CLOSE_BRACE 
4182           {
4183                 --lexer.parsing_block;
4184                 $$ = end_block ((Location) $4);
4185           }
4186         ;
4187
4188 block_prepared
4189         : OPEN_BRACE
4190           {
4191                 ++lexer.parsing_block;
4192           }
4193           opt_statement_list CLOSE_BRACE 
4194           {
4195                 --lexer.parsing_block;
4196                 $$ = end_block ((Location) $4);
4197           }
4198         ;
4199
4200 opt_statement_list
4201         : /* empty */
4202         | statement_list 
4203         ;
4204
4205 statement_list
4206         : statement
4207         | statement_list statement
4208         ;
4209
4210 statement
4211         : declaration_statement
4212           {
4213                 if ($1 != null && (Block) $1 != current_block){
4214                         current_block.AddStatement ((Statement) $1);
4215                         current_block = (Block) $1;
4216                 }
4217           }
4218         | valid_declaration_statement
4219           {
4220                 current_block.AddStatement ((Statement) $1);
4221           }
4222         | labeled_statement
4223         ;
4224
4225 //
4226 // The interactive_statement and its derivatives are only 
4227 // used to provide a special version of `expression_statement'
4228 // that has a side effect of assigning the expression to
4229 // $retval
4230 //
4231 interactive_statement_list
4232         : interactive_statement
4233         | interactive_statement_list interactive_statement
4234         ;
4235
4236 interactive_statement
4237         : declaration_statement
4238           {
4239                 if ($1 != null && (Block) $1 != current_block){
4240                         current_block.AddStatement ((Statement) $1);
4241                         current_block = (Block) $1;
4242                 }
4243           }
4244         | interactive_valid_declaration_statement
4245           {
4246                 current_block.AddStatement ((Statement) $1);
4247           }
4248         | labeled_statement
4249         ;
4250
4251 valid_declaration_statement
4252         : block
4253         | empty_statement
4254         | expression_statement
4255         | selection_statement
4256         | iteration_statement
4257         | jump_statement                  
4258         | try_statement
4259         | checked_statement
4260         | unchecked_statement
4261         | lock_statement
4262         | using_statement
4263         | unsafe_statement
4264         | fixed_statement
4265         ;
4266
4267 interactive_valid_declaration_statement
4268         : block
4269         | empty_statement
4270         | interactive_expression_statement
4271         | selection_statement
4272         | iteration_statement
4273         | jump_statement                  
4274         | try_statement
4275         | checked_statement
4276         | unchecked_statement
4277         | lock_statement
4278         | using_statement
4279         | unsafe_statement
4280         | fixed_statement
4281         ;
4282
4283 embedded_statement
4284         : valid_declaration_statement
4285         | declaration_statement
4286           {
4287                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4288                   $$ = null;
4289           }
4290         | labeled_statement
4291           {
4292                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4293                   $$ = null;
4294           }
4295         ;
4296
4297 empty_statement
4298         : SEMICOLON
4299           {
4300                   $$ = EmptyStatement.Value;
4301           }
4302         ;
4303
4304 labeled_statement
4305         : IDENTIFIER COLON 
4306           {
4307                 LocatedToken lt = (LocatedToken) $1;
4308                 LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location);
4309
4310                 if (current_block.AddLabel (labeled))
4311                         current_block.AddStatement (labeled);
4312           }
4313           statement
4314         ;
4315
4316 declaration_statement
4317         : local_variable_declaration SEMICOLON
4318           {
4319                 current_array_type = null;
4320                 if ($1 != null){
4321                         DictionaryEntry de = (DictionaryEntry) $1;
4322                         Expression e = (Expression) de.Key;
4323
4324                         $$ = declare_local_variables (e, (ArrayList) de.Value, e.Location);
4325                 }
4326           }
4327
4328         | local_constant_declaration SEMICOLON
4329           {
4330                 current_array_type = null;
4331                 if ($1 != null){
4332                         DictionaryEntry de = (DictionaryEntry) $1;
4333
4334                         $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value);
4335                 }
4336           }
4337         ;
4338
4339 /* 
4340  * The following is from Rhys' grammar:
4341  * > Types in local variable declarations must be recognized as 
4342  * > expressions to prevent reduce/reduce errors in the grammar.
4343  * > The expressions are converted into types during semantic analysis.
4344  */
4345 local_variable_type
4346         : primary_expression opt_rank_specifier_or_nullable
4347           { 
4348                 // FIXME: Do something smart here regarding the composition of the type.
4349
4350                 // Ok, the above "primary_expression" is there to get rid of
4351                 // both reduce/reduce and shift/reduces in the grammar, it should
4352                 // really just be "type_name".  If you use type_name, a reduce/reduce
4353                 // creeps up.  If you use namespace_or_type_name (which is all we need
4354                 // really) two shift/reduces appear.
4355                 // 
4356
4357                 // So the super-trick is that primary_expression
4358                 // can only be either a SimpleName or a MemberAccess. 
4359                 // The MemberAccess case arises when you have a fully qualified type-name like :
4360                 // Foo.Bar.Blah i;
4361                 // SimpleName is when you have
4362                 // Blah i;
4363                 
4364                 Expression expr = (Expression) $1;
4365                 string rank_or_nullable = (string) $2;
4366                 
4367                 if (expr is ComposedCast){
4368                         $$ = new ComposedCast ((ComposedCast)expr, rank_or_nullable);
4369                 } else if (expr is ATypeNameExpression){
4370                         //
4371                         // So we extract the string corresponding to the SimpleName
4372                         // or MemberAccess
4373                         //
4374                         if (rank_or_nullable.Length == 0) {
4375                                 SimpleName sn = expr as SimpleName;
4376                                 if (sn != null && sn.Name == "var" &&
4377                                     (RootContext.Version > LanguageVersion.ISO_2 || RootContext.Version == LanguageVersion.Default_MCS))
4378                                         $$ = new VarExpr (sn.Location);
4379                                 else
4380                                         $$ = $1;
4381                         } else {
4382                                 $$ = new ComposedCast ((ATypeNameExpression)expr, rank_or_nullable);
4383                         }
4384                 } else {
4385                         Error_ExpectingTypeName (expr);
4386                         $$ = TypeManager.system_object_expr;
4387                 }
4388           }
4389         | builtin_types opt_rank_specifier_or_nullable
4390           {
4391                 if ((string) $2 == "")
4392                         $$ = $1;
4393                 else
4394                         $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, (string) $2, lexer.Location);
4395           }
4396         ;
4397
4398 local_variable_pointer_type
4399         : primary_expression STAR
4400           {
4401                 ATypeNameExpression expr = $1 as ATypeNameExpression;
4402
4403                 if (expr != null) {
4404                         $$ = new ComposedCast (expr, "*");
4405                 } else {
4406                         Error_ExpectingTypeName ((Expression)$1);
4407                         $$ = expr;
4408                 }
4409           }
4410         | builtin_types STAR
4411           {
4412                 $$ = new ComposedCast ((FullNamedExpression) $1, "*", lexer.Location);
4413           }
4414         | VOID STAR
4415           {
4416                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1);
4417           }
4418         | local_variable_pointer_type STAR
4419           {
4420                 $$ = new ComposedCast ((FullNamedExpression) $1, "*");
4421           }
4422         ;
4423
4424 local_variable_declaration
4425         : local_variable_type variable_declarators
4426           {
4427                 if ($1 != null) {
4428                         VarExpr ve = $1 as VarExpr;
4429                         if (ve != null)
4430                                 ve.VariableInitializer = (ArrayList)$2;
4431                                 
4432                         $$ = new DictionaryEntry ($1, $2);
4433                 } else
4434                         $$ = null;
4435           }
4436         | local_variable_pointer_type opt_rank_specifier_or_nullable variable_declarators
4437           {
4438                 if ($1 != null){
4439                         Expression t;
4440
4441                         if ((string) $2 == "")
4442                                 t = (Expression) $1;
4443                         else
4444                                 t = new ComposedCast ((FullNamedExpression) $1, (string) $2);
4445                         $$ = new DictionaryEntry (t, $3);
4446                 } else 
4447                         $$ = null;
4448           }
4449         ;
4450
4451 local_constant_declaration
4452         : CONST local_variable_type constant_declarators
4453           {
4454                 if ($2 != null)
4455                         $$ = new DictionaryEntry ($2, $3);
4456                 else
4457                         $$ = null;
4458           }
4459         ;
4460
4461 expression_statement
4462         : statement_expression SEMICOLON { $$ = $1; }
4463         ;
4464
4465 interactive_expression_statement
4466         : interactive_statement_expression SEMICOLON { $$ = $1; }
4467         ;
4468
4469         //
4470         // We have to do the wrapping here and not in the case above,
4471         // because statement_expression is used for example in for_statement
4472         //
4473 statement_expression
4474         : expression
4475           {
4476                 Expression expr = (Expression) $1;
4477                 ExpressionStatement s;
4478
4479                 s = expr as ExpressionStatement;
4480
4481                 if (s == null) {
4482                         expr.Error_InvalidExpressionStatement ();
4483                         $$ = null;
4484                 } 
4485                 $$ = new StatementExpression (s);
4486           }
4487         | error
4488           {
4489                 Report.ExtraInformation (GetLocation ($1), "(token is: " + yyToken + " in previous ");
4490                 Report.Error (1002, GetLocation ($1), "Expecting `;'");
4491                 $$ = null;
4492           }
4493         ;
4494
4495 interactive_statement_expression
4496         : expression
4497           {
4498                 Expression expr = (Expression) $1;
4499                 ExpressionStatement s;
4500
4501                 s = new OptionalAssign (new SimpleName ("$retval", lexer.Location), expr, lexer.Location);
4502                 $$ = new StatementExpression (s);
4503           }
4504         | error
4505           {
4506                 Report.Error (1002, GetLocation ($1), "Expecting `;' (token is: {0})", yyToken);
4507                 $$ = null;
4508           }
4509         ;
4510         
4511 selection_statement
4512         : if_statement
4513         | switch_statement
4514         ; 
4515
4516 if_statement
4517         : IF OPEN_PARENS boolean_expression CLOSE_PARENS 
4518           embedded_statement
4519           { 
4520                 Location l = (Location) $1;
4521
4522                 $$ = new If ((Expression) $3, (Statement) $5, l);
4523
4524                 // FIXME: location for warning should be loc property of $5.
4525                 if ($5 == EmptyStatement.Value)
4526                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4527
4528           }
4529         | IF OPEN_PARENS boolean_expression CLOSE_PARENS
4530           embedded_statement ELSE embedded_statement
4531           {
4532                 Location l = (Location) $1;
4533
4534                 $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7, l);
4535
4536                 // FIXME: location for warning should be loc property of $5 and $7.
4537                 if ($5 == EmptyStatement.Value)
4538                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4539                 if ($7 == EmptyStatement.Value)
4540                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4541           }
4542         ;
4543
4544 switch_statement
4545         : SWITCH OPEN_PARENS
4546           { 
4547                 if (switch_stack == null)
4548                         switch_stack = new Stack (2);
4549                 switch_stack.Push (current_block);
4550           }
4551           expression CLOSE_PARENS 
4552           switch_block
4553           {
4554                 $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) $1);
4555                 current_block = (Block) switch_stack.Pop ();
4556           }
4557         ;
4558
4559 switch_block
4560         : OPEN_BRACE
4561           opt_switch_sections
4562           CLOSE_BRACE
4563           {
4564                 $$ = $2;
4565           }
4566         ;
4567
4568 opt_switch_sections
4569         : /* empty */           
4570           {
4571                 Report.Warning (1522, 1, lexer.Location, "Empty switch block"); 
4572                 $$ = new ArrayList ();
4573           }
4574         | switch_sections
4575         ;
4576
4577 switch_sections
4578         : switch_section 
4579           {
4580                 ArrayList sections = new ArrayList (4);
4581
4582                 sections.Add ($1);
4583                 $$ = sections;
4584           }
4585         | switch_sections switch_section
4586           {
4587                 ArrayList sections = (ArrayList) $1;
4588
4589                 sections.Add ($2);
4590                 $$ = sections;
4591           }
4592         ;
4593
4594 switch_section
4595         : switch_labels
4596           {
4597                 current_block = current_block.CreateSwitchBlock (lexer.Location);
4598           }
4599           statement_list 
4600           {
4601                 $$ = new SwitchSection ((ArrayList) $1, current_block.Explicit);
4602           }
4603         ;
4604
4605 switch_labels
4606         : switch_label 
4607           {
4608                 ArrayList labels = new ArrayList (4);
4609
4610                 labels.Add ($1);
4611                 $$ = labels;
4612           }
4613         | switch_labels switch_label 
4614           {
4615                 ArrayList labels = (ArrayList) ($1);
4616                 labels.Add ($2);
4617
4618                 $$ = labels;
4619           }
4620         ;
4621
4622 switch_label
4623         : CASE constant_expression COLON        { $$ = new SwitchLabel ((Expression) $2, (Location) $1); }
4624         | DEFAULT_COLON                         { $$ = new SwitchLabel (null, (Location) $1); }
4625         | error {
4626                 Report.Error (
4627                         1523, GetLocation ($1), 
4628                         "The keyword case or default must precede code in switch block");
4629           }
4630         ;
4631
4632 iteration_statement
4633         : while_statement
4634         | do_statement
4635         | for_statement
4636         | foreach_statement
4637         ;
4638
4639 while_statement
4640         : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement
4641           {
4642                 Location l = (Location) $1;
4643                 $$ = new While ((Expression) $3, (Statement) $5, l);
4644           }
4645         ;
4646
4647 do_statement
4648         : DO embedded_statement 
4649           WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
4650           {
4651                 Location l = (Location) $1;
4652
4653                 $$ = new Do ((Statement) $2, (Expression) $5, l);
4654           }
4655         ;
4656
4657 for_statement
4658         : FOR OPEN_PARENS 
4659           opt_for_initializer SEMICOLON
4660           {
4661                 Location l = lexer.Location;
4662                 start_block (l);  
4663                 Block assign_block = current_block;
4664
4665                 if ($3 is DictionaryEntry){
4666                         DictionaryEntry de = (DictionaryEntry) $3;
4667                         
4668                         Expression type = (Expression) de.Key;
4669                         ArrayList var_declarators = (ArrayList) de.Value;
4670
4671                         foreach (VariableDeclaration decl in var_declarators){
4672
4673                                 LocalInfo vi;
4674
4675                                 vi = current_block.AddVariable (type, decl.identifier, decl.Location);
4676                                 if (vi == null)
4677                                         continue;
4678
4679                                 Expression expr = decl.expression_or_array_initializer;
4680                                         
4681                                 LocalVariableReference var;
4682                                 var = new LocalVariableReference (assign_block, decl.identifier, l);
4683
4684                                 if (expr != null) {
4685                                         Assign a = new SimpleAssign (var, expr, decl.Location);
4686                                         
4687                                         assign_block.AddStatement (new StatementExpression (a));
4688                                 }
4689                         }
4690                         
4691                         // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal.
4692                         // This can be referred to as $5 below.
4693                         $$ = null;
4694                 } else {
4695                         $$ = $3;
4696                 }
4697           } 
4698           opt_for_condition SEMICOLON
4699           opt_for_iterator CLOSE_PARENS 
4700           embedded_statement
4701           {
4702                 Location l = (Location) $1;
4703
4704                 For f = new For ((Statement) $5, (Expression) $6, (Statement) $8, (Statement) $10, l);
4705
4706                 current_block.AddStatement (f);
4707
4708                 $$ = end_block (lexer.Location);
4709           }
4710         ;
4711
4712 opt_for_initializer
4713         : /* empty */           { $$ = EmptyStatement.Value; }
4714         | for_initializer       
4715         ;
4716
4717 for_initializer
4718         : local_variable_declaration
4719         | statement_expression_list
4720         ;
4721
4722 opt_for_condition
4723         : /* empty */           { $$ = null; }
4724         | boolean_expression
4725         ;
4726
4727 opt_for_iterator
4728         : /* empty */           { $$ = EmptyStatement.Value; }
4729         | for_iterator
4730         ;
4731
4732 for_iterator
4733         : statement_expression_list
4734         ;
4735
4736 statement_expression_list
4737         : statement_expression  
4738           {
4739                 // CHANGE: was `null'
4740                 Statement s = (Statement) $1;
4741                 Block b = new Block (current_block, s.loc, lexer.Location);   
4742
4743                 b.AddStatement (s);
4744                 $$ = b;
4745           }
4746         | statement_expression_list COMMA statement_expression
4747           {
4748                 Block b = (Block) $1;
4749
4750                 b.AddStatement ((Statement) $3);
4751                 $$ = $1;
4752           }
4753         ;
4754
4755 foreach_statement
4756         : FOREACH OPEN_PARENS type IN expression CLOSE_PARENS
4757           {
4758                 Report.Error (230, (Location) $1, "Type and identifier are both required in a foreach statement");
4759                 $$ = null;
4760           }
4761         | FOREACH OPEN_PARENS type IDENTIFIER IN
4762           expression CLOSE_PARENS 
4763           {
4764                 start_block (lexer.Location);
4765                 Block foreach_block = current_block;
4766
4767                 LocatedToken lt = (LocatedToken) $4;
4768                 Location l = lt.Location;
4769                 LocalInfo vi = foreach_block.AddVariable ((Expression) $3, lt.Value, l);
4770                 if (vi != null) {
4771                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach);
4772
4773                         // Get a writable reference to this read-only variable.
4774                         //
4775                         // Note that the $$ here refers to the value of _this_ code block,
4776                         // not the value of the LHS non-terminal.  This can be referred to as $8 below.
4777                         $$ = new LocalVariableReference (foreach_block, lt.Value, l, vi, false);
4778                 } else {
4779                         $$ = null;
4780                 }
4781           } 
4782           embedded_statement 
4783           {
4784                 LocalVariableReference v = (LocalVariableReference) $8;
4785                 Location l = (Location) $1;
4786
4787                 if (v != null) {
4788                         Foreach f = new Foreach ((Expression) $3, v, (Expression) $6, (Statement) $9, l);
4789                         current_block.AddStatement (f);
4790                 }
4791
4792                 $$ = end_block (lexer.Location);
4793           }
4794         ;
4795
4796 jump_statement
4797         : break_statement
4798         | continue_statement
4799         | goto_statement
4800         | return_statement
4801         | throw_statement
4802         | yield_statement
4803         ;
4804
4805 break_statement
4806         : BREAK SEMICOLON
4807           {
4808                 $$ = new Break ((Location) $1);
4809           }
4810         ;
4811
4812 continue_statement
4813         : CONTINUE SEMICOLON
4814           {
4815                 $$ = new Continue ((Location) $1);
4816           }
4817         ;
4818
4819 goto_statement
4820         : GOTO IDENTIFIER SEMICOLON 
4821           {
4822                 LocatedToken lt = (LocatedToken) $2;
4823                 $$ = new Goto (lt.Value, lt.Location);
4824           }
4825         | GOTO CASE constant_expression SEMICOLON
4826           {
4827                 $$ = new GotoCase ((Expression) $3, (Location) $1);
4828           }
4829         | GOTO DEFAULT SEMICOLON 
4830           {
4831                 $$ = new GotoDefault ((Location) $1);
4832           }
4833         ; 
4834
4835 return_statement
4836         : RETURN opt_expression SEMICOLON
4837           {
4838                 $$ = new Return ((Expression) $2, (Location) $1);
4839           }
4840         ;
4841
4842 throw_statement
4843         : THROW opt_expression SEMICOLON
4844           {
4845                 $$ = new Throw ((Expression) $2, (Location) $1);
4846           }
4847         ;
4848
4849 yield_statement 
4850         : IDENTIFIER RETURN expression SEMICOLON
4851           {
4852                 LocatedToken lt = (LocatedToken) $1;
4853                 string s = lt.Value;
4854                 if (s != "yield"){
4855                         Report.Error (1003, lt.Location, "; expected");
4856                         $$ = null;
4857                 }
4858                 if (RootContext.Version == LanguageVersion.ISO_1){
4859                         Report.FeatureIsNotAvailable (lt.Location, "yield statement");
4860                         $$ = null;
4861                 }
4862                 current_block.Toplevel.IsIterator = true;
4863                 $$ = new Yield ((Expression) $3, lt.Location); 
4864           }
4865         | IDENTIFIER RETURN SEMICOLON
4866           {
4867                 Report.Error (1627, (Location) $2, "Expression expected after yield return");
4868                 $$ = null;
4869           }
4870         | IDENTIFIER BREAK SEMICOLON
4871           {
4872                 LocatedToken lt = (LocatedToken) $1;
4873                 string s = lt.Value;
4874                 if (s != "yield"){
4875                         Report.Error (1003, lt.Location, "; expected");
4876                         $$ = null;
4877                 }
4878                 if (RootContext.Version == LanguageVersion.ISO_1){
4879                         Report.FeatureIsNotAvailable (lt.Location, "yield statement");
4880                         $$ = null;
4881                 }
4882                 
4883                 current_block.Toplevel.IsIterator = true;
4884                 $$ = new YieldBreak (lt.Location);
4885           }
4886         ;
4887
4888 opt_expression
4889         : /* empty */
4890         | expression
4891         ;
4892
4893 try_statement
4894         : TRY block catch_clauses
4895           {
4896                 $$ = new TryCatch ((Block) $2, (ArrayList) $3, (Location) $1, false);
4897           }
4898         | TRY block FINALLY block
4899           {
4900                 $$ = new TryFinally ((Statement) $2, (Block) $4, (Location) $1);
4901           }
4902         | TRY block catch_clauses FINALLY block
4903           {
4904                 $$ = new TryFinally (new TryCatch ((Block) $2, (ArrayList) $3, (Location) $1, true), (Block) $5, (Location) $1);
4905           }
4906         | TRY block error 
4907           {
4908                 Report.Error (1524, (Location) $1, "Expected catch or finally");
4909                 $$ = null;
4910           }
4911         ;
4912
4913 catch_clauses
4914         : catch_clause 
4915           {
4916                 ArrayList l = new ArrayList (4);
4917
4918                 l.Add ($1);
4919                 $$ = l;
4920           }
4921         | catch_clauses catch_clause
4922           {
4923                 ArrayList l = (ArrayList) $1;
4924
4925                 l.Add ($2);
4926                 $$ = l;
4927           }
4928         ;
4929
4930 opt_identifier
4931         : /* empty */   { $$ = null; }
4932         | IDENTIFIER
4933         ;
4934
4935 catch_clause 
4936         : CATCH opt_catch_args 
4937           {
4938                 Expression type = null;
4939                 
4940                 if ($2 != null) {
4941                         DictionaryEntry cc = (DictionaryEntry) $2;
4942                         type = (Expression) cc.Key;
4943                         LocatedToken lt = (LocatedToken) cc.Value;
4944
4945                         if (lt != null){
4946                                 ArrayList one = new ArrayList (4);
4947
4948                                 one.Add (new VariableDeclaration (lt, null));
4949
4950                                 start_block (lexer.Location);
4951                                 current_block = declare_local_variables (type, one, lt.Location);
4952                         }
4953                 }
4954           } block {
4955                 Expression type = null;
4956                 string id = null;
4957                 Block var_block = null;
4958
4959                 if ($2 != null){
4960                         DictionaryEntry cc = (DictionaryEntry) $2;
4961                         type = (Expression) cc.Key;
4962                         LocatedToken lt = (LocatedToken) cc.Value;
4963
4964                         if (lt != null){
4965                                 id = lt.Value;
4966                                 var_block = end_block (lexer.Location);
4967                         }
4968                 }
4969
4970                 $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc);
4971           }
4972         ;
4973
4974 opt_catch_args
4975         : /* empty */ { $$ = null; }
4976         | catch_args
4977         ;         
4978
4979 catch_args 
4980         : OPEN_PARENS type opt_identifier CLOSE_PARENS 
4981           {
4982                 $$ = new DictionaryEntry ($2, $3);
4983           }
4984         | OPEN_PARENS CLOSE_PARENS 
4985           {
4986                 Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected");
4987           }
4988         ;
4989
4990 checked_statement
4991         : CHECKED block
4992           {
4993                 $$ = new Checked ((Block) $2);
4994           }
4995         ;
4996
4997 unchecked_statement
4998         : UNCHECKED block
4999           {
5000                 $$ = new Unchecked ((Block) $2);
5001           }
5002         ;
5003
5004 unsafe_statement
5005         : UNSAFE 
5006           {
5007                 RootContext.CheckUnsafeOption ((Location) $1);
5008           } block {
5009                 $$ = new Unsafe ((Block) $3);
5010           }
5011         ;
5012
5013 fixed_statement
5014         : FIXED OPEN_PARENS 
5015           type fixed_pointer_declarators 
5016           CLOSE_PARENS
5017           {
5018                 ArrayList list = (ArrayList) $4;
5019                 Expression type = (Expression) $3;
5020                 Location l = (Location) $1;
5021                 int top = list.Count;
5022
5023                 start_block (lexer.Location);
5024
5025                 for (int i = 0; i < top; i++){
5026                         Pair p = (Pair) list [i];
5027                         LocalInfo v;
5028
5029                         v = current_block.AddVariable (type, (string) p.First, l);
5030                         if (v == null)
5031                                 continue;
5032
5033                         v.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
5034                         v.Pinned = true;
5035                         p.First = v;
5036                         list [i] = p;
5037                 }
5038           }
5039           embedded_statement 
5040           {
5041                 Location l = (Location) $1;
5042
5043                 Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
5044
5045                 current_block.AddStatement (f);
5046
5047                 $$ = end_block (lexer.Location);
5048           }
5049         ;
5050
5051 fixed_pointer_declarators
5052         : fixed_pointer_declarator      { 
5053                 ArrayList declarators = new ArrayList (4);
5054                 if ($1 != null)
5055                         declarators.Add ($1);
5056                 $$ = declarators;
5057           }
5058         | fixed_pointer_declarators COMMA fixed_pointer_declarator
5059           {
5060                 ArrayList declarators = (ArrayList) $1;
5061                 if ($3 != null)
5062                         declarators.Add ($3);
5063                 $$ = declarators;
5064           }
5065         ;
5066
5067 fixed_pointer_declarator
5068         : IDENTIFIER ASSIGN expression
5069           {
5070                 LocatedToken lt = (LocatedToken) $1;
5071                 // FIXME: keep location
5072                 $$ = new Pair (lt.Value, $3);
5073           }
5074         | IDENTIFIER
5075           {
5076                 Report.Error (210, ((LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration");
5077                 $$ = null;
5078           }
5079         ;
5080
5081 lock_statement
5082         : LOCK OPEN_PARENS expression CLOSE_PARENS 
5083           {
5084                 //
5085           } 
5086           embedded_statement
5087           {
5088                 $$ = new Lock ((Expression) $3, (Statement) $6, (Location) $1);
5089           }
5090         ;
5091
5092 using_statement
5093         : USING OPEN_PARENS local_variable_declaration CLOSE_PARENS
5094           {
5095                 start_block (lexer.Location);
5096                 Block assign_block = current_block;
5097
5098                 DictionaryEntry de = (DictionaryEntry) $3;
5099                 Location l = (Location) $1;
5100
5101                 Expression type = (Expression) de.Key;
5102                 ArrayList var_declarators = (ArrayList) de.Value;
5103
5104                 Stack vars = new Stack ();
5105
5106                 foreach (VariableDeclaration decl in var_declarators) {
5107                         LocalInfo vi = current_block.AddVariable (type, decl.identifier, decl.Location);
5108                         if (vi == null)
5109                                 continue;
5110                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
5111
5112                         Expression expr = decl.expression_or_array_initializer;
5113                         if (expr == null) {
5114                                 Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
5115                                 continue;
5116                         }
5117                         LocalVariableReference var;
5118
5119                         // Get a writable reference to this read-only variable.
5120                         var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
5121
5122                         // This is so that it is not a warning on using variables
5123                         vi.Used = true;
5124
5125                         vars.Push (new DictionaryEntry (var, expr));
5126
5127                         // Assign a = new SimpleAssign (var, expr, decl.Location);
5128                         // assign_block.AddStatement (new StatementExpression (a));
5129                 }
5130
5131                 // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
5132                 // It can be referred to as $5 below.
5133                 $$ = vars;
5134           }
5135           embedded_statement
5136           {
5137                 Statement stmt = (Statement) $6;
5138                 Stack vars = (Stack) $5;
5139                 Location l = (Location) $1;
5140
5141                 while (vars.Count > 0) {
5142                           DictionaryEntry de = (DictionaryEntry) vars.Pop ();
5143                           stmt = new Using ((Expression) de.Key, (Expression) de.Value, stmt, l);
5144                 }
5145                 current_block.AddStatement (stmt);
5146                 $$ = end_block (lexer.Location);
5147           }
5148         | USING OPEN_PARENS expression CLOSE_PARENS
5149           {
5150                 start_block (lexer.Location);
5151           }
5152           embedded_statement
5153           {
5154                 current_block.AddStatement (new UsingTemporary ((Expression) $3, (Statement) $6, (Location) $1));
5155                 $$ = end_block (lexer.Location);
5156           }
5157         ; 
5158
5159
5160 // LINQ
5161
5162 query_expression
5163         : first_from_clause
5164           {
5165                 ++lexer.query_parsing;
5166           }
5167           query_body
5168           {
5169                 if (--lexer.query_parsing == 1)
5170                         lexer.query_parsing = 0;
5171                         
5172                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5173                         
5174                 from.Tail.Next = (Linq.AQueryClause)$3;
5175                 $$ = from;
5176                 
5177                 current_block.SetEndLocation (lexer.Location);
5178                 current_block = current_block.Parent;
5179           }     
5180         ;
5181         
5182 first_from_clause
5183         : FROM IDENTIFIER IN expression
5184           {
5185                 current_block = new Linq.QueryBlock (current_block, GetLocation ($1));
5186                 LocatedToken lt = (LocatedToken) $2;
5187                 
5188                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, lt.Value, lt.Location);
5189                 $$ = new Linq.QueryExpression (lt, new Linq.QueryStartClause ((Expression)$4));
5190           }
5191         | FROM type IDENTIFIER IN expression
5192           {
5193                 current_block = new Linq.QueryBlock (current_block, GetLocation ($1));
5194                 LocatedToken lt = (LocatedToken) $3;
5195
5196                 Expression type = (Expression)$2;
5197                 current_block.AddVariable (type, lt.Value, lt.Location);
5198                 $$ = new Linq.QueryExpression (lt, new Linq.Cast (type, (Expression)$5));
5199           }
5200         ;
5201         
5202 from_clause
5203         : FROM IDENTIFIER IN expression
5204           {
5205                 LocatedToken lt = (LocatedToken) $2;
5206                 
5207                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance,
5208                         lt.Value, lt.Location);
5209                         
5210                 $$ = new Linq.SelectMany (lt, (Expression)$4);                  
5211           }
5212         | FROM type IDENTIFIER IN expression
5213           {
5214                 LocatedToken lt = (LocatedToken) $3;
5215
5216                 Expression type = (Expression)$2;
5217                 current_block.AddVariable (type, lt.Value, lt.Location);
5218                 $$ = new Linq.SelectMany (lt, new Linq.Cast (type, (Expression)$5));
5219           }
5220         ;       
5221
5222 query_body
5223         : opt_query_body_clauses select_or_group_clause opt_query_continuation
5224           {
5225                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5226                 
5227                 if ($3 != null)
5228                         head.Next = (Linq.AQueryClause)$3;
5229                                 
5230                 if ($1 != null) {
5231                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5232                         clause.Tail.Next = head;
5233                         head = clause;
5234                 }
5235                 
5236                 $$ = head;
5237           }
5238         ;
5239         
5240 select_or_group_clause
5241         : SELECT expression
5242           {
5243                 $$ = new Linq.Select ((Expression)$2, GetLocation ($1));
5244           }
5245         | GROUP expression BY expression
5246           {
5247             $$ = new Linq.GroupBy ((Expression)$2, (Expression)$4, GetLocation ($1));
5248           }
5249         ;
5250         
5251 opt_query_body_clauses
5252         : /* empty */
5253         | query_body_clauses
5254         ;
5255         
5256 query_body_clauses
5257         : query_body_clause
5258         | query_body_clauses query_body_clause
5259           {
5260                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
5261                 $$ = $1;
5262           }
5263         ;
5264         
5265 query_body_clause
5266         : from_clause
5267         | let_clause
5268         | where_clause
5269         | join_clause
5270         | orderby_clause
5271         ;
5272         
5273 let_clause
5274         : LET IDENTIFIER ASSIGN expression
5275           {
5276                 LocatedToken lt = (LocatedToken) $2;
5277                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance,
5278                         lt.Value, lt.Location);   
5279                 $$ = new Linq.Let (lt, (Expression)$4, GetLocation ($1));
5280           }
5281         ;
5282
5283 where_clause
5284         : WHERE boolean_expression
5285           {
5286                 $$ = new Linq.Where ((Expression)$2, GetLocation ($1));
5287           }
5288         ;
5289         
5290 join_clause
5291         : JOIN IDENTIFIER IN expression ON expression EQUALS expression opt_join_into
5292           {
5293                 Location loc = GetLocation ($1);
5294                 LocatedToken lt = (LocatedToken) $2;
5295                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance,
5296                         lt.Value, lt.Location);
5297                 
5298                 if ($9 == null) {
5299                         $$ = new Linq.Join (lt, (Expression)$4, (Expression)$6,
5300                                 (Expression)$8, loc);
5301                 } else {
5302                         LocatedToken lt_into = (LocatedToken) $9;
5303                         $$ = new Linq.GroupJoin (lt, (Expression)$4, (Expression)$6,
5304                                 (Expression)$8, lt_into, loc);
5305                 }
5306           }
5307         | JOIN type IDENTIFIER IN expression ON expression EQUALS expression opt_join_into
5308           {
5309                 Location loc = GetLocation ($1);
5310                 LocatedToken lt = (LocatedToken) $3;
5311                 current_block.AddVariable ((Expression)$2, lt.Value, lt.Location);
5312                 
5313                 Linq.Cast cast = new Linq.Cast ((Expression)$2, (Expression)$5);
5314                 if ($10 == null) {
5315                         $$ = new Linq.Join (lt, cast, (Expression)$7,
5316                                 (Expression)$9, loc);
5317                 } else {
5318                         LocatedToken lt_into = (LocatedToken) $10;
5319                         $$ = new Linq.GroupJoin (lt, cast, (Expression)$7,
5320                                 (Expression)$9, lt_into, loc);
5321                 }
5322           }
5323         ;
5324         
5325 opt_join_into
5326         : /* empty */
5327         | INTO IDENTIFIER
5328           {
5329                 $$ = $2;
5330           }
5331         ;
5332         
5333 orderby_clause
5334         : ORDERBY orderings
5335           {
5336                 $$ = $2;
5337           }
5338         ;
5339         
5340 orderings
5341         : order_by
5342         | order_by COMMA orderings_then_by
5343           {
5344                 ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$3;
5345                 $$ = $1;
5346           }
5347         ;
5348         
5349 orderings_then_by
5350         : then_by
5351           {
5352                 $$ = $1;
5353           }
5354         | orderings_then_by COMMA then_by
5355           {
5356                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$3;
5357                 $$ = $1;
5358           }
5359         ;       
5360         
5361 order_by
5362         : expression
5363           {
5364                 $$ = new Linq.OrderByAscending ((Expression)$1);        
5365           }
5366         | expression ASCENDING
5367           {
5368                 $$ = new Linq.OrderByAscending ((Expression)$1);        
5369           }
5370         | expression DESCENDING
5371           {
5372                 $$ = new Linq.OrderByDescending ((Expression)$1);       
5373           }
5374         ;
5375
5376 then_by
5377         : expression
5378           {
5379                 $$ = new Linq.ThenByAscending ((Expression)$1); 
5380           }
5381         | expression ASCENDING
5382           {
5383                 $$ = new Linq.ThenByAscending ((Expression)$1); 
5384           }
5385         | expression DESCENDING
5386           {
5387                 $$ = new Linq.ThenByDescending ((Expression)$1);        
5388           }     
5389         ;
5390
5391
5392 opt_query_continuation
5393         : /* empty */
5394         | INTO IDENTIFIER
5395           {
5396                 // query continuation block is not linked with query block but with block
5397                 // before. This means each query can use same range variable names for
5398                 // different identifiers.
5399
5400                 current_block.SetEndLocation (GetLocation ($1));
5401                 current_block = current_block.Parent;
5402                 current_block = new Linq.QueryBlock (current_block, GetLocation ($1));
5403                 
5404                 LocatedToken lt = (LocatedToken) $2;
5405                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance,
5406                         lt.Value, lt.Location);
5407           }
5408           query_body
5409           {
5410                 $$ = new Linq.QueryExpression ((LocatedToken) $2,
5411                         (Linq.AQueryClause)$4);
5412           }
5413         ;
5414         
5415 //
5416 // Support for using the compiler as an interactive parser
5417 //
5418 // The INTERACTIVE_PARSER token is first sent to parse our
5419 // productions;  If the result is a Statement, the parsing
5420 // is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
5421 // to setup the blocks in advance.
5422 //
5423 // This setup is here so that in the future we can add 
5424 // support for other constructs (type parsing, namespaces, etc)
5425 // that do not require a block to be setup in advance
5426 //
5427
5428 interactive_parsing
5429         : EVAL_STATEMENT_PARSER EOF 
5430         | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives 
5431         | EVAL_STATEMENT_PARSER { 
5432                 InteractiveShell.LoadAliases (current_namespace);
5433
5434                 push_current_class (new Class (current_namespace, current_class, new MemberName ("Class" + class_count++),
5435                         Modifiers.PUBLIC, null), null);
5436
5437                 ArrayList baseclass_list = new ArrayList ();
5438                 baseclass_list.Add (new TypeExpression (typeof (InteractiveBase), lexer.Location));
5439                 current_container.AddBasesForPart (current_class, baseclass_list);
5440
5441                 // (ref object retval)
5442                 Parameter [] mpar = new Parameter [1];
5443                 mpar [0] = new Parameter (TypeManager.system_object_expr, "$retval", Parameter.Modifier.REF, null, Location.Null);
5444
5445                 Parameters pars = new Parameters (mpar);
5446                 current_local_parameters = pars;
5447                 Method method = new Method (
5448                         current_class,
5449                         null, // generic
5450                         TypeManager.system_void_expr,
5451                         Modifiers.PUBLIC | Modifiers.STATIC,
5452                         new MemberName ("Host"),
5453                         pars,
5454                         null /* attributes */);
5455
5456                 oob_stack.Push (method);
5457                 ++lexer.parsing_block;
5458                 start_block (lexer.Location);
5459           }             
5460           interactive_statement_list
5461           {
5462                 --lexer.parsing_block;
5463                 Method method = (Method) oob_stack.Pop ();
5464
5465                 method.Block = (ToplevelBlock) end_block(lexer.Location);
5466                 current_container.AddMethod (method);
5467
5468                 InteractiveResult = pop_current_class ();
5469                 current_local_parameters = null;
5470           } 
5471 //      | EVAL_COMPILATION_UNIT_PARSER {
5472 //              InteractiveShell.LoadAliases (current_namespace);
5473 //        }
5474 //        compilation_unit
5475         ;
5476 %%
5477
5478 // <summary>
5479 //   A class used to pass around variable declarations and constants
5480 // </summary>
5481 public class VariableDeclaration {
5482         public string identifier;
5483         public Expression expression_or_array_initializer;
5484         public Location Location;
5485         public Attributes OptAttributes;
5486         public string DocComment;
5487
5488         public VariableDeclaration (LocatedToken lt, object eoai, Attributes opt_attrs)
5489         {
5490                 this.identifier = lt.Value;
5491                 if (eoai is ArrayList) {
5492                         this.expression_or_array_initializer = new ArrayCreation (CSharpParser.current_array_type, "", (ArrayList)eoai, lt.Location);
5493                 } else {
5494                         this.expression_or_array_initializer = (Expression)eoai;
5495                 }
5496                 this.Location = lt.Location;
5497                 this.OptAttributes = opt_attrs;
5498         }
5499
5500         public VariableDeclaration (LocatedToken lt, object eoai) : this (lt, eoai, null)
5501         {
5502         }
5503 }
5504
5505 // <summary>
5506 //   A class used to hold info about an indexer declarator
5507 // </summary>
5508 public class IndexerDeclaration {
5509         public FullNamedExpression type;
5510         public MemberName interface_type;
5511         public Parameters param_list;
5512         public Location location;
5513
5514         public IndexerDeclaration (FullNamedExpression type, MemberName interface_type,
5515                                    Parameters param_list, Location loc)
5516         {
5517                 this.type = type;
5518                 this.interface_type = interface_type;
5519                 this.param_list = param_list;
5520                 this.location = loc;
5521         }
5522 }
5523
5524 // <summary>
5525 //  A class used to hold info about an operator declarator
5526 // </summary>
5527 struct OperatorDeclaration {
5528         public readonly Operator.OpType optype;
5529         public readonly FullNamedExpression ret_type;
5530         public readonly Location location;
5531
5532         public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
5533         {
5534                 optype = op;
5535                 this.ret_type = ret_type;
5536                 this.location = location;
5537         }
5538 }
5539
5540 void Error_ExpectingTypeName (Expression expr)
5541 {
5542         if (expr is Invocation){
5543                 Report.Error (1002, expr.Location, "Expecting `;'");
5544         } else {
5545                 expr.Error_InvalidExpressionStatement ();
5546         }
5547 }
5548
5549 static void Error_ParameterModifierNotValid (string modifier, Location loc)
5550 {
5551         Report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
5552                                       modifier);
5553 }
5554
5555 static void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
5556 {
5557         Report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
5558                 Parameter.GetModifierSignature (mod));
5559 }
5560
5561 static void Error_TypeExpected (Location loc)
5562 {
5563         Report.Error (1031, loc, "Type expected");
5564 }
5565
5566 void push_current_class (TypeContainer tc, object partial_token)
5567 {
5568         if (RootContext.EvalMode){
5569                 tc.ModFlags = (tc.ModFlags & ~(Modifiers.PRIVATE|Modifiers.INTERNAL)) | Modifiers.PUBLIC;
5570                 undo.AddTypeContainer (current_container, tc);
5571         }
5572
5573         if (partial_token != null)
5574                 current_container = current_container.AddPartial (tc);
5575         else
5576                 current_container = current_container.AddTypeContainer (tc);
5577
5578
5579         current_class = tc;
5580 }
5581
5582 DeclSpace pop_current_class ()
5583 {
5584         DeclSpace retval = current_class;
5585
5586         current_class = current_class.Parent;
5587         current_container = current_class.PartialContainer;
5588
5589         return retval;
5590 }
5591
5592 // <summary>
5593 //   Given the @class_name name, it creates a fully qualified name
5594 //   based on the containing declaration space
5595 // </summary>
5596 MemberName
5597 MakeName (MemberName class_name)
5598 {
5599         Namespace ns = current_namespace.NS;
5600
5601         if (current_container.Name.Length == 0){
5602                 if (ns.Name.Length != 0)
5603                         return new MemberName (ns.MemberName, class_name);
5604                 else
5605                         return class_name;
5606         } else {
5607                 return new MemberName (current_container.MemberName, class_name);
5608         }
5609 }
5610
5611 Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
5612 {
5613         Block implicit_block;
5614         ArrayList inits = null;
5615
5616         //
5617         // If we are doing interactive editing, we want variable declarations
5618         // that are in the top block to be added instead to the class as 
5619         // static variables
5620         //
5621         if (RootContext.StatementMode){
5622                 bool hoist = true;
5623
5624                 for (Block b = current_block; b != null; b = b.Parent){
5625                         if (b is ExplicitBlock && !(b is ToplevelBlock)){
5626                                 // There has been an explicit block, we cant add to the class
5627                                 hoist = false;
5628                                 break;
5629                         }
5630                 }               
5631                 if (hoist){
5632                         //
5633                         // We can use "current_block" since we know there are no explicit blocks
5634                         //
5635                         foreach (VariableDeclaration decl in variable_declarators){
5636                                 // We can not use the super-handy f.Initializer, because
5637                                 // multiple lines would force code to be executed out of sync
5638                                 if (decl.expression_or_array_initializer != null){
5639                                         string id = "$" + decl.identifier;
5640                                         current_block.AddVariable (type, id, decl.Location);                                    
5641
5642                                         LocalVariableReference var;
5643                                         var = new LocalVariableReferenceWithClassSideEffect (current_container, decl.identifier, current_block, id, decl.Location);
5644                                         Assign assign = new SimpleAssign (var, decl.expression_or_array_initializer, decl.Location);
5645                                         current_block.AddStatement (new StatementExpression (assign));
5646                                         assign = new SimpleAssign (new SimpleName (decl.identifier, decl.Location), var);
5647                                         current_block.AddStatement (new StatementExpression (assign));
5648                                 } else {
5649                                         Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.PUBLIC | Modifiers.STATIC, decl.identifier, null, loc);
5650                                         current_container.AddField (f);
5651
5652                                         // Register the field to be visible later as a global variable
5653                                         InteractiveShell.QueueField (f);
5654                                 }
5655                         }
5656
5657                         return current_block;
5658                 }
5659         }
5660
5661         //
5662         // We use the `Used' property to check whether statements
5663         // have been added to the current block.  If so, we need
5664         // to create another block to contain the new declaration
5665         // otherwise, as an optimization, we use the same block to
5666         // add the declaration.
5667         //
5668         // FIXME: A further optimization is to check if the statements
5669         // that were added were added as part of the initialization
5670         // below.  In which case, no other statements have been executed
5671         // and we might be able to reduce the number of blocks for
5672         // situations like this:
5673         //
5674         // int j = 1;  int k = j + 1;
5675         //
5676         if (current_block.Used)
5677                 implicit_block = new Block (current_block, loc, lexer.Location);
5678         else
5679                 implicit_block = current_block;
5680
5681         foreach (VariableDeclaration decl in variable_declarators){
5682
5683                 if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) {
5684                         if (decl.expression_or_array_initializer != null){
5685                                 if (inits == null)
5686                                         inits = new ArrayList (4);
5687                                 inits.Add (decl);
5688                         }
5689                 }
5690         }
5691
5692         if (inits == null)
5693                 return implicit_block;
5694
5695         foreach (VariableDeclaration decl in inits){
5696                 Assign assign;
5697                 Expression expr = decl.expression_or_array_initializer;
5698                 
5699                 LocalVariableReference var;
5700                 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
5701
5702                 assign = new SimpleAssign (var, expr, decl.Location);
5703
5704                 implicit_block.AddStatement (new StatementExpression (assign));
5705         }
5706         
5707         return implicit_block;
5708 }
5709
5710 Block declare_local_constants (Expression type, ArrayList declarators)
5711 {
5712         Block implicit_block;
5713
5714         if (current_block.Used)
5715                 implicit_block = new Block (current_block);
5716         else
5717                 implicit_block = current_block;
5718
5719         foreach (VariableDeclaration decl in declarators){
5720                 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer, decl.Location);
5721         }
5722         
5723         return implicit_block;
5724 }
5725
5726 string CheckAttributeTarget (string a, Location l)
5727 {
5728         switch (a) {
5729         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
5730                         return a;
5731         }
5732
5733         Report.Warning (658, 1, l,
5734                  "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
5735         return string.Empty;
5736 }
5737
5738 static bool IsUnaryOperator (Operator.OpType op)
5739 {
5740         switch (op) {
5741                 
5742         case Operator.OpType.LogicalNot: 
5743         case Operator.OpType.OnesComplement: 
5744         case Operator.OpType.Increment:
5745         case Operator.OpType.Decrement:
5746         case Operator.OpType.True: 
5747         case Operator.OpType.False: 
5748         case Operator.OpType.UnaryPlus: 
5749         case Operator.OpType.UnaryNegation:
5750                 return true;
5751         }
5752         return false;
5753 }
5754
5755 void syntax_error (Location l, string msg)
5756 {
5757         Report.Error (1003, l, "Syntax error, " + msg);
5758 }
5759
5760 void note (string s)
5761 {
5762         // Used to put annotations
5763 }
5764
5765 Tokenizer lexer;
5766
5767 public Tokenizer Lexer {
5768         get {
5769                 return lexer;
5770         }
5771 }                  
5772
5773 static CSharpParser ()
5774 {
5775         oob_stack = new Stack ();
5776 }
5777
5778 public CSharpParser (SeekableStreamReader reader, CompilationUnit file)
5779 {
5780         if (RootContext.EvalMode)
5781                 undo = new Undo ();
5782
5783         this.file = file;
5784         current_namespace = new NamespaceEntry (null, file, null);
5785         current_class = current_namespace.SlaveDeclSpace;
5786         current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
5787         oob_stack.Clear ();
5788         lexer = new Tokenizer (reader, file);
5789 }
5790
5791 public void parse ()
5792 {
5793         eof_token = Token.EOF;
5794
5795         try {
5796                 if (yacc_verbose_flag > 1)
5797                         yyparse (lexer, new yydebug.yyDebugSimple ());
5798                 else
5799                         yyparse (lexer);
5800         } catch (Exception e){
5801                 if (e is yyParser.yyUnexpectedEof)
5802                         UnexpectedEOF = true;
5803                 else if (yacc_verbose_flag > 0)
5804                         Console.WriteLine (e);
5805                 if (e is yyParser.yyException)
5806                         Report.Error (-25, lexer.Location, "Parsing error");
5807                 else 
5808                         Report.Error (-32, lexer.Location, "Internal compiler error during parsing, Run with -v for details");
5809         }
5810         Tokenizer tokenizer = lexer as Tokenizer;
5811         tokenizer.cleanup ();
5812
5813         if (RootContext.ToplevelTypes.NamespaceEntry != null)
5814                 throw new InternalErrorException ("who set it?");
5815 }
5816
5817 static void CheckToken (int error, int yyToken, string msg, Location loc)
5818 {
5819         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
5820                 Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ());
5821         else
5822                 Report.Error (error, loc, msg);
5823 }
5824
5825 void CheckIdentifierToken (int yyToken, Location loc)
5826 {
5827         CheckToken (1041, yyToken, "Identifier expected", loc);
5828 }
5829
5830 string ConsumeStoredComment ()
5831 {
5832         string s = tmpComment;
5833         tmpComment = null;
5834         Lexer.doc_state = XmlCommentState.Allowed;
5835         return s;
5836 }
5837
5838 Location GetLocation (object obj)
5839 {
5840         if (obj is MemberCore)
5841                 return ((MemberCore) obj).Location;
5842         if (obj is MemberName)
5843                 return ((MemberName) obj).Location;
5844         if (obj is LocatedToken)
5845                 return ((LocatedToken) obj).Location;
5846         if (obj is Location)
5847                 return (Location) obj;
5848         return lexer.Location;
5849 }
5850
5851 void start_block (Location loc)
5852 {
5853         if (current_block == null || parsing_anonymous_method) {
5854                 current_block = new ToplevelBlock (current_block, current_local_parameters, current_generic_method, loc);
5855                 parsing_anonymous_method = false;
5856         } else {
5857                 current_block = new ExplicitBlock (current_block, loc, Location.Null);
5858         }
5859 }
5860
5861 Block
5862 end_block (Location loc)
5863 {
5864         Block retval = current_block.Explicit;
5865         retval.SetEndLocation (loc);
5866         current_block = retval.Parent;
5867         return retval;
5868 }
5869
5870 void
5871 start_anonymous (bool lambda, Parameters parameters, Location loc)
5872 {
5873         oob_stack.Push (current_anonymous_method);
5874         oob_stack.Push (current_local_parameters);
5875
5876         current_local_parameters = parameters;
5877
5878         current_anonymous_method = lambda 
5879                 ? new LambdaExpression (parameters, loc) 
5880                 : new AnonymousMethodExpression (parameters, loc);
5881
5882         // Force the next block to be created as a ToplevelBlock
5883         parsing_anonymous_method = true;
5884 }
5885
5886 /*
5887  * Completes the anonymous method processing, if lambda_expr is null, this
5888  * means that we have a Statement instead of an Expression embedded 
5889  */
5890 AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block, Location loc)
5891 {
5892         AnonymousMethodExpression retval;
5893
5894         if (RootContext.Version == LanguageVersion.ISO_1){
5895                 Report.FeatureIsNotAvailable (loc, "anonymous methods");
5896                 retval = null;
5897         } else  {
5898                 current_anonymous_method.Block = anon_block;
5899                 retval = current_anonymous_method;
5900         }
5901
5902         current_local_parameters = (Parameters) oob_stack.Pop ();
5903         current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
5904
5905         return retval;
5906 }
5907
5908 public NamespaceEntry CurrentNamespace {
5909        get { 
5910            return current_namespace;
5911        }
5912 }
5913
5914 /* end end end */
5915 }