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