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