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