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