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