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