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