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