[mcs] Fix parsing member access expression with await simple name
[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@gnome.org)
6 //          Ravi Pratap     (ravi@ximian.com)
7 //          Marek Safar     (marek.safar@gmail.com)
8 //
9 // Dual Licensed under the terms of the GNU GPL and the MIT X11 license
10 //
11 // (C) 2001 Ximian, Inc (http://www.ximian.com)
12 // (C) 2004-2011 Novell, Inc
13 // Copyright 2011-2012 Xamarin Inc.
14 //
15
16 using System.Text;
17 using System.IO;
18 using System;
19 using System.Collections.Generic;
20
21 namespace Mono.CSharp
22 {
23         /// <summary>
24         ///    The C# Parser
25         /// </summary>
26         public class CSharpParser
27         {
28                 [Flags]
29                 enum ParameterModifierType
30                 {
31                         Ref             = 1 << 1,
32                         Out             = 1 << 2,
33                         This    = 1 << 3,
34                         Params  = 1 << 4,
35                         Arglist = 1 << 5,
36                         DefaultValue = 1 << 6,
37                         
38                         All = Ref | Out | This | Params | Arglist | DefaultValue,
39                         PrimaryConstructor = Ref | Out | Params | DefaultValue
40                 }
41                 
42                 static readonly object ModifierNone = 0;
43         
44                 NamespaceContainer current_namespace;
45                 TypeContainer current_container;
46                 TypeDefinition current_type;
47                 PropertyBase current_property;
48                 EventProperty current_event;
49                 EventField current_event_field;
50                 FieldBase current_field;
51         
52                 /// <summary>
53                 ///   Current block is used to add statements as we find
54                 ///   them.  
55                 /// </summary>
56                 Block      current_block;
57                 
58                 BlockVariable current_variable;
59
60                 Delegate   current_delegate;
61                 
62                 AnonymousMethodExpression current_anonymous_method;
63
64                 /// <summary>
65                 ///   This is used by the unary_expression code to resolve
66                 ///   a name against a parameter.  
67                 /// </summary>
68                 
69                 // FIXME: This is very ugly and it's very hard to reset it correctly
70                 // on all places, especially when some parameters are autogenerated.
71                 ParametersCompiled current_local_parameters;
72
73                 bool parsing_anonymous_method;
74                 
75                 bool async_block;
76
77                 ///
78                 /// An out-of-band stack.
79                 ///
80                 Stack<object> oob_stack;
81
82                 ///
83                 /// Controls the verbosity of the errors produced by the parser
84                 ///
85                 int yacc_verbose_flag;
86
87                 /// 
88                 /// Used by the interactive shell, flags whether EOF was reached
89                 /// and an error was produced
90                 ///
91                 public bool UnexpectedEOF;
92
93                 ///
94                 /// The current file.
95                 ///
96                 readonly CompilationSourceFile file;
97
98                 ///
99                 /// Temporary Xml documentation cache.
100                 /// For enum types, we need one more temporary store.
101                 ///
102                 string tmpComment;
103                 string enumTypeComment;
104                         
105                 /// Current attribute target
106                 string current_attr_target;
107                 
108                 ParameterModifierType valid_param_mod;
109                 
110                 bool default_parameter_used;
111
112                 /// When using the interactive parser, this holds the
113                 /// resulting expression
114                 public Class InteractiveResult;
115
116                 //
117                 // Keeps track of global data changes to undo on parser error
118                 //
119                 public Undo undo;
120
121                 bool? interactive_async;
122                 
123                 Stack<Linq.QueryBlock> linq_clause_blocks;
124
125                 ModuleContainer module;
126                 
127                 readonly CompilerContext compiler;
128                 readonly LanguageVersion lang_version;
129                 readonly bool doc_support;
130                 readonly CompilerSettings settings;
131                 readonly Report report;
132                 
133                 //
134                 // Instead of allocating carrier array everytime we
135                 // share the bucket for very common constructs which can never
136                 // be recursive
137                 //
138                 List<Parameter> parameters_bucket;
139                 
140                 //
141                 // Full AST support members
142                 //
143                 LocationsBag lbag;
144                 List<Tuple<Modifiers, Location>> mod_locations;
145                 Stack<Location> location_stack;
146 %}
147
148 %token EOF
149 %token NONE   /* This token is never returned by our lexer */
150 %token ERROR            // This is used not by the parser, but by the tokenizer.
151                         // do not remove.
152
153 /*
154  *These are the C# keywords
155  */
156 %token FIRST_KEYWORD
157 %token ABSTRACT 
158 %token AS
159 %token ADD
160 %token BASE     
161 %token BOOL     
162 %token BREAK    
163 %token BYTE     
164 %token CASE     
165 %token CATCH    
166 %token CHAR     
167 %token CHECKED  
168 %token CLASS    
169 %token CONST    
170 %token CONTINUE 
171 %token DECIMAL  
172 %token DEFAULT  
173 %token DELEGATE 
174 %token DO       
175 %token DOUBLE   
176 %token ELSE     
177 %token ENUM     
178 %token EVENT    
179 %token EXPLICIT 
180 %token EXTERN   
181 %token FALSE    
182 %token FINALLY  
183 %token FIXED    
184 %token FLOAT    
185 %token FOR      
186 %token FOREACH  
187 %token GOTO     
188 %token IF       
189 %token IMPLICIT 
190 %token IN       
191 %token INT      
192 %token INTERFACE
193 %token INTERNAL 
194 %token IS       
195 %token LOCK     
196 %token LONG     
197 %token NAMESPACE
198 %token NEW      
199 %token NULL     
200 %token OBJECT   
201 %token OPERATOR 
202 %token OUT      
203 %token OVERRIDE 
204 %token PARAMS   
205 %token PRIVATE  
206 %token PROTECTED
207 %token PUBLIC   
208 %token READONLY 
209 %token REF      
210 %token RETURN   
211 %token REMOVE
212 %token SBYTE    
213 %token SEALED   
214 %token SHORT    
215 %token SIZEOF   
216 %token STACKALLOC
217 %token STATIC   
218 %token STRING   
219 %token STRUCT   
220 %token SWITCH   
221 %token THIS     
222 %token THROW    
223 %token TRUE     
224 %token TRY      
225 %token TYPEOF   
226 %token UINT     
227 %token ULONG    
228 %token UNCHECKED
229 %token UNSAFE   
230 %token USHORT   
231 %token USING    
232 %token VIRTUAL  
233 %token VOID     
234 %token VOLATILE
235 %token WHERE
236 %token WHILE    
237 %token ARGLIST
238 %token PARTIAL
239 %token ARROW
240 %token FROM
241 %token FROM_FIRST
242 %token JOIN
243 %token ON
244 %token EQUALS
245 %token SELECT
246 %token GROUP
247 %token BY
248 %token LET
249 %token ORDERBY
250 %token ASCENDING
251 %token DESCENDING
252 %token INTO
253 %token INTERR_NULLABLE
254 %token EXTERN_ALIAS
255 %token REFVALUE
256 %token REFTYPE
257 %token MAKEREF
258 %token ASYNC
259 %token AWAIT
260
261 /* C# keywords which are not really keywords */
262 %token GET
263 %token SET
264
265 %left LAST_KEYWORD
266
267 /* C# single character operators/punctuation. */
268 %token OPEN_BRACE
269 %token CLOSE_BRACE
270 %token OPEN_BRACKET
271 %token CLOSE_BRACKET
272 %token OPEN_PARENS
273 %token CLOSE_PARENS
274
275 %token DOT
276 %token COMMA
277 %token COLON
278 %token SEMICOLON
279 %token TILDE
280
281 %token PLUS
282 %token MINUS
283 %token BANG
284 %token ASSIGN
285 %token OP_LT
286 %token OP_GT
287 %token BITWISE_AND
288 %token BITWISE_OR
289 %token STAR
290 %token PERCENT
291 %token DIV
292 %token CARRET
293 %token INTERR
294
295 /* C# multi-character operators. */
296 %token DOUBLE_COLON
297 %token OP_INC
298 %token OP_DEC
299 %token OP_SHIFT_LEFT
300 %token OP_SHIFT_RIGHT
301 %token OP_LE
302 %token OP_GE
303 %token OP_EQ
304 %token OP_NE
305 %token OP_AND
306 %token OP_OR
307 %token OP_MULT_ASSIGN
308 %token OP_DIV_ASSIGN
309 %token OP_MOD_ASSIGN
310 %token OP_ADD_ASSIGN
311 %token OP_SUB_ASSIGN
312 %token OP_SHIFT_LEFT_ASSIGN
313 %token OP_SHIFT_RIGHT_ASSIGN
314 %token OP_AND_ASSIGN
315 %token OP_XOR_ASSIGN
316 %token OP_OR_ASSIGN
317 %token OP_PTR
318 %token OP_COALESCING
319
320 /* Generics <,> tokens */
321 %token OP_GENERICS_LT
322 %token OP_GENERICS_LT_DECL
323 %token OP_GENERICS_GT
324
325 %token LITERAL
326
327 %token IDENTIFIER
328 %token OPEN_PARENS_LAMBDA
329 %token OPEN_PARENS_CAST
330 %token GENERIC_DIMENSION
331 %token DEFAULT_COLON
332 %token OPEN_BRACKET_EXPR
333
334 // Make the parser go into eval mode parsing (statements and compilation units).
335 %token EVAL_STATEMENT_PARSER
336 %token EVAL_COMPILATION_UNIT_PARSER
337 %token EVAL_USING_DECLARATIONS_UNIT_PARSER
338
339 %token DOC_SEE
340
341 // 
342 // This token is generated to trigger the completion engine at this point
343 //
344 %token GENERATE_COMPLETION
345
346 //
347 // This token is return repeatedly after the first GENERATE_COMPLETION
348 // token is produced and before the final EOF
349 //
350 %token COMPLETE_COMPLETION
351
352 /* Add precedence rules to solve dangling else s/r conflict */
353 %nonassoc IF
354 %nonassoc ELSE
355
356 /* Define the operator tokens and their precedences */
357 %right ASSIGN
358 %right OP_COALESCING
359 %right INTERR
360 %left OP_OR
361 %left OP_AND
362 %left BITWISE_OR
363 %left BITWISE_AND
364 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
365 %left PLUS MINUS
366 %left STAR DIV PERCENT
367 %right BANG CARRET UMINUS
368 %nonassoc OP_INC OP_DEC
369 %left OPEN_PARENS
370 %left OPEN_BRACKET OPEN_BRACE
371 %left DOT
372
373 %start compilation_unit
374 %%
375
376 compilation_unit
377         : outer_declaration opt_EOF
378           {
379                 Lexer.check_incorrect_doc_comment ();
380           }
381         | interactive_parsing  { Lexer.CompleteOnEOF = false; } opt_EOF
382         | documentation_parsing
383         ;
384         
385 outer_declaration
386         : opt_extern_alias_directives opt_using_directives
387         | opt_extern_alias_directives opt_using_directives namespace_or_type_declarations opt_attributes
388           {
389                 if ($4 != null) {
390                         Attributes attrs = (Attributes) $4;
391                         report.Error (1730, attrs.Attrs [0].Location,
392                                 "Assembly and module attributes must precede all other elements except using clauses and extern alias declarations");
393
394                         current_namespace.UnattachedAttributes = attrs;
395                 }
396           }
397         | opt_extern_alias_directives opt_using_directives attribute_sections
398           {
399                 module.AddAttributes ((Attributes) $3, current_namespace);
400           }
401         | error
402           {
403                 if (yyToken == Token.EXTERN_ALIAS)
404                         report.Error (439, lexer.Location, "An extern alias declaration must precede all other elements");
405                 else
406                         Error_SyntaxError (yyToken);
407           }
408         ;
409         
410 opt_EOF
411         : /* empty */
412         | EOF
413         ;
414
415 extern_alias_directives
416         : extern_alias_directive
417         | extern_alias_directives extern_alias_directive
418         ;
419
420 extern_alias_directive
421         : EXTERN_ALIAS IDENTIFIER IDENTIFIER SEMICOLON
422           {
423                 var lt = (LocatedToken) $2;
424                 string s = lt.Value;
425                 if (s != "alias") {
426                         syntax_error (lt.Location, "`alias' expected");
427                 } else {
428                         if (lang_version == LanguageVersion.ISO_1)
429                                 FeatureIsNotAvailable (lt.Location, "external alias");
430
431                         lt = (LocatedToken) $3;
432                         if (lt.Value == QualifiedAliasMember.GlobalAlias) {
433                                 RootNamespace.Error_GlobalNamespaceRedefined (report, lt.Location);
434                         }
435                         
436                         var na = new UsingExternAlias (new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
437                         current_namespace.AddUsing (na);
438                         
439                         lbag.AddLocation (na, GetLocation ($2), GetLocation ($4));
440                 }
441           }
442         | EXTERN_ALIAS error
443           {
444                 Error_SyntaxError (yyToken);
445           }
446         ;
447  
448 using_directives
449         : using_directive 
450         | using_directives using_directive
451         ;
452
453 using_directive
454         : using_namespace
455           {
456                 if (doc_support)
457                         Lexer.doc_state = XmlCommentState.Allowed;
458           }
459         ;
460
461 using_namespace
462         : USING namespace_or_type_expr SEMICOLON 
463           {
464                 var un = new UsingNamespace ((ATypeNameExpression) $2, GetLocation ($1));
465                 current_namespace.AddUsing (un);
466                 
467                 lbag.AddLocation (un, GetLocation ($3));
468           }
469         | USING IDENTIFIER ASSIGN namespace_or_type_expr SEMICOLON
470           {
471                 var lt = (LocatedToken) $2;
472                 if (lang_version != LanguageVersion.ISO_1 && lt.Value == "global") {
473                         report.Warning (440, 2, lt.Location,
474                          "An alias named `global' will not be used when resolving `global::'. The global namespace will be used instead");
475                 }
476
477                 var un = new UsingAliasNamespace (new SimpleMemberName (lt.Value, lt.Location), (ATypeNameExpression) $4, GetLocation ($1));
478                 current_namespace.AddUsing (un);
479                 
480                 lbag.AddLocation (un, GetLocation ($3), GetLocation ($5));
481           }
482         | USING error
483          {
484                 Error_SyntaxError (yyToken);
485                 $$ = null;
486          }
487         ;
488
489 //
490 // Strictly speaking, namespaces don't have attributes but
491 // we parse global attributes along with namespace declarations and then
492 // detach them
493 // 
494 namespace_declaration
495         : opt_attributes NAMESPACE namespace_name
496           {
497                 Attributes attrs = (Attributes) $1;
498                 var name = (MemberName) $3;
499                 if (attrs != null) {
500                         bool valid_global_attrs = true;
501                         if ((current_namespace.DeclarationFound || current_namespace != file)) {
502                                 valid_global_attrs = false;
503                         } else {
504                                 foreach (var a in attrs.Attrs) {
505                                         if (a.ExplicitTarget == "assembly" || a.ExplicitTarget == "module")
506                                                 continue;
507                                                 
508                                         valid_global_attrs = false;
509                                         break;
510                                 }
511                         }
512                         
513                         if (!valid_global_attrs)
514                                 report.Error (1671, name.Location, "A namespace declaration cannot have modifiers or attributes");
515                 }
516         
517                 module.AddAttributes (attrs, current_namespace);
518                 
519                 var ns = new NamespaceContainer (name, current_namespace);
520                 current_namespace.AddTypeContainer (ns);
521                 current_container = current_namespace = ns;
522           }
523           OPEN_BRACE
524           {
525                 if (doc_support)
526                         Lexer.doc_state = XmlCommentState.Allowed;
527           }
528           opt_extern_alias_directives opt_using_directives opt_namespace_or_type_declarations CLOSE_BRACE opt_semicolon_error
529           {
530                 if ($11 != null)
531                         lbag.AddLocation (current_container, GetLocation ($2), GetLocation ($5), GetLocation ($10), GetLocation ($11));
532                 else
533                         lbag.AddLocation (current_container, GetLocation ($2), GetLocation ($5), GetLocation ($10));
534           
535                 current_container = current_namespace = current_namespace.Parent;
536           }
537         | opt_attributes NAMESPACE namespace_name
538           {
539                 report.Error (1514, lexer.Location, "Unexpected symbol `{0}', expecting `.' or `{{'", GetSymbolName (yyToken));
540
541                 var name = (MemberName) $3;             
542                 var ns = new NamespaceContainer (name, current_namespace);
543                 lbag.AddLocation (ns, GetLocation ($2));
544                 current_namespace.AddTypeContainer (ns);
545           }
546         ;
547
548 opt_semicolon_error
549         : /* empty */
550         | SEMICOLON
551         | error
552           {
553                 Error_SyntaxError (yyToken);
554                 $$ = null;
555           }
556         ;
557
558 namespace_name
559         : IDENTIFIER
560           {
561                 var lt = (LocatedToken) $1;
562                 $$ = new MemberName (lt.Value, lt.Location);
563           }
564         | namespace_name DOT IDENTIFIER
565           {
566                 var lt = (LocatedToken) $3;
567                 $$ = new MemberName ((MemberName) $1, lt.Value, lt.Location);           
568                 lbag.AddLocation ($$, GetLocation ($2));
569           }
570         | error
571           {
572                 Error_SyntaxError (yyToken);
573                 $$ = new MemberName ("<invalid>", lexer.Location);
574           }
575         ;
576
577 opt_semicolon
578         : /* empty */
579         | SEMICOLON
580         ;
581
582 opt_comma
583         : /* empty */
584         | COMMA
585         ;
586
587 opt_using_directives
588         : /* empty */
589         | using_directives
590         ;
591
592 opt_extern_alias_directives
593         : /* empty */
594         | extern_alias_directives
595         ;
596
597 opt_namespace_or_type_declarations
598         : /* empty */
599         | namespace_or_type_declarations
600         ;
601
602 namespace_or_type_declarations
603         : namespace_or_type_declaration
604         | namespace_or_type_declarations namespace_or_type_declaration
605         ;
606
607 namespace_or_type_declaration
608         : type_declaration
609           {
610                 if ($1 != null) {
611                         TypeContainer ds = (TypeContainer)$1;
612
613                         if ((ds.ModFlags & (Modifiers.PRIVATE | Modifiers.PROTECTED)) != 0){
614                                 report.Error (1527, ds.Location, 
615                                 "Namespace elements cannot be explicitly declared as private, protected or protected internal");
616                         }
617
618                         // Here is a trick, for explicit attributes we don't know where they belong to until
619                         // we parse succeeding declaration hence we parse them as normal and re-attach them
620                         // when we know whether they are global (assembly:, module:) or local (type:).
621                         if (ds.OptAttributes != null) {
622                                 ds.OptAttributes.ConvertGlobalAttributes (ds, current_namespace, !current_namespace.DeclarationFound && current_namespace == file);
623                         }
624                 }
625                 current_namespace.DeclarationFound = true;
626           }
627         | namespace_declaration
628           {
629                 current_namespace.DeclarationFound = true;
630           }
631         | attribute_sections CLOSE_BRACE {
632                 current_namespace.UnattachedAttributes = (Attributes) $1;
633                 report.Error (1518, lexer.Location, "Attributes must be attached to class, delegate, enum, interface or struct");
634                 lexer.putback ('}');
635           }
636         ;
637
638 type_declaration
639         : class_declaration             
640         | struct_declaration
641         | interface_declaration
642         | enum_declaration              
643         | delegate_declaration
644 //
645 // Enable this when we have handled all errors, because this acts as a generic fallback
646 //
647 //      | error {
648 //              Console.WriteLine ("Token=" + yyToken);
649 //              report.Error (1518, GetLocation ($1), "Expected class, struct, interface, enum or delegate");
650 //        }
651         ;
652
653 //
654 // Attributes
655 //
656
657 opt_attributes
658         : /* empty */ 
659         | attribute_sections
660     ;
661  
662 attribute_sections
663         : attribute_section
664           {
665                 var sect = (List<Attribute>) $1;
666                 $$ = new Attributes (sect);
667           }
668         | attribute_sections attribute_section
669           {
670                 Attributes attrs = $1 as Attributes;
671                 var sect = (List<Attribute>) $2;
672                 if (attrs == null)
673                         attrs = new Attributes (sect);
674                 else if (sect != null)
675                         attrs.AddAttributes (sect);
676                 $$ = attrs;
677           }
678         ;
679         
680 attribute_section
681         : OPEN_BRACKET
682           {
683                 PushLocation (GetLocation ($1));
684                 lexer.parsing_attribute_section = true;
685           }
686           attribute_section_cont
687           {
688                 lexer.parsing_attribute_section = false;
689                 $$ = $3;
690           }
691         ;       
692         
693 attribute_section_cont
694         : attribute_target COLON
695           {
696                 current_attr_target = (string) $1;
697                 if (current_attr_target == "assembly" || current_attr_target == "module") {
698                         Lexer.check_incorrect_doc_comment ();
699                 }
700           }
701           attribute_list opt_comma CLOSE_BRACKET
702           {
703                 // when attribute target is invalid
704                 if (current_attr_target == string.Empty)
705                         $$ = new List<Attribute> (0);
706                 else
707                         $$ = $4;
708
709                 lbag.InsertLocation ($$, 0, PopLocation ());
710                 if ($5 != null) {
711                         lbag.AddLocation ($$, GetLocation ($2), GetLocation ($5), GetLocation ($6));
712                 } else {
713                         lbag.AddLocation ($$, GetLocation ($2), GetLocation ($6));
714                 }
715
716                 current_attr_target = null;
717                 lexer.parsing_attribute_section = false;
718           }
719         | attribute_list opt_comma CLOSE_BRACKET
720           {
721                 $$ = $1;
722
723                 lbag.InsertLocation ($$, 0, PopLocation ());
724                 if ($2 != null) {
725                         lbag.AddLocation ($$, GetLocation($2), GetLocation ($3));
726                 } else {
727                         lbag.AddLocation ($$, GetLocation($3));
728                 }
729           }
730         | IDENTIFIER error
731           {
732                 Error_SyntaxError (yyToken);
733
734                 var lt = (LocatedToken) $1;
735                 var tne = new SimpleName (lt.Value, null, lt.Location);
736
737                 $$ = new List<Attribute> () {
738                         new Attribute (null, tne, null, GetLocation ($1), false)
739                 };
740           }
741         | error
742           {
743                 CheckAttributeTarget (yyToken, GetTokenName (yyToken), GetLocation ($1)); 
744                 $$ = null;
745           }
746         ;       
747
748 attribute_target
749         : IDENTIFIER
750           {
751                 var lt = (LocatedToken) $1;
752                 $$ = CheckAttributeTarget (yyToken, lt.Value, lt.Location);
753           }
754         | EVENT  { $$ = "event"; }
755         | RETURN { $$ = "return"; }
756         ;
757
758 attribute_list
759         : attribute
760           {
761                 $$ = new List<Attribute> (4) { (Attribute) $1 };
762           }
763         | attribute_list COMMA attribute
764           {
765                 var attrs = (List<Attribute>) $1;
766                 if (attrs != null) {
767                         attrs.Add ((Attribute) $3);
768                         lbag.AppendTo (attrs, GetLocation ($2));
769                 }
770
771                 $$ = attrs;
772           }
773         ;
774
775 attribute
776         : attribute_name
777           {
778                 ++lexer.parsing_block;
779           }
780           opt_attribute_arguments
781           {
782                 --lexer.parsing_block;
783                 
784                 var tne = (ATypeNameExpression) $1;
785                 if (tne.HasTypeArguments) {
786                         report.Error (404, tne.Location, "Attributes cannot be generic");
787                 }
788
789                 $$ = new Attribute (current_attr_target, tne, (Arguments[]) $3, GetLocation ($1), lexer.IsEscapedIdentifier (tne));
790           }
791         ;
792
793 attribute_name
794         : namespace_or_type_expr
795         ;
796
797 opt_attribute_arguments
798         : /* empty */   { $$ = null; }
799         | OPEN_PARENS attribute_arguments CLOSE_PARENS
800           {
801                 $$ = $2;
802           }
803         ;
804
805
806 attribute_arguments
807         : /* empty */           { $$ = null; } 
808         | positional_or_named_argument
809           {
810                 Arguments a = new Arguments (4);
811                 a.Add ((Argument) $1);
812                 $$ = new Arguments [] { a, null };
813           }
814         | named_attribute_argument
815           {
816                 Arguments a = new Arguments (4);
817                 a.Add ((Argument) $1);  
818                 $$ = new Arguments [] { null, a };
819           }
820     | attribute_arguments COMMA positional_or_named_argument
821           {
822                 Arguments[] o = (Arguments[]) $1;
823                 if (o [1] != null) {
824                         report.Error (1016, ((Argument) $3).Expr.Location, "Named attribute arguments must appear after the positional arguments");
825                         o [0] = new Arguments (4);
826                 }
827                 
828                 Arguments args = ((Arguments) o [0]);
829                 if (args.Count > 0 && !($3 is NamedArgument) && args [args.Count - 1] is NamedArgument)
830                         Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
831                 
832                 args.Add ((Argument) $3);
833           }
834     | attribute_arguments COMMA named_attribute_argument
835           {
836                 Arguments[] o = (Arguments[]) $1;
837                 if (o [1] == null) {
838                         o [1] = new Arguments (4);
839                 }
840
841                 ((Arguments) o [1]).Add ((Argument) $3);
842           }
843     ;
844
845 positional_or_named_argument
846         : expression
847           {
848                 $$ = new Argument ((Expression) $1);
849           }
850         | named_argument
851         | error
852           {
853                 Error_SyntaxError (yyToken);
854                 $$ = null;
855           }
856         ;
857
858 named_attribute_argument
859         : IDENTIFIER ASSIGN
860           {
861                 ++lexer.parsing_block;
862           }
863           expression
864           {
865                 --lexer.parsing_block;
866                 var lt = (LocatedToken) $1;
867                 $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4);          
868                 lbag.AddLocation ($$, GetLocation($2));
869           }
870         ;
871         
872 named_argument
873         : identifier_inside_body COLON opt_named_modifier expression_or_error
874           {
875                 if (lang_version <= LanguageVersion.V_3)
876                         FeatureIsNotAvailable (GetLocation ($1), "named argument");
877                         
878                 // Avoid boxing in common case (no modifier)
879                 var arg_mod = $3 == null ? Argument.AType.None : (Argument.AType) $3;
880                         
881                 var lt = (LocatedToken) $1;
882                 $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4, arg_mod);
883                 lbag.AddLocation ($$, GetLocation($2));
884           }
885         ;
886         
887 opt_named_modifier
888         : /* empty */   { $$ = null; }
889         | REF
890           { 
891                 $$ = Argument.AType.Ref;
892           }
893         | OUT
894           { 
895                 $$ = Argument.AType.Out;
896           }
897         ;
898                   
899 opt_class_member_declarations
900         : /* empty */
901         | class_member_declarations
902         ;
903
904 class_member_declarations
905         : class_member_declaration
906           {
907                 lexer.parsing_modifiers = true;
908                 lexer.parsing_block = 0;
909           }
910         | class_member_declarations class_member_declaration
911           {
912                 lexer.parsing_modifiers = true;
913                 lexer.parsing_block = 0;
914           }
915         ;
916         
917 class_member_declaration
918         : constant_declaration
919         | field_declaration
920         | method_declaration
921         | property_declaration
922         | event_declaration
923         | indexer_declaration
924         | operator_declaration
925         | constructor_declaration
926         | destructor_declaration
927         | type_declaration
928         | attributes_without_members
929         | incomplete_member
930         | error
931           {
932                 report.Error (1519, lexer.Location, "Unexpected symbol `{0}' in class, struct, or interface member declaration",
933                         GetSymbolName (yyToken));
934                 $$ = null;
935                 lexer.parsing_generic_declaration = false;
936           }     
937         ;
938
939 struct_declaration
940         : opt_attributes
941           opt_modifiers
942           opt_partial
943           STRUCT
944           {
945           }
946           type_declaration_name
947           { 
948                 lexer.ConstraintsParsing = true;
949                 valid_param_mod = ParameterModifierType.PrimaryConstructor;
950                 push_current_container (new Struct (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3);
951           }
952           opt_primary_parameters
953           opt_class_base
954           opt_type_parameter_constraints_clauses
955           {
956                 valid_param_mod = 0;
957                 lexer.ConstraintsParsing = false;
958
959                 if ($8 != null)
960                         current_type.PrimaryConstructorParameters = (ParametersCompiled) $8;
961
962                 if ($10 != null)
963                         current_container.SetConstraints ((List<Constraints>) $10);
964
965                 if (doc_support)
966                         current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
967
968                 lbag.AddMember (current_container, mod_locations, GetLocation ($4));
969                 
970                 lexer.parsing_modifiers = true;
971           }
972           OPEN_BRACE
973           {
974                 if (doc_support)
975                         Lexer.doc_state = XmlCommentState.Allowed;
976           }
977           opt_class_member_declarations CLOSE_BRACE
978           {
979                 --lexer.parsing_declaration;
980                 if (doc_support)
981                         Lexer.doc_state = XmlCommentState.Allowed;
982           }
983           opt_semicolon
984           {
985                 if ($16 == null) {
986                         lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15));
987                 } else {
988                         lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15), GetLocation ($17));
989                 }
990                 $$ = pop_current_class ();
991           }
992         | opt_attributes opt_modifiers opt_partial STRUCT error
993           {
994                 Error_SyntaxError (yyToken);
995           }
996         ;
997         
998 constant_declaration
999         : opt_attributes 
1000           opt_modifiers
1001           CONST type IDENTIFIER
1002           {
1003                 var lt = (LocatedToken) $5;
1004                 var mod = (Modifiers) $2;
1005                 current_field = new Const (current_type, (FullNamedExpression) $4, mod, new MemberName (lt.Value, lt.Location), (Attributes) $1);
1006                 current_type.AddMember (current_field);
1007                 
1008                 if ((mod & Modifiers.STATIC) != 0) {
1009                         report.Error (504, current_field.Location, "The constant `{0}' cannot be marked static", current_field.GetSignatureForError ());
1010                 }
1011                 
1012                 $$ = current_field;
1013           }
1014           constant_initializer opt_constant_declarators SEMICOLON
1015           {
1016                 if (doc_support) {
1017                         current_field.DocComment = Lexer.consume_doc_comment ();
1018                         Lexer.doc_state = XmlCommentState.Allowed;
1019                 }
1020                 
1021                 current_field.Initializer = (ConstInitializer) $7;
1022                 lbag.AddMember (current_field, mod_locations, GetLocation ($3), GetLocation ($9));
1023                 current_field = null;
1024           }
1025         | opt_attributes 
1026           opt_modifiers
1027           CONST type error
1028           {
1029                 Error_SyntaxError (yyToken);
1030
1031                 current_type.AddMember (new Const (current_type, (FullNamedExpression) $4, (Modifiers) $2, MemberName.Null, (Attributes) $1));
1032           }     
1033         ;
1034         
1035 opt_constant_declarators
1036         : /* empty */
1037         | constant_declarators
1038         ;
1039         
1040 constant_declarators
1041         : constant_declarator
1042           {
1043                 current_field.AddDeclarator ((FieldDeclarator) $1);
1044           }
1045         | constant_declarators constant_declarator
1046           {
1047                 current_field.AddDeclarator ((FieldDeclarator) $2);
1048           }
1049         ;
1050         
1051 constant_declarator
1052         : COMMA IDENTIFIER constant_initializer
1053           {
1054                 var lt = (LocatedToken) $2;
1055                 $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3);
1056                 lbag.AddLocation ($$, GetLocation ($1));
1057           }
1058         ;               
1059
1060 constant_initializer
1061         : ASSIGN
1062           {
1063                 ++lexer.parsing_block;
1064           }
1065           constant_initializer_expr
1066           {
1067                 --lexer.parsing_block;
1068                 $$ = new ConstInitializer (current_field, (Expression) $3, GetLocation ($1));
1069           }
1070         | error
1071           {
1072                 report.Error (145, lexer.Location, "A const field requires a value to be provided");
1073                 $$ = null;
1074           }       
1075         ;
1076         
1077 constant_initializer_expr
1078         : constant_expression
1079         | array_initializer
1080         ;
1081
1082 field_declaration
1083         : opt_attributes
1084           opt_modifiers
1085           member_type IDENTIFIER
1086           {
1087                 lexer.parsing_generic_declaration = false;
1088
1089                 FullNamedExpression type = (FullNamedExpression) $3;
1090                 if (type.Type != null && type.Type.Kind == MemberKind.Void)
1091                         report.Error (670, GetLocation ($3), "Fields cannot have void type");
1092                         
1093                 var lt = (LocatedToken) $4;
1094                 current_field = new Field (current_type, type, (Modifiers) $2, new MemberName (lt.Value, lt.Location), (Attributes) $1);
1095                 current_type.AddField (current_field);
1096                 $$ = current_field;
1097           }
1098           opt_field_initializer
1099           opt_field_declarators
1100           SEMICOLON
1101           { 
1102                 if (doc_support) {
1103                         current_field.DocComment = Lexer.consume_doc_comment ();
1104                         Lexer.doc_state = XmlCommentState.Allowed;
1105                 }
1106                         
1107                 lbag.AddMember (current_field, mod_locations, GetLocation ($8));
1108                 $$ = current_field;
1109                 current_field = null;
1110           }
1111         | opt_attributes
1112           opt_modifiers
1113           FIXED simple_type IDENTIFIER
1114           { 
1115                 if (lang_version < LanguageVersion.ISO_2)
1116                         FeatureIsNotAvailable (GetLocation ($3), "fixed size buffers");
1117
1118                 var lt = (LocatedToken) $5;
1119                 current_field = new FixedField (current_type, (FullNamedExpression) $4, (Modifiers) $2,
1120                         new MemberName (lt.Value, lt.Location), (Attributes) $1);
1121                         
1122                 current_type.AddField (current_field);
1123           }
1124           fixed_field_size opt_fixed_field_declarators SEMICOLON
1125           {
1126                 if (doc_support) {
1127                         current_field.DocComment = Lexer.consume_doc_comment ();
1128                         Lexer.doc_state = XmlCommentState.Allowed;
1129             }
1130
1131                 current_field.Initializer = (ConstInitializer) $7;          
1132                 lbag.AddMember (current_field, mod_locations, GetLocation ($9));
1133                 $$ = current_field;
1134             current_field = null;
1135           }
1136         | opt_attributes
1137           opt_modifiers
1138           FIXED simple_type error
1139           SEMICOLON
1140           {
1141                 report.Error (1641, GetLocation ($5), "A fixed size buffer field must have the array size specifier after the field name");
1142           }
1143         ;
1144         
1145 opt_field_initializer
1146         : /* empty */
1147         | ASSIGN
1148           {
1149                 ++lexer.parsing_block;
1150                 current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
1151                 start_block (GetLocation ($1));
1152           }
1153           variable_initializer
1154           {
1155                 --lexer.parsing_block;
1156                 current_field.Initializer = (Expression) $3;
1157                 lbag.AppendToMember (current_field, GetLocation ($1));
1158                 end_block (lexer.Location);
1159                 current_local_parameters = null;
1160           }
1161         ;
1162         
1163 opt_field_declarators
1164         : /* empty */
1165         | field_declarators
1166         ;
1167         
1168 field_declarators
1169         : field_declarator
1170           {
1171                 current_field.AddDeclarator ((FieldDeclarator) $1);
1172           }
1173         | field_declarators field_declarator
1174           {
1175                 current_field.AddDeclarator ((FieldDeclarator) $2);
1176           }
1177         ;
1178         
1179 field_declarator
1180         : COMMA IDENTIFIER
1181           {
1182                 var lt = (LocatedToken) $2;
1183                 $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null);
1184                 lbag.AddLocation ($$, GetLocation ($1));
1185           }
1186         | COMMA IDENTIFIER ASSIGN
1187           {
1188                 ++lexer.parsing_block;
1189           }
1190           variable_initializer
1191           {
1192                 --lexer.parsing_block;
1193                 var lt = (LocatedToken) $2;       
1194                 $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5);
1195                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
1196           }
1197         ;       
1198
1199 opt_fixed_field_declarators
1200         : /* empty */
1201         | fixed_field_declarators
1202         ;
1203         
1204 fixed_field_declarators
1205         : fixed_field_declarator
1206           {
1207                 current_field.AddDeclarator ((FieldDeclarator) $1);
1208           }
1209         | fixed_field_declarators fixed_field_declarator
1210           {
1211                 current_field.AddDeclarator ((FieldDeclarator) $2);
1212           }
1213         ;
1214         
1215 fixed_field_declarator
1216         : COMMA IDENTIFIER fixed_field_size
1217           {
1218                 var lt = (LocatedToken) $2;       
1219                 $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3);
1220                 lbag.AddLocation ($$, GetLocation ($1));
1221           }
1222         ;
1223
1224 fixed_field_size
1225         : OPEN_BRACKET
1226           {
1227                 ++lexer.parsing_block;
1228           }
1229           expression CLOSE_BRACKET
1230           {
1231                 --lexer.parsing_block;
1232                 $$ = new ConstInitializer (current_field, (Expression) $3, GetLocation ($1));
1233                 lbag.AddLocation ($$, GetLocation ($4));
1234           }
1235         | OPEN_BRACKET error
1236           {
1237                 report.Error (443, lexer.Location, "Value or constant expected");
1238                 $$ = null;
1239           }       
1240         ;
1241
1242 variable_initializer
1243         : expression
1244         | array_initializer
1245         | error
1246           {
1247                 // It has to be here for the parent to safely restore artificial block
1248                 Error_SyntaxError (yyToken);
1249                 $$ = null;
1250           }
1251         ;
1252
1253 method_declaration
1254         : method_header
1255           {
1256                 if (doc_support)
1257                         Lexer.doc_state = XmlCommentState.NotAllowed;
1258
1259                 // Was added earlier in the case of body being eof for full ast
1260           }
1261           method_body
1262           {
1263                 Method method = (Method) $1;
1264                 method.Block = (ToplevelBlock) $3;
1265                 async_block = false;
1266                 
1267                 if (method.Block == null) {
1268                         method.ParameterInfo.CheckParameters (method);
1269
1270                         if ((method.ModFlags & Modifiers.ASYNC) != 0) {
1271                                 report.Error (1994, method.Location, "`{0}': The async modifier can only be used with methods that have a body",
1272                                         method.GetSignatureForError ());
1273                         }
1274                 } else {
1275                         if (current_container.Kind == MemberKind.Interface) {
1276                                 report.Error (531, method.Location, "`{0}': interface members cannot have a definition",
1277                                         method.GetSignatureForError ());
1278                         }
1279                 }
1280
1281                 current_local_parameters = null;
1282
1283                 if (doc_support)
1284                         Lexer.doc_state = XmlCommentState.Allowed;
1285           }
1286         ;
1287
1288 method_header
1289         : opt_attributes
1290           opt_modifiers
1291           member_type
1292           method_declaration_name OPEN_PARENS
1293           {
1294                 valid_param_mod = ParameterModifierType.All;
1295           }
1296           opt_formal_parameter_list CLOSE_PARENS
1297           {
1298                 valid_param_mod = 0;
1299                 MemberName name = (MemberName) $4;
1300                 current_local_parameters = (ParametersCompiled) $7;
1301
1302                 var method = Method.Create (current_type, (FullNamedExpression) $3, (Modifiers) $2,
1303                                      name, current_local_parameters, (Attributes) $1);
1304
1305                 current_type.AddMember (method);
1306
1307                 async_block = (method.ModFlags & Modifiers.ASYNC) != 0;
1308
1309                 if (doc_support)
1310                         method.DocComment = Lexer.consume_doc_comment ();
1311
1312                 lbag.AddMember (method, mod_locations, GetLocation ($5), GetLocation ($8));
1313
1314                 $$ = method;
1315
1316                 lexer.ConstraintsParsing = true;
1317           }
1318           opt_type_parameter_constraints_clauses
1319           {
1320                 lexer.ConstraintsParsing = false;
1321
1322                 if ($10 != null) {
1323                         var method = (Method) $9;
1324                         method.SetConstraints ((List<Constraints>) $10);
1325                 }
1326
1327                 $$ = $9;
1328           }
1329         | opt_attributes
1330           opt_modifiers
1331           PARTIAL
1332           VOID
1333           {
1334                 lexer.parsing_generic_declaration = true;
1335           }
1336           method_declaration_name
1337           OPEN_PARENS
1338           {
1339                 lexer.parsing_generic_declaration = false;
1340                 valid_param_mod = ParameterModifierType.All;
1341           }
1342           opt_formal_parameter_list CLOSE_PARENS 
1343           {
1344                 lexer.ConstraintsParsing = true;
1345           }
1346           opt_type_parameter_constraints_clauses
1347           {
1348                 lexer.ConstraintsParsing = false;
1349                 valid_param_mod = 0;
1350
1351                 MemberName name = (MemberName) $6;
1352                 current_local_parameters = (ParametersCompiled) $9;
1353
1354                 var modifiers = (Modifiers) $2;
1355                 modifiers |= Modifiers.PARTIAL;
1356
1357                 var method = Method.Create (current_type, new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($4)),
1358                                      modifiers, name, current_local_parameters, (Attributes) $1);
1359
1360                 current_type.AddMember (method);
1361
1362                 async_block = (method.ModFlags & Modifiers.ASYNC) != 0;
1363
1364                 if ($12 != null)
1365                         method.SetConstraints ((List<Constraints>) $12);
1366
1367                 if (doc_support)
1368                         method.DocComment = Lexer.consume_doc_comment ();
1369
1370                 StoreModifierLocation (Modifiers.PARTIAL, GetLocation ($3));
1371                 lbag.AddMember (method, mod_locations, GetLocation ($7), GetLocation ($10));
1372                 $$ = method;
1373           }
1374         | opt_attributes
1375           opt_modifiers
1376           member_type
1377           modifiers method_declaration_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1378           {
1379                 MemberName name = (MemberName) $5;
1380                 report.Error (1585, name.Location, 
1381                         "Member modifier `{0}' must precede the member type and name", ModifiersExtensions.Name ((Modifiers) $4));
1382
1383                 var method = Method.Create (current_type, (FullNamedExpression) $3,
1384                                             0, name, (ParametersCompiled) $7, (Attributes) $1);
1385
1386                 current_type.AddMember (method);
1387
1388                 current_local_parameters = (ParametersCompiled) $7;
1389
1390                 if (doc_support)
1391                         method.DocComment = Lexer.consume_doc_comment ();
1392
1393                 $$ = method;
1394           }
1395         | opt_attributes
1396           opt_modifiers
1397           member_type
1398           method_declaration_name error
1399           {
1400                 Error_SyntaxError (yyToken);
1401                 current_local_parameters = ParametersCompiled.Undefined;
1402
1403                 MemberName name = (MemberName) $4;
1404                 var method = Method.Create (current_type, (FullNamedExpression) $3, (Modifiers) $2,
1405                                                                         name, current_local_parameters, (Attributes) $1);
1406
1407                 current_type.AddMember (method);
1408
1409                 if (doc_support)
1410                         method.DocComment = Lexer.consume_doc_comment ();
1411
1412                 $$ = method;
1413           }
1414         ;
1415
1416 method_body
1417         : block
1418         | SEMICOLON             { $$ = null; }
1419         ;
1420
1421 opt_formal_parameter_list
1422         : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
1423         | formal_parameter_list
1424         ;
1425         
1426 formal_parameter_list
1427         : fixed_parameters
1428           {
1429                 var pars_list = (List<Parameter>) $1;
1430                 $$ = new ParametersCompiled (pars_list.ToArray ());
1431           } 
1432         | fixed_parameters COMMA parameter_array
1433           {
1434                 var pars_list = (List<Parameter>) $1;
1435                 pars_list.Add ((Parameter) $3);
1436
1437                 $$ = new ParametersCompiled (pars_list.ToArray ()); 
1438           }
1439         | fixed_parameters COMMA arglist_modifier
1440           {
1441                 var pars_list = (List<Parameter>) $1;
1442                 pars_list.Add (new ArglistParameter (GetLocation ($3)));
1443                 $$ = new ParametersCompiled (pars_list.ToArray (), true);
1444           }
1445         | parameter_array COMMA error
1446           {
1447                 if ($1 != null)
1448                         report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list");
1449
1450                 $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } );                      
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
1457                 var pars_list = (List<Parameter>) $1;
1458                 pars_list.Add (new ArglistParameter (GetLocation ($3)));
1459
1460                 $$ = new ParametersCompiled (pars_list.ToArray (), true);
1461           }
1462         | arglist_modifier COMMA error
1463           {
1464                 report.Error (257, GetLocation ($1), "An __arglist parameter must be the last parameter in a formal parameter list");
1465
1466                 $$ = new ParametersCompiled (new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true);
1467           }
1468         | fixed_parameters COMMA ARGLIST COMMA error 
1469           {
1470                 report.Error (257, GetLocation ($3), "An __arglist parameter must be the last parameter in a formal parameter list");
1471
1472                 var pars_list = (List<Parameter>) $1;
1473                 pars_list.Add (new ArglistParameter (GetLocation ($3)));
1474
1475                 $$ = new ParametersCompiled (pars_list.ToArray (), true);
1476           }
1477         | parameter_array 
1478           {
1479                 $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } );
1480           }
1481         | arglist_modifier
1482           {
1483                 $$ = new ParametersCompiled (new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true);
1484           }
1485         | error
1486           {
1487                 Error_SyntaxError (yyToken);
1488                 $$ = ParametersCompiled.EmptyReadOnlyParameters;
1489           }
1490         ;
1491
1492 fixed_parameters
1493         : fixed_parameter       
1494           {
1495                 parameters_bucket.Clear ();
1496                 Parameter p = (Parameter) $1;
1497                 parameters_bucket.Add (p);
1498                 
1499                 default_parameter_used = p.HasDefaultValue;
1500                 $$ = parameters_bucket;
1501           }
1502         | fixed_parameters COMMA fixed_parameter
1503           {
1504                 var pars = (List<Parameter>) $1;
1505                 Parameter p = (Parameter) $3;
1506                 if (p != null) {
1507                         if (p.HasExtensionMethodModifier)
1508                                 report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter");
1509                         else if (!p.HasDefaultValue && default_parameter_used)
1510                                 report.Error (1737, p.Location, "Optional parameter cannot precede required parameters");
1511
1512                         default_parameter_used |= p.HasDefaultValue;
1513                         pars.Add (p);
1514                         
1515                         lbag.AddLocation (p, GetLocation ($2));
1516                 }
1517                 
1518                 $$ = $1;
1519           }
1520         ;
1521
1522 fixed_parameter
1523         : opt_attributes
1524           opt_parameter_modifier
1525           parameter_type
1526           identifier_inside_body
1527           {
1528                 var lt = (LocatedToken) $4;
1529                 $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
1530           }
1531         | opt_attributes
1532           opt_parameter_modifier
1533           parameter_type
1534           identifier_inside_body OPEN_BRACKET CLOSE_BRACKET
1535           {
1536                 var lt = (LocatedToken) $4;
1537                 report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name");
1538                 $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
1539           }
1540         | attribute_sections error
1541           {
1542                 Error_SyntaxError (yyToken);
1543                 Location l = GetLocation ($2);
1544                 $$ = new Parameter (null, null, Parameter.Modifier.NONE, (Attributes) $1, l);
1545           }
1546         | opt_attributes
1547           opt_parameter_modifier
1548           parameter_type
1549           error
1550           {
1551                 Error_SyntaxError (yyToken);
1552                 Location l = GetLocation ($4);
1553                 $$ = new Parameter ((FullNamedExpression) $3, null, (Parameter.Modifier) $2, (Attributes) $1, l);
1554           }
1555         | opt_attributes
1556           opt_parameter_modifier
1557           parameter_type
1558           identifier_inside_body
1559           ASSIGN
1560           {
1561                 ++lexer.parsing_block;
1562           }
1563           constant_expression
1564           {
1565                 --lexer.parsing_block;
1566                 if (lang_version <= LanguageVersion.V_3) {
1567                         FeatureIsNotAvailable (GetLocation ($5), "optional parameter");
1568                 }
1569                 
1570                 Parameter.Modifier mod = (Parameter.Modifier) $2;
1571                 if (mod != Parameter.Modifier.NONE) {
1572                         switch (mod) {
1573                         case Parameter.Modifier.REF:
1574                         case Parameter.Modifier.OUT:
1575                                 report.Error (1741, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter",
1576                                         Parameter.GetModifierSignature (mod));
1577                                 break;
1578                                 
1579                         case Parameter.Modifier.This:
1580                                 report.Error (1743, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter",
1581                                         Parameter.GetModifierSignature (mod));
1582                                 break;
1583                         default:
1584                                 throw new NotImplementedException (mod.ToString ());
1585                         }
1586                                 
1587                         mod = Parameter.Modifier.NONE;
1588                 }
1589                 
1590                 if ((valid_param_mod & ParameterModifierType.DefaultValue) == 0)
1591                         report.Error (1065, GetLocation ($5), "Optional parameter is not valid in this context");
1592                 
1593                 var lt = (LocatedToken) $4;
1594                 $$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, lt.Location);
1595                 lbag.AddLocation ($$, GetLocation ($5));
1596                 
1597                 if ($7 != null)
1598                         ((Parameter) $$).DefaultValue = new DefaultParameterValueExpression ((Expression) $7);
1599           }
1600         ;
1601
1602 opt_parameter_modifier
1603         : /* empty */           { $$ = Parameter.Modifier.NONE; }
1604         | parameter_modifiers
1605         ;
1606
1607 parameter_modifiers
1608         : parameter_modifier
1609           {
1610                 $$ = $1;
1611           }
1612         | parameter_modifiers parameter_modifier
1613           {
1614                 Parameter.Modifier p2 = (Parameter.Modifier)$2;
1615                 Parameter.Modifier mod = (Parameter.Modifier)$1 | p2;
1616                 if (((Parameter.Modifier)$1 & p2) == p2) {
1617                         Error_DuplicateParameterModifier (lexer.Location, p2);
1618                 } else {
1619                         switch (mod & ~Parameter.Modifier.This) {
1620                                 case Parameter.Modifier.REF:
1621                                         report.Error (1101, lexer.Location, "The parameter modifiers `this' and `ref' cannot be used altogether");
1622                                         break;
1623                                 case Parameter.Modifier.OUT:
1624                                         report.Error (1102, lexer.Location, "The parameter modifiers `this' and `out' cannot be used altogether");
1625                                         break;
1626                                 default:
1627                                         report.Error (1108, lexer.Location, "A parameter cannot have specified more than one modifier");
1628                                         break;
1629                         }
1630                 }
1631                 $$ = mod;
1632           }
1633         ;
1634
1635 parameter_modifier
1636         : REF
1637           {
1638                 if ((valid_param_mod & ParameterModifierType.Ref) == 0)
1639                         Error_ParameterModifierNotValid ("ref", GetLocation ($1));
1640                         
1641                 $$ = Parameter.Modifier.REF;
1642           }
1643         | OUT
1644           {
1645                 if ((valid_param_mod & ParameterModifierType.Out) == 0)
1646                         Error_ParameterModifierNotValid ("out", GetLocation ($1));
1647           
1648                 $$ = Parameter.Modifier.OUT;
1649           }
1650         | THIS
1651           {
1652                 if ((valid_param_mod & ParameterModifierType.This) == 0)
1653                         Error_ParameterModifierNotValid ("this", GetLocation ($1));
1654
1655                 if (lang_version <= LanguageVersion.ISO_2)
1656                         FeatureIsNotAvailable (GetLocation ($1), "extension methods");
1657                                 
1658                 $$ = Parameter.Modifier.This;
1659           }
1660         ;
1661
1662 parameter_array
1663         : opt_attributes params_modifier type IDENTIFIER
1664           {
1665                 var lt = (LocatedToken) $4;
1666                 $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location);
1667           }
1668         | opt_attributes params_modifier type IDENTIFIER ASSIGN constant_expression
1669           {
1670                 report.Error (1751, GetLocation ($2), "Cannot specify a default value for a parameter array");
1671                 
1672                 var lt = (LocatedToken) $4;
1673                 $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location);            
1674           }
1675         | opt_attributes params_modifier type error
1676           {
1677                 Error_SyntaxError (yyToken);
1678
1679                 $$ = new ParamsParameter ((FullNamedExpression) $3, null, (Attributes) $1, Location.Null);
1680           }
1681         ;
1682         
1683 params_modifier
1684         : PARAMS
1685           {
1686                 if ((valid_param_mod & ParameterModifierType.Params) == 0)
1687                         report.Error (1670, (GetLocation ($1)), "The `params' modifier is not allowed in current context");
1688           }
1689         | PARAMS parameter_modifier
1690           {
1691                 Parameter.Modifier mod = (Parameter.Modifier)$2;
1692                 if ((mod & Parameter.Modifier.This) != 0) {
1693                         report.Error (1104, GetLocation ($1), "The parameter modifiers `this' and `params' cannot be used altogether");
1694                 } else {
1695                         report.Error (1611, GetLocation ($1), "The params parameter cannot be declared as ref or out");
1696                 }         
1697           }
1698         | PARAMS params_modifier
1699           {
1700                 Error_DuplicateParameterModifier (GetLocation ($1), Parameter.Modifier.PARAMS);
1701           }
1702         ;
1703         
1704 arglist_modifier
1705         : ARGLIST
1706           {
1707                 if ((valid_param_mod & ParameterModifierType.Arglist) == 0)
1708                         report.Error (1669, GetLocation ($1), "__arglist is not valid in this context");
1709           }
1710         ;
1711         
1712 property_declaration
1713         : opt_attributes
1714           opt_modifiers
1715           member_type
1716           member_declaration_name
1717           {
1718                 if (doc_support)
1719                         tmpComment = Lexer.consume_doc_comment ();
1720           }
1721           OPEN_BRACE
1722           {
1723                 var type = (FullNamedExpression) $3;
1724                 current_property = new Property (current_type, type, (Modifiers) $2,
1725                         (MemberName) $4, (Attributes) $1);
1726                         
1727                 if (type.Type != null && type.Type.Kind == MemberKind.Void)
1728                         report.Error (547, GetLocation ($3), "`{0}': property or indexer cannot have void type", current_property.GetSignatureForError ());                                     
1729                         
1730                 current_type.AddMember (current_property);
1731                 lbag.AddMember (current_property, mod_locations, GetLocation ($6));
1732                 
1733                 lexer.PropertyParsing = true;
1734           }
1735           accessor_declarations 
1736           {
1737                 lexer.PropertyParsing = false;
1738                 
1739                 if (doc_support)
1740                         current_property.DocComment = ConsumeStoredComment ();                          
1741           }
1742           CLOSE_BRACE
1743           {
1744                 lbag.AppendToMember (current_property, GetLocation ($10));
1745                 current_property = null;
1746           }
1747         ;
1748
1749
1750 indexer_declaration
1751         : opt_attributes opt_modifiers
1752           member_type indexer_declaration_name OPEN_BRACKET
1753           {
1754                 valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue;
1755           }
1756           opt_formal_parameter_list CLOSE_BRACKET 
1757           {
1758                 valid_param_mod = 0;
1759                 var type = (FullNamedExpression) $3;
1760                 Indexer indexer = new Indexer (current_type, type, (MemberName) $4, (Modifiers) $2, (ParametersCompiled) $7, (Attributes) $1);
1761                         
1762                 current_property = indexer;
1763
1764                 current_type.AddIndexer (indexer);
1765                 lbag.AddMember (current_property, mod_locations, GetLocation ($5), GetLocation ($8));
1766                 
1767                 if (type.Type != null && type.Type.Kind == MemberKind.Void)
1768                         report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ());           
1769
1770                 if (indexer.ParameterInfo.IsEmpty) {
1771                         report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter");
1772                 }
1773
1774                 if (doc_support) {
1775                         tmpComment = Lexer.consume_doc_comment ();
1776                         Lexer.doc_state = XmlCommentState.Allowed;
1777                 }
1778
1779                 lexer.PropertyParsing = true;
1780           }
1781           OPEN_BRACE accessor_declarations 
1782           {
1783                 lexer.PropertyParsing = false;
1784           }
1785           CLOSE_BRACE
1786           {
1787                 if (current_property.AccessorFirst != null && current_property.AccessorFirst.Block == null)
1788                         ((Indexer) current_property).ParameterInfo.CheckParameters (current_property);
1789           
1790                 if (doc_support)
1791                         current_property.DocComment = ConsumeStoredComment ();
1792                         
1793                 lbag.AppendToMember (current_property, GetLocation ($10), GetLocation ($13));
1794                 current_property = null;                
1795           }
1796         ;
1797
1798
1799 accessor_declarations
1800         : get_accessor_declaration
1801         | get_accessor_declaration accessor_declarations
1802         | set_accessor_declaration
1803         | set_accessor_declaration accessor_declarations
1804         | error
1805           {
1806                 if (yyToken == Token.CLOSE_BRACE) {
1807                         report.Error (548, lexer.Location, "`{0}': property or indexer must have at least one accessor", current_property.GetSignatureForError ());
1808                 } else {
1809                         if (yyToken == Token.SEMICOLON)
1810                                 report.Error (1597, lexer.Location, "Semicolon after method or accessor block is not valid");
1811                         else
1812                                 report.Error (1014, GetLocation ($1), "A get or set accessor expected");
1813                 }
1814           }
1815         ;
1816
1817 get_accessor_declaration
1818         : opt_attributes opt_modifiers GET
1819           {
1820                 if ($2 != ModifierNone && lang_version == LanguageVersion.ISO_1) {
1821                         FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties");
1822                 }
1823           
1824                 if (current_property.Get != null) {
1825                         report.Error (1007, GetLocation ($3), "Property accessor already defined");
1826                 }
1827                 
1828                 if (current_property is Indexer) {
1829                         current_property.Get = new Indexer.GetIndexerMethod (current_property, (Modifiers) $2, ((Indexer)current_property).ParameterInfo.Clone (),
1830                                 (Attributes) $1, GetLocation ($3));
1831                 } else {
1832                         current_property.Get = new Property.GetMethod (current_property,
1833                                 (Modifiers) $2, (Attributes) $1, GetLocation ($3));
1834                 }       
1835           
1836                 current_local_parameters = current_property.Get.ParameterInfo;    
1837                 lbag.AddMember (current_property.Get, mod_locations);
1838                 lexer.PropertyParsing = false;
1839           }
1840           accessor_body
1841           {
1842                 if ($5 != null) {
1843                         current_property.Get.Block = (ToplevelBlock) $5;                        
1844                 
1845                         if (current_container.Kind == MemberKind.Interface) {
1846                                 report.Error (531, current_property.Get.Block.StartLocation,
1847                                         "`{0}': interface members cannot have a definition", current_property.Get.GetSignatureForError ());
1848                         }               
1849                 }
1850           
1851                 current_local_parameters = null;
1852                 lexer.PropertyParsing = true;
1853
1854                 if (doc_support)
1855                         if (Lexer.doc_state == XmlCommentState.Error)
1856                                 Lexer.doc_state = XmlCommentState.NotAllowed;
1857           }
1858         ;
1859
1860 set_accessor_declaration
1861         : opt_attributes opt_modifiers SET 
1862           {
1863                 if ($2 != ModifierNone && lang_version == LanguageVersion.ISO_1) {
1864                         FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties");
1865                 }
1866                 
1867                 if (current_property.Set != null) {
1868                         report.Error (1007, GetLocation ($3), "Property accessor already defined");
1869                 }
1870           
1871                 if (current_property is Indexer) {
1872                         current_property.Set = new Indexer.SetIndexerMethod (current_property, (Modifiers) $2,
1873                                 ParametersCompiled.MergeGenerated (compiler,
1874                                 ((Indexer)current_property).ParameterInfo, true, new Parameter (
1875                                         current_property.TypeExpression, "value", Parameter.Modifier.NONE, null, GetLocation ($3)),
1876                                         null),
1877                                 (Attributes) $1, GetLocation ($3));
1878                 } else {
1879                         current_property.Set = new Property.SetMethod (current_property, (Modifiers) $2, 
1880                                 ParametersCompiled.CreateImplicitParameter (current_property.TypeExpression, GetLocation ($3)),
1881                                 (Attributes) $1, GetLocation ($3));
1882                 }
1883                 
1884                 current_local_parameters = current_property.Set.ParameterInfo;  
1885                 lbag.AddMember (current_property.Set, mod_locations);
1886                 lexer.PropertyParsing = false;
1887           }
1888           accessor_body
1889           {
1890                 if ($5 != null) {               
1891                         current_property.Set.Block = (ToplevelBlock) $5;
1892                 
1893                         if (current_container.Kind == MemberKind.Interface) {
1894                                 report.Error (531, current_property.Set.Block.StartLocation,
1895                                         "`{0}': interface members cannot have a definition", current_property.Set.GetSignatureForError ());
1896                         }
1897                 }
1898                 
1899                 current_local_parameters = null;
1900                 lexer.PropertyParsing = true;
1901
1902                 if (doc_support
1903                         && Lexer.doc_state == XmlCommentState.Error)
1904                         Lexer.doc_state = XmlCommentState.NotAllowed;
1905           }
1906         ;
1907
1908 accessor_body
1909         : block 
1910         | SEMICOLON
1911           {
1912                 // TODO: lbag
1913                 $$ = null;
1914           }
1915         | error
1916           {
1917                 Error_SyntaxError (1043, yyToken, "Invalid accessor body");
1918                 $$ = null;
1919           }
1920         ;
1921
1922 interface_declaration
1923         : opt_attributes
1924           opt_modifiers
1925           opt_partial
1926           INTERFACE
1927           {
1928           }
1929           type_declaration_name
1930           {
1931                 lexer.ConstraintsParsing = true;
1932                 push_current_container (new Interface (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3);
1933                 lbag.AddMember (current_container, mod_locations, GetLocation ($4));            
1934           }
1935           opt_class_base
1936           opt_type_parameter_constraints_clauses
1937           {
1938                 lexer.ConstraintsParsing = false;
1939
1940                 if ($9 != null)
1941                         current_container.SetConstraints ((List<Constraints>) $9);
1942
1943                 if (doc_support) {
1944                         current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
1945                         Lexer.doc_state = XmlCommentState.Allowed;
1946                 }
1947                 
1948                 lexer.parsing_modifiers = true;
1949           }
1950           OPEN_BRACE opt_interface_member_declarations CLOSE_BRACE
1951           {
1952                 --lexer.parsing_declaration;      
1953                 if (doc_support)
1954                         Lexer.doc_state = XmlCommentState.Allowed;
1955           }
1956           opt_semicolon 
1957           {
1958                 if ($15 == null) {
1959                         lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13));
1960                 } else {
1961                         lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13), GetLocation ($15));
1962                 }
1963                 $$ = pop_current_class ();
1964           }
1965         | opt_attributes opt_modifiers opt_partial INTERFACE error
1966           {
1967                 Error_SyntaxError (yyToken);      
1968           }
1969         ;
1970
1971 opt_interface_member_declarations
1972         : /* empty */
1973         | interface_member_declarations
1974         ;
1975
1976 interface_member_declarations
1977         : interface_member_declaration
1978           {
1979                 lexer.parsing_modifiers = true;
1980                 lexer.parsing_block = 0;
1981           }
1982         | interface_member_declarations interface_member_declaration
1983           {
1984                 lexer.parsing_modifiers = true;
1985                 lexer.parsing_block = 0;
1986           }
1987         ;
1988
1989 interface_member_declaration
1990         : constant_declaration
1991           {
1992                 report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
1993           }
1994         | field_declaration
1995           {
1996                 report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
1997           }
1998         | method_declaration
1999         | property_declaration
2000         | event_declaration
2001         | indexer_declaration
2002         | operator_declaration
2003           {
2004                 report.Error (567, GetLocation ($1), "Interfaces cannot contain operators");
2005           }
2006         | constructor_declaration
2007           {
2008                 report.Error (526, GetLocation ($1), "Interfaces cannot contain contructors");
2009           }
2010         | type_declaration
2011           {
2012                 report.Error (524, GetLocation ($1), "Interfaces cannot declare classes, structs, interfaces, delegates, or enumerations");
2013           }
2014         ;
2015
2016 operator_declaration
2017         : opt_attributes opt_modifiers operator_declarator 
2018           {
2019           }
2020           operator_body
2021           {
2022                 OperatorDeclaration decl = (OperatorDeclaration) $3;
2023                 if (decl != null) {
2024                         Operator op = new Operator (
2025                                 current_type, decl.optype, decl.ret_type, (Modifiers) $2, 
2026                                 current_local_parameters,
2027                                 (ToplevelBlock) $5, (Attributes) $1, decl.location);
2028                                 
2029                         if (op.Block == null)
2030                                 op.ParameterInfo.CheckParameters (op);
2031
2032                         if (doc_support) {
2033                                 op.DocComment = tmpComment;
2034                                 Lexer.doc_state = XmlCommentState.Allowed;
2035                         }
2036
2037                         // Note again, checking is done in semantic analysis
2038                         current_type.AddOperator (op);
2039
2040                         lbag.AddMember (op, mod_locations, lbag.GetLocations (decl));
2041                 }
2042                 
2043                 current_local_parameters = null;
2044           }
2045         ;
2046
2047 operator_body 
2048         : block
2049         | SEMICOLON { $$ = null; }
2050         ; 
2051
2052 operator_type
2053         : type_expression_or_array
2054         | VOID
2055           {
2056                 report.Error (590, GetLocation ($1), "User-defined operators cannot return void");
2057                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
2058           }
2059         ;
2060
2061 operator_declarator
2062         : operator_type OPERATOR overloadable_operator OPEN_PARENS
2063           {
2064                 valid_param_mod = ParameterModifierType.DefaultValue;
2065           }
2066           opt_formal_parameter_list CLOSE_PARENS
2067           {
2068                 valid_param_mod = 0;
2069
2070                 Location loc = GetLocation ($2);
2071                 Operator.OpType op = (Operator.OpType) $3;
2072                 current_local_parameters = (ParametersCompiled)$6;
2073                 
2074                 int p_count = current_local_parameters.Count;
2075                 if (p_count == 1) {
2076                         if (op == Operator.OpType.Addition)
2077                                 op = Operator.OpType.UnaryPlus;
2078                         else if (op == Operator.OpType.Subtraction)
2079                                 op = Operator.OpType.UnaryNegation;
2080                 }
2081                 
2082                 if (IsUnaryOperator (op)) {
2083                         if (p_count == 2) {
2084                                 report.Error (1020, loc, "Overloadable binary operator expected");
2085                         } else if (p_count != 1) {
2086                                 report.Error (1535, loc, "Overloaded unary operator `{0}' takes one parameter",
2087                                         Operator.GetName (op));
2088                         }
2089                 } else {
2090                         if (p_count == 1) {
2091                                 report.Error (1019, loc, "Overloadable unary operator expected");
2092                         } else if (p_count != 2) {
2093                                 report.Error (1534, loc, "Overloaded binary operator `{0}' takes two parameters",
2094                                         Operator.GetName (op));
2095                         }
2096                 }
2097                 
2098                 if (doc_support) {
2099                         tmpComment = Lexer.consume_doc_comment ();
2100                         Lexer.doc_state = XmlCommentState.NotAllowed;
2101                 }
2102
2103                 $$ = new OperatorDeclaration (op, (FullNamedExpression) $1, loc);
2104                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3), GetLocation ($4), GetLocation ($7));
2105           }
2106         | conversion_operator_declarator
2107         ;
2108
2109 overloadable_operator
2110 // Unary operators:
2111         : BANG   { $$ = Operator.OpType.LogicalNot; }
2112         | TILDE  { $$ = Operator.OpType.OnesComplement; }  
2113         | OP_INC { $$ = Operator.OpType.Increment; }
2114         | OP_DEC { $$ = Operator.OpType.Decrement; }
2115         | TRUE   { $$ = Operator.OpType.True; }
2116         | FALSE  { $$ = Operator.OpType.False; }
2117 // Unary and binary:
2118         | PLUS { $$ = Operator.OpType.Addition; }
2119         | MINUS { $$ = Operator.OpType.Subtraction; }
2120 // Binary:
2121         | STAR { $$ = Operator.OpType.Multiply; }
2122         | DIV {  $$ = Operator.OpType.Division; }
2123         | PERCENT { $$ = Operator.OpType.Modulus; }
2124         | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
2125         | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
2126         | CARRET { $$ = Operator.OpType.ExclusiveOr; }
2127         | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
2128         | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
2129         | OP_EQ { $$ = Operator.OpType.Equality; }
2130         | OP_NE { $$ = Operator.OpType.Inequality; }
2131         | OP_GT { $$ = Operator.OpType.GreaterThan; }
2132         | OP_LT { $$ = Operator.OpType.LessThan; }
2133         | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
2134         | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
2135         ;
2136
2137 conversion_operator_declarator
2138         : IMPLICIT OPERATOR type OPEN_PARENS
2139           {
2140                 valid_param_mod = ParameterModifierType.DefaultValue;
2141           }
2142           opt_formal_parameter_list CLOSE_PARENS
2143           {
2144                 valid_param_mod = 0;
2145
2146                 Location loc = GetLocation ($2);
2147                 current_local_parameters = (ParametersCompiled)$6;  
2148
2149                 if (current_local_parameters.Count != 1) {
2150                         report.Error (1535, loc, "Overloaded unary operator `implicit' takes one parameter");
2151                 }
2152
2153                 if (doc_support) {
2154                         tmpComment = Lexer.consume_doc_comment ();
2155                         Lexer.doc_state = XmlCommentState.NotAllowed;
2156                 }
2157
2158                 $$ = new OperatorDeclaration (Operator.OpType.Implicit, (FullNamedExpression) $3, loc);
2159                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7));
2160           }
2161         | EXPLICIT OPERATOR type OPEN_PARENS
2162           {
2163                 valid_param_mod = ParameterModifierType.DefaultValue;
2164           }
2165           opt_formal_parameter_list CLOSE_PARENS
2166           {
2167                 valid_param_mod = 0;
2168                 
2169                 Location loc = GetLocation ($2);
2170                 current_local_parameters = (ParametersCompiled)$6;  
2171
2172                 if (current_local_parameters.Count != 1) {
2173                         report.Error (1535, loc, "Overloaded unary operator `explicit' takes one parameter");
2174                 }
2175
2176                 if (doc_support) {
2177                         tmpComment = Lexer.consume_doc_comment ();
2178                         Lexer.doc_state = XmlCommentState.NotAllowed;
2179                 }
2180
2181                 $$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc);
2182                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7));
2183           }
2184         | IMPLICIT error 
2185           {
2186                 Error_SyntaxError (yyToken);
2187                 current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
2188                 $$ = new OperatorDeclaration (Operator.OpType.Implicit, null, GetLocation ($1));
2189           }
2190         | EXPLICIT error 
2191           {
2192                 Error_SyntaxError (yyToken);
2193                 current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
2194                 $$ = new OperatorDeclaration (Operator.OpType.Explicit, null, GetLocation ($1));
2195           }
2196         ;
2197
2198 constructor_declaration
2199         : constructor_declarator
2200           constructor_body
2201           { 
2202                 Constructor c = (Constructor) $1;
2203                 c.Block = (ToplevelBlock) $2;
2204                 
2205                 if (doc_support)
2206                         c.DocComment = ConsumeStoredComment ();
2207
2208                 current_local_parameters = null;
2209                 if (doc_support)
2210                         Lexer.doc_state = XmlCommentState.Allowed;
2211           }
2212         ;
2213
2214 constructor_declarator
2215         : opt_attributes
2216           opt_modifiers
2217           IDENTIFIER
2218           {
2219                 if (doc_support) {
2220                         tmpComment = Lexer.consume_doc_comment ();
2221                         Lexer.doc_state = XmlCommentState.Allowed;
2222                 }
2223                 
2224                 valid_param_mod = ParameterModifierType.All;
2225           }
2226           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2227           {
2228                 valid_param_mod = 0;
2229                 current_local_parameters = (ParametersCompiled) $6;
2230                 
2231                 var lt = (LocatedToken) $3;
2232                 var mods = (Modifiers) $2;
2233                 var c = new Constructor (current_type, lt.Value, mods, (Attributes) $1, current_local_parameters, lt.Location);
2234
2235                 if (lt.Value != current_container.MemberName.Name) {
2236                         report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
2237                 } else if ((mods & Modifiers.STATIC) != 0) {
2238                         if ((mods & Modifiers.AccessibilityMask) != 0){
2239                                 report.Error (515, c.Location,
2240                                         "`{0}': static constructor cannot have an access modifier",
2241                                         c.GetSignatureForError ());
2242                         }
2243                 }
2244
2245                 current_type.AddConstructor (c);
2246                 lbag.AddMember (c, mod_locations, GetLocation ($5), GetLocation ($7));
2247                 $$ = c;
2248
2249                 //
2250                 // start block here, so possible anonymous methods inside
2251                 // constructor initializer can get correct parent block
2252                 //
2253                 start_block (lexer.Location);
2254           }
2255           opt_constructor_initializer
2256           {
2257                 if ($9 != null) {
2258                         var c = (Constructor) $8;
2259                         c.Initializer = (ConstructorInitializer) $9;
2260                         
2261                         if (c.IsStatic) {
2262                                 report.Error (514, c.Location,
2263                                         "`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
2264                                         c.GetSignatureForError ());
2265                         }
2266                 }
2267
2268                 $$ = $8;
2269           }
2270         ;
2271
2272 constructor_body
2273         : block_prepared
2274         | SEMICOLON             { current_block = null; $$ = null; }
2275         ;
2276
2277 opt_constructor_initializer
2278         : /* Empty */
2279         | constructor_initializer
2280         ;
2281
2282 constructor_initializer
2283         : COLON BASE OPEN_PARENS
2284           {
2285                 ++lexer.parsing_block;
2286           }
2287           opt_argument_list CLOSE_PARENS
2288           {
2289                 --lexer.parsing_block;
2290                 $$ = new ConstructorBaseInitializer ((Arguments) $5, GetLocation ($2));
2291                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6));
2292           }
2293         | COLON THIS OPEN_PARENS
2294           {
2295                 ++lexer.parsing_block;
2296           }
2297           opt_argument_list CLOSE_PARENS
2298           {
2299                 --lexer.parsing_block;
2300                 $$ = new ConstructorThisInitializer ((Arguments) $5, GetLocation ($2));
2301                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6));
2302           }
2303         | COLON error
2304           {
2305                 Error_SyntaxError (yyToken);      
2306                 $$ = new ConstructorThisInitializer (null, GetLocation ($2));
2307                 lbag.AddLocation ($$, GetLocation ($1));
2308           }
2309         | error
2310           {
2311                 Error_SyntaxError (yyToken);
2312                 $$ = null;
2313           }
2314         ;
2315
2316 destructor_declaration
2317         : opt_attributes opt_modifiers TILDE 
2318           {
2319                 if (doc_support) {
2320                         tmpComment = Lexer.consume_doc_comment ();
2321                         Lexer.doc_state = XmlCommentState.NotAllowed;
2322                 }
2323                 
2324                 current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
2325           }
2326           IDENTIFIER OPEN_PARENS CLOSE_PARENS method_body
2327           {
2328                 var lt = (LocatedToken) $5;
2329                 if (lt.Value != current_container.MemberName.Name){
2330                         report.Error (574, lt.Location, "Name of destructor must match name of class");
2331                 } else if (current_container.Kind != MemberKind.Class){
2332                         report.Error (575, lt.Location, "Only class types can contain destructor");
2333                 }
2334                 
2335                 Destructor d = new Destructor (current_type, (Modifiers) $2,
2336                         ParametersCompiled.EmptyReadOnlyParameters, (Attributes) $1, lt.Location);
2337                 if (doc_support)
2338                         d.DocComment = ConsumeStoredComment ();
2339                   
2340                 d.Block = (ToplevelBlock) $8;
2341                 current_type.AddMember (d);
2342                 lbag.AddMember (d, mod_locations, GetLocation ($3), GetLocation ($6), GetLocation ($7));
2343
2344                 current_local_parameters = null;
2345           }
2346         ;
2347
2348 event_declaration
2349         : opt_attributes
2350           opt_modifiers
2351           EVENT type member_declaration_name
2352           {
2353                 current_event_field = new EventField (current_type, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, (Attributes) $1);
2354                 current_type.AddMember (current_event_field);
2355                 
2356                 if (current_event_field.MemberName.ExplicitInterface != null) {
2357                         report.Error (71, current_event_field.Location, "`{0}': An explicit interface implementation of an event must use property syntax",
2358                         current_event_field.GetSignatureForError ());
2359                 }
2360                 
2361                 $$ = current_event_field;
2362           }
2363           opt_event_initializer
2364           opt_event_declarators
2365           SEMICOLON
2366           {
2367                 if (doc_support) {
2368                         current_event_field.DocComment = Lexer.consume_doc_comment ();
2369                         Lexer.doc_state = XmlCommentState.Allowed;
2370                 }
2371                 
2372                 lbag.AddMember (current_event_field, mod_locations, GetLocation ($3), GetLocation ($9));
2373                 current_event_field = null;
2374           }
2375         | opt_attributes
2376           opt_modifiers
2377           EVENT type member_declaration_name
2378           OPEN_BRACE
2379           {
2380                 current_event = new EventProperty (current_type, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, (Attributes) $1);
2381                 current_type.AddMember (current_event);
2382                 lbag.AddMember (current_event, mod_locations, GetLocation ($3), GetLocation ($6));
2383                 
2384                 lexer.EventParsing = true;
2385           }
2386           event_accessor_declarations
2387           {
2388                 if (current_container.Kind == MemberKind.Interface)
2389                         report.Error (69, GetLocation ($6), "Event in interface cannot have add or remove accessors");
2390           
2391                 lexer.EventParsing = false;
2392           }
2393           CLOSE_BRACE
2394           {
2395                 if (doc_support) {
2396                         current_event.DocComment = Lexer.consume_doc_comment ();
2397                         Lexer.doc_state = XmlCommentState.Allowed;
2398                 }
2399                 
2400                 lbag.AppendToMember (current_event, GetLocation ($9));
2401                 current_event = null;   
2402                 current_local_parameters = null;
2403           }
2404         | opt_attributes
2405           opt_modifiers
2406           EVENT type error
2407           {
2408                 Error_SyntaxError (yyToken);
2409
2410                 current_type.AddMember (new EventField (current_type, (FullNamedExpression) $4, (Modifiers) $2, MemberName.Null, (Attributes) $1));
2411           }
2412         ;
2413         
2414 opt_event_initializer
2415         : /* empty */
2416         | ASSIGN
2417           {
2418                 ++lexer.parsing_block;
2419           }
2420           event_variable_initializer
2421           {
2422                 --lexer.parsing_block;
2423                 current_event_field.Initializer = (Expression) $3;
2424           }
2425         ;
2426         
2427 opt_event_declarators
2428         : /* empty */
2429         | event_declarators
2430         ;
2431         
2432 event_declarators
2433         : event_declarator
2434           {
2435                 current_event_field.AddDeclarator ((FieldDeclarator) $1);
2436           }
2437         | event_declarators event_declarator
2438           {
2439                 current_event_field.AddDeclarator ((FieldDeclarator) $2);
2440           }
2441         ;
2442         
2443 event_declarator
2444         : COMMA IDENTIFIER
2445           {
2446                 var lt = (LocatedToken) $2;
2447                 $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null);
2448                 lbag.AddLocation ($$, GetLocation ($1));
2449           }
2450         | COMMA IDENTIFIER ASSIGN
2451           {
2452                 ++lexer.parsing_block;
2453           }
2454           event_variable_initializer
2455           {
2456                 --lexer.parsing_block;
2457                 var lt = (LocatedToken) $2;       
2458                 $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5);
2459                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
2460           }
2461         ;
2462         
2463 event_variable_initializer
2464         : {
2465                 if (current_container.Kind == MemberKind.Interface) {
2466                         report.Error (68, lexer.Location, "`{0}': event in interface cannot have an initializer",
2467                                 current_event_field.GetSignatureForError ());
2468                 }
2469                 
2470                 if ((current_event_field.ModFlags & Modifiers.ABSTRACT) != 0) {
2471                         report.Error (74, lexer.Location, "`{0}': abstract event cannot have an initializer",
2472                                 current_event_field.GetSignatureForError ());
2473                 }               
2474           }
2475           variable_initializer
2476           {
2477                 $$ = $2;
2478           }
2479         ;
2480         
2481 event_accessor_declarations
2482         : add_accessor_declaration remove_accessor_declaration
2483         | remove_accessor_declaration add_accessor_declaration
2484         | add_accessor_declaration
2485           {
2486                 report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors",
2487                         current_event.GetSignatureForError ());
2488           } 
2489         | remove_accessor_declaration
2490           {
2491                 report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors",
2492                         current_event.GetSignatureForError ());
2493           }     
2494         | error
2495           { 
2496                 report.Error (1055, GetLocation ($1), "An add or remove accessor expected");
2497                 $$ = null;
2498           }
2499         ;
2500
2501 add_accessor_declaration
2502         : opt_attributes opt_modifiers ADD
2503           {
2504                 if ($2 != ModifierNone) {
2505                         report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations");
2506                 }
2507                 
2508                 current_event.Add = new EventProperty.AddDelegateMethod (current_event, (Attributes) $1, GetLocation ($3));
2509                 current_local_parameters = current_event.Add.ParameterInfo;
2510                 
2511                 lbag.AddMember (current_event.Add, mod_locations);
2512                 lexer.EventParsing = false;             
2513           }
2514           event_accessor_block
2515           {
2516                 lexer.EventParsing = true;
2517           
2518                 current_event.Add.Block = (ToplevelBlock) $5;
2519                 
2520                 if (current_container.Kind == MemberKind.Interface) {
2521                         report.Error (531, current_event.Add.Block.StartLocation,
2522                                 "`{0}': interface members cannot have a definition", current_event.Add.GetSignatureForError ());
2523                 }
2524                 
2525                 current_local_parameters = null;
2526           }
2527         ;
2528         
2529 remove_accessor_declaration
2530         : opt_attributes opt_modifiers REMOVE
2531           {
2532                 if ($2 != ModifierNone) {
2533                         report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations");
2534                 }
2535                 
2536                 current_event.Remove = new EventProperty.RemoveDelegateMethod (current_event, (Attributes) $1, GetLocation ($3));
2537                 current_local_parameters = current_event.Remove.ParameterInfo;
2538
2539                 lbag.AddMember (current_event.Remove, mod_locations);
2540                 lexer.EventParsing = false;             
2541           }
2542           event_accessor_block
2543           {
2544                 lexer.EventParsing = true;
2545           
2546                 current_event.Remove.Block = (ToplevelBlock) $5;
2547                 
2548                 if (current_container.Kind == MemberKind.Interface) {
2549                         report.Error (531, current_event.Remove.Block.StartLocation,
2550                                 "`{0}': interface members cannot have a definition", current_event.Remove.GetSignatureForError ());
2551                 }
2552                 
2553                 current_local_parameters = null;
2554           }
2555         ;
2556
2557 event_accessor_block
2558         : opt_semicolon
2559           {
2560                 report.Error (73, lexer.Location, "An add or remove accessor must have a body");
2561                 $$ = null;
2562           }
2563         | block;
2564         ;
2565
2566 attributes_without_members
2567         : attribute_sections CLOSE_BRACE
2568           {
2569                 current_type.UnattachedAttributes = (Attributes) $1;
2570                 report.Error (1519, GetLocation ($1), "An attribute is missing member declaration");
2571                 lexer.putback ('}');
2572           }
2573         ;
2574
2575 // For full ast try to recover incomplete ambiguous member
2576 // declaration in form on class X { public int }
2577 incomplete_member
2578         : opt_attributes opt_modifiers member_type CLOSE_BRACE
2579           {
2580                 report.Error (1519, lexer.Location, "Unexpected symbol `}' in class, struct, or interface member declaration");
2581  
2582                 lexer.putback ('}');
2583
2584                 lexer.parsing_generic_declaration = false;
2585                 FullNamedExpression type = (FullNamedExpression) $3;
2586                 current_field = new Field (current_type, type, (Modifiers) $2, MemberName.Null, (Attributes) $1);
2587                 current_type.AddField (current_field);
2588                 $$ = current_field;
2589           }
2590         ;
2591           
2592 enum_declaration
2593         : opt_attributes
2594           opt_modifiers
2595           ENUM type_declaration_name
2596           opt_enum_base
2597           {
2598                 if (doc_support)
2599                         enumTypeComment = Lexer.consume_doc_comment ();
2600           }
2601           OPEN_BRACE
2602           {
2603                 if (doc_support)
2604                         Lexer.doc_state = XmlCommentState.Allowed;
2605
2606                 MemberName name = (MemberName) $4;
2607                 if (name.IsGeneric) {
2608                         report.Error (1675, name.Location, "Enums cannot have type parameters");
2609                 }
2610                 
2611                 push_current_container (new Enum (current_container, (FullNamedExpression) $5, (Modifiers) $2, name, (Attributes) $1), null);
2612           }
2613           opt_enum_member_declarations
2614           {
2615                 lexer.parsing_modifiers = true;
2616           
2617                 // here will be evaluated after CLOSE_BLACE is consumed.
2618                 if (doc_support)
2619                         Lexer.doc_state = XmlCommentState.Allowed;
2620           }
2621           CLOSE_BRACE opt_semicolon
2622           {
2623                 if (doc_support)
2624                         current_container.DocComment = enumTypeComment;
2625                         
2626                 --lexer.parsing_declaration;
2627
2628 //                      if (doc_support)
2629 //                              em.DocComment = ev.DocComment;
2630
2631                 lbag.AddMember (current_container, mod_locations, GetLocation ($3), GetLocation ($7), GetLocation ($11));
2632                 $$ = pop_current_class ();
2633           }
2634         ;
2635
2636 opt_enum_base
2637         : /* empty */
2638         | COLON type
2639          {
2640                 var te = $2 as TypeExpression;
2641                 if (te == null || !EnumSpec.IsValidUnderlyingType (te.Type)) {
2642                         Enum.Error_1008 (GetLocation ($2), report);
2643                 }
2644                 $$ = $2;
2645          }
2646         | COLON error
2647          {
2648                 Error_TypeExpected (GetLocation ($1));
2649                 $$ = null;
2650          }
2651         ;
2652
2653 opt_enum_member_declarations
2654         : /* empty */
2655         | enum_member_declarations
2656         | enum_member_declarations COMMA
2657           {
2658                 lbag.AddLocation ($1, GetLocation ($2));
2659           }
2660         ;
2661
2662 enum_member_declarations
2663         : enum_member_declaration
2664         | enum_member_declarations COMMA enum_member_declaration
2665           {
2666                 lbag.AddLocation ($1, GetLocation ($2));
2667                 $$ = $3;
2668           }
2669         ;
2670
2671 enum_member_declaration
2672         : opt_attributes IDENTIFIER
2673           {
2674                 var lt = (LocatedToken) $2;
2675                 var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
2676                 ((Enum) current_type).AddEnumMember (em);
2677
2678                 if (doc_support) {
2679                         em.DocComment = Lexer.consume_doc_comment ();
2680                         Lexer.doc_state = XmlCommentState.Allowed;
2681                 }
2682
2683                 $$ = em;
2684           }
2685         | opt_attributes IDENTIFIER
2686           {
2687                 ++lexer.parsing_block;
2688                 if (doc_support) {
2689                         tmpComment = Lexer.consume_doc_comment ();
2690                         Lexer.doc_state = XmlCommentState.NotAllowed;
2691                 }
2692           }
2693           ASSIGN constant_expression
2694           { 
2695                 --lexer.parsing_block;
2696                 
2697                 var lt = (LocatedToken) $2;
2698                 var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
2699                 em.Initializer = new ConstInitializer (em, (Expression) $5, GetLocation ($4));
2700                 ((Enum) current_type).AddEnumMember (em);
2701                 
2702                 if (doc_support)
2703                         em.DocComment = ConsumeStoredComment ();
2704
2705                 $$ = em;
2706           }
2707         | opt_attributes IDENTIFIER error
2708           {
2709                 Error_SyntaxError (yyToken);
2710           
2711                 var lt = (LocatedToken) $2;
2712                 var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
2713                 ((Enum) current_type).AddEnumMember (em);
2714
2715                 if (doc_support) {
2716                         em.DocComment = Lexer.consume_doc_comment ();
2717                         Lexer.doc_state = XmlCommentState.Allowed;
2718                 }
2719
2720                 $$ = em;
2721           }
2722         | attributes_without_members
2723         ;
2724
2725 delegate_declaration
2726         : opt_attributes
2727           opt_modifiers
2728           DELEGATE
2729           member_type type_declaration_name
2730           OPEN_PARENS
2731           {
2732                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue;
2733           }
2734           opt_formal_parameter_list CLOSE_PARENS
2735           {
2736                 valid_param_mod = 0;
2737
2738                 ParametersCompiled p = (ParametersCompiled) $8;
2739
2740                 Delegate del = new Delegate (current_container, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, p, (Attributes) $1);
2741
2742                 p.CheckParameters (del);
2743
2744                 current_container.AddTypeContainer (del);
2745
2746                 current_delegate = del;
2747                 lexer.ConstraintsParsing = true;
2748           }
2749           opt_type_parameter_constraints_clauses
2750           {
2751                 lexer.ConstraintsParsing = false;
2752           }
2753           SEMICOLON
2754           {
2755                 if (doc_support) {
2756                         current_delegate.DocComment = Lexer.consume_doc_comment ();
2757                         Lexer.doc_state = XmlCommentState.Allowed;
2758                 }
2759           
2760                 if ($11 != null)
2761                         current_delegate.SetConstraints ((List<Constraints>) $11);
2762                 lbag.AddMember (current_delegate, mod_locations, GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($13));
2763
2764                 $$ = current_delegate;
2765
2766                 current_delegate = null;
2767           }
2768         ;
2769
2770 opt_nullable
2771         : /* empty */
2772         | INTERR_NULLABLE
2773           {
2774                 if (lang_version < LanguageVersion.ISO_2)
2775                         FeatureIsNotAvailable (GetLocation ($1), "nullable types");
2776           
2777                 $$ = ComposedTypeSpecifier.CreateNullable (GetLocation ($1));
2778           }
2779         ;
2780
2781 namespace_or_type_expr
2782         : member_name
2783         | qualified_alias_member IDENTIFIER opt_type_argument_list
2784           {
2785                 var lt1 = (LocatedToken) $1;
2786                 var lt2 = (LocatedToken) $2;
2787                 
2788                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
2789                 lbag.AddLocation ($$, GetLocation ($2));
2790           }
2791         ;
2792
2793 member_name
2794         : simple_name_expr
2795         | namespace_or_type_expr DOT IDENTIFIER opt_type_argument_list
2796           {
2797                 var lt = (LocatedToken) $3;
2798                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
2799                 lbag.AddLocation ($$, GetLocation ($2));
2800           }
2801         ;
2802
2803 simple_name_expr
2804         : IDENTIFIER opt_type_argument_list
2805           {
2806                 var lt = (LocatedToken) $1;
2807                 $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);
2808           }
2809         ;
2810         
2811 //
2812 // Generics arguments  (any type, without attributes)
2813 //
2814 opt_type_argument_list
2815         : /* empty */
2816         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2817           {
2818                 if (lang_version < LanguageVersion.ISO_2)
2819                         FeatureIsNotAvailable (GetLocation ($1), "generics");     
2820           
2821                 $$ = $2;
2822           }
2823         | OP_GENERICS_LT error
2824           {
2825                 Error_TypeExpected (lexer.Location);
2826                 $$ = new TypeArguments ();
2827           }
2828         ;
2829
2830 type_arguments
2831         : type
2832           {
2833                 TypeArguments type_args = new TypeArguments ();
2834                 type_args.Add ((FullNamedExpression) $1);
2835                 $$ = type_args;
2836           }
2837         | type_arguments COMMA type
2838           {
2839                 TypeArguments type_args = (TypeArguments) $1;
2840                 type_args.Add ((FullNamedExpression) $3);
2841                 $$ = type_args;
2842           }       
2843         ;
2844
2845 //
2846 // Generics parameters (identifiers only, with attributes), used in type or method declarations
2847 //
2848 type_declaration_name
2849         : IDENTIFIER
2850           {
2851                 lexer.parsing_generic_declaration = true;
2852           }
2853           opt_type_parameter_list
2854           {
2855                 lexer.parsing_generic_declaration = false;
2856                 var lt = (LocatedToken) $1;
2857                 $$ = new MemberName (lt.Value, (TypeParameters)$3, lt.Location);
2858           }
2859         ;
2860
2861 member_declaration_name
2862         : method_declaration_name
2863           {
2864                 MemberName mn = (MemberName)$1;
2865                 if (mn.TypeParameters != null)
2866                         syntax_error (mn.Location, string.Format ("Member `{0}' cannot declare type arguments",
2867                                 mn.GetSignatureForError ()));
2868           }
2869         ;
2870
2871 method_declaration_name
2872         : type_declaration_name
2873         | explicit_interface IDENTIFIER opt_type_parameter_list
2874           {
2875                 lexer.parsing_generic_declaration = false;        
2876                 var lt = (LocatedToken) $2;
2877                 $$ = new MemberName (lt.Value, (TypeParameters) $3, (ATypeNameExpression) $1, lt.Location);
2878           }
2879         ;
2880         
2881 indexer_declaration_name
2882         : THIS
2883           {
2884                 lexer.parsing_generic_declaration = false;        
2885                 $$ = new MemberName (TypeDefinition.DefaultIndexerName, GetLocation ($1));
2886           }
2887         | explicit_interface THIS
2888           {
2889                 lexer.parsing_generic_declaration = false;
2890                 $$ = new MemberName (TypeDefinition.DefaultIndexerName, null, (ATypeNameExpression) $1, GetLocation ($2));
2891           }
2892         ;
2893
2894 explicit_interface
2895         : IDENTIFIER opt_type_argument_list DOT
2896           {
2897                 var lt = (LocatedToken) $1;
2898                 $$ = new SimpleName (lt.Value, (TypeArguments) $2, lt.Location);
2899                 lbag.AddLocation ($$, GetLocation ($3));
2900           }
2901         | qualified_alias_member IDENTIFIER opt_type_argument_list DOT
2902           {
2903                 var lt1 = (LocatedToken) $1;
2904                 var lt2 = (LocatedToken) $2;
2905
2906                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
2907                 lbag.AddLocation ($$, GetLocation ($4));
2908           }
2909         | explicit_interface IDENTIFIER opt_type_argument_list DOT
2910           {
2911                 var lt = (LocatedToken) $2;
2912                 $$ = new MemberAccess ((ATypeNameExpression) $1, lt.Value, (TypeArguments) $3, lt.Location);
2913                 lbag.AddLocation ($$, GetLocation ($4));
2914           }
2915         ;
2916         
2917 opt_type_parameter_list
2918         : /* empty */
2919         | OP_GENERICS_LT_DECL type_parameters OP_GENERICS_GT
2920           {
2921                 if (lang_version < LanguageVersion.ISO_2)
2922                         FeatureIsNotAvailable (GetLocation ($1), "generics");
2923           
2924                 $$ = $2;
2925                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
2926           }
2927         ;
2928
2929 type_parameters
2930         : type_parameter
2931           {
2932                 var tparams = new TypeParameters ();
2933                 tparams.Add ((TypeParameter)$1);
2934                 $$ = tparams;
2935           }
2936         | type_parameters COMMA type_parameter
2937           {
2938                 var tparams = (TypeParameters) $1;
2939                 tparams.Add ((TypeParameter)$3);
2940                 $$ = tparams;
2941                 lbag.AddLocation ($3, GetLocation ($3));
2942           }       
2943         ;
2944
2945 type_parameter
2946         : opt_attributes opt_type_parameter_variance IDENTIFIER
2947           {
2948                 var lt = (LocatedToken)$3;
2949                 $$ = new TypeParameter (new MemberName (lt.Value, lt.Location), (Attributes)$1, (VarianceDecl) $2);
2950           }
2951         | error
2952           {
2953                 if (GetTokenName (yyToken) == "type")
2954                         report.Error (81, GetLocation ($1), "Type parameter declaration must be an identifier not a type");
2955                 else
2956                         Error_SyntaxError (yyToken);
2957                         
2958                 $$ = new TypeParameter (MemberName.Null, null, null);
2959           }
2960         ;
2961
2962 //
2963 // All types where void is allowed
2964 //
2965 type_and_void
2966         : type_expression_or_array
2967         | VOID
2968           {
2969                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
2970           }
2971         ;
2972         
2973 member_type
2974         : type_and_void
2975           {
2976                 lexer.parsing_generic_declaration = true;
2977           }
2978         ;
2979         
2980 //
2981 // A type which does not allow `void' to be used
2982 //
2983 type
2984         : type_expression_or_array
2985         | VOID
2986           {
2987                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
2988                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
2989           }     
2990         ;
2991         
2992 simple_type
2993         : type_expression
2994         | VOID
2995           {
2996                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
2997                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
2998           }     
2999         ;
3000         
3001 parameter_type
3002         : type_expression_or_array
3003         | VOID
3004           {
3005                 report.Error (1536, GetLocation ($1), "Invalid parameter type `void'");
3006                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
3007           }     
3008         ;
3009
3010 type_expression_or_array
3011         : type_expression
3012         | type_expression rank_specifiers
3013           {
3014                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
3015           }
3016         ;
3017         
3018 type_expression
3019         : namespace_or_type_expr opt_nullable
3020           {
3021                 if ($2 != null) {
3022                         $$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
3023                 } else {
3024                         var sn = $1 as SimpleName;
3025                         if (sn != null && sn.Name == "var")
3026                                 $$ = new VarExpr (sn.Location);
3027                         else
3028                                 $$ = $1;
3029                 }
3030           }
3031         | namespace_or_type_expr pointer_stars
3032           {
3033                 $$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
3034           }
3035         | builtin_types opt_nullable
3036           {
3037                 if ($2 != null)
3038                         $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
3039           }
3040         | builtin_types pointer_stars
3041           {
3042                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
3043           }
3044         | VOID pointer_stars
3045           {
3046                 $$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
3047           }
3048         ;
3049
3050 type_list
3051         : base_type_name
3052           {
3053                 var types = new List<FullNamedExpression> (2);
3054                 types.Add ((FullNamedExpression) $1);
3055                 $$ = types;
3056           }
3057         | type_list COMMA base_type_name
3058           {
3059                 var types = (List<FullNamedExpression>) $1;
3060                 types.Add ((FullNamedExpression) $3);
3061                 $$ = types;
3062           }
3063         ;
3064
3065 base_type_name
3066         : type
3067           {
3068                 if ($1 is ComposedCast) {
3069                         report.Error (1521, GetLocation ($1), "Invalid base type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
3070                 }
3071                 $$ = $1;
3072           }
3073         ;
3074         
3075 /*
3076  * replaces all the productions for isolating the various
3077  * simple types, but we need this to reuse it easily in variable_type
3078  */
3079 builtin_types
3080         : OBJECT        { $$ = new TypeExpression (compiler.BuiltinTypes.Object, GetLocation ($1)); }
3081         | STRING        { $$ = new TypeExpression (compiler.BuiltinTypes.String, GetLocation ($1)); }
3082         | BOOL          { $$ = new TypeExpression (compiler.BuiltinTypes.Bool, GetLocation ($1)); }
3083         | DECIMAL       { $$ = new TypeExpression (compiler.BuiltinTypes.Decimal, GetLocation ($1)); }
3084         | FLOAT         { $$ = new TypeExpression (compiler.BuiltinTypes.Float, GetLocation ($1)); }
3085         | DOUBLE        { $$ = new TypeExpression (compiler.BuiltinTypes.Double, GetLocation ($1)); }
3086         | integral_type
3087         ;
3088
3089 integral_type
3090         : SBYTE         { $$ = new TypeExpression (compiler.BuiltinTypes.SByte, GetLocation ($1)); }
3091         | BYTE          { $$ = new TypeExpression (compiler.BuiltinTypes.Byte, GetLocation ($1)); }
3092         | SHORT         { $$ = new TypeExpression (compiler.BuiltinTypes.Short, GetLocation ($1)); }
3093         | USHORT        { $$ = new TypeExpression (compiler.BuiltinTypes.UShort, GetLocation ($1)); }
3094         | INT           { $$ = new TypeExpression (compiler.BuiltinTypes.Int, GetLocation ($1)); }
3095         | UINT          { $$ = new TypeExpression (compiler.BuiltinTypes.UInt, GetLocation ($1)); }
3096         | LONG          { $$ = new TypeExpression (compiler.BuiltinTypes.Long, GetLocation ($1)); }
3097         | ULONG         { $$ = new TypeExpression (compiler.BuiltinTypes.ULong, GetLocation ($1)); }
3098         | CHAR          { $$ = new TypeExpression (compiler.BuiltinTypes.Char, GetLocation ($1)); }
3099         ;
3100
3101 //
3102 // Expressions, section 7.5
3103 //
3104
3105
3106 primary_expression
3107         : primary_expression_or_type
3108         | literal
3109         | array_creation_expression
3110         | parenthesized_expression
3111         | default_value_expression
3112         | invocation_expression
3113         | element_access
3114         | this_access
3115         | base_access
3116         | post_increment_expression
3117         | post_decrement_expression
3118         | object_or_delegate_creation_expression
3119         | anonymous_type_expression
3120         | typeof_expression
3121         | sizeof_expression
3122         | checked_expression
3123         | unchecked_expression
3124         | pointer_member_access
3125         | anonymous_method_expression
3126         | undocumented_expressions
3127         ;
3128
3129 primary_expression_or_type
3130         : IDENTIFIER opt_type_argument_list
3131           {
3132                 var lt = (LocatedToken) $1;
3133                 $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);   
3134           }
3135         | IDENTIFIER GENERATE_COMPLETION {
3136                 var lt = (LocatedToken) $1;
3137                $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location);
3138           }
3139         | member_access
3140         ;
3141
3142 literal
3143         : boolean_literal
3144         | LITERAL
3145         | NULL                  { $$ = new NullLiteral (GetLocation ($1)); }
3146         ;
3147
3148 boolean_literal
3149         : TRUE                  { $$ = new BoolLiteral (compiler.BuiltinTypes, true, GetLocation ($1)); }
3150         | FALSE                 { $$ = new BoolLiteral (compiler.BuiltinTypes, false, GetLocation ($1)); }
3151         ;
3152
3153
3154 //
3155 // Here is the trick, tokenizer may think that parens is a special but
3156 // parser is interested in open parens only, so we merge them.
3157 // Consider: if (a)foo ();
3158 //
3159 open_parens_any
3160         : OPEN_PARENS
3161         | OPEN_PARENS_CAST
3162         ;
3163
3164 // 
3165 // Use this production to accept closing parenthesis or 
3166 // performing completion
3167 //
3168 close_parens
3169         : CLOSE_PARENS
3170         | COMPLETE_COMPLETION
3171         ;
3172
3173
3174 parenthesized_expression
3175         : OPEN_PARENS expression CLOSE_PARENS
3176           {
3177                 $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
3178                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
3179           }
3180         | OPEN_PARENS expression COMPLETE_COMPLETION
3181           {
3182                 $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
3183           }
3184         ;
3185         
3186 member_access
3187         : primary_expression DOT identifier_inside_body opt_type_argument_list
3188           {
3189                 var lt = (LocatedToken) $3;
3190                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3191                 lbag.AddLocation ($$, GetLocation ($2));
3192           }
3193         | builtin_types DOT identifier_inside_body opt_type_argument_list
3194           {
3195                 var lt = (LocatedToken) $3;
3196                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3197                 lbag.AddLocation ($$, GetLocation ($2));
3198           }
3199         | BASE DOT identifier_inside_body opt_type_argument_list
3200           {
3201                 var lt = (LocatedToken) $3;
3202                 $$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location);
3203                 lbag.AddLocation ($$, GetLocation ($2));
3204           }
3205         | AWAIT DOT identifier_inside_body opt_type_argument_list
3206           {
3207                 var lt = (LocatedToken) $3;
3208                 $$ = new MemberAccess (new SimpleName ("await", ((LocatedToken) $1).Location), lt.Value, (TypeArguments) $4, lt.Location);
3209                 lbag.AddLocation ($$, GetLocation ($2));
3210           }
3211         | qualified_alias_member identifier_inside_body opt_type_argument_list
3212           {
3213                 var lt1 = (LocatedToken) $1;
3214                 var lt2 = (LocatedToken) $2;
3215
3216                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
3217                 lbag.AddLocation ($$, GetLocation ($2));
3218           }
3219         | primary_expression DOT GENERATE_COMPLETION {
3220                 $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3));
3221           }
3222         | primary_expression DOT IDENTIFIER GENERATE_COMPLETION {
3223                 var lt = (LocatedToken) $3;
3224                 $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
3225           }
3226         | builtin_types DOT GENERATE_COMPLETION
3227           {
3228                 $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location);
3229           }
3230         | builtin_types DOT IDENTIFIER GENERATE_COMPLETION {
3231                 var lt = (LocatedToken) $3;
3232                 $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
3233           }
3234         ;
3235
3236 invocation_expression
3237         : primary_expression open_parens_any opt_argument_list close_parens
3238           {
3239                 $$ = new Invocation ((Expression) $1, (Arguments) $3);
3240                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3241           }
3242         | primary_expression open_parens_any argument_list error
3243           {
3244                 Error_SyntaxError (yyToken);
3245
3246                 $$ = new Invocation ((Expression) $1, (Arguments) $3);
3247                 lbag.AddLocation ($$, GetLocation ($2));
3248           }
3249         | primary_expression open_parens_any error
3250           {
3251                 Error_SyntaxError (yyToken);
3252
3253                 $$ = new Invocation ((Expression) $1, null);
3254                 lbag.AddLocation ($$, GetLocation ($2));
3255           }
3256         ;
3257
3258 opt_object_or_collection_initializer
3259         : /* empty */           { $$ = null; }
3260         | object_or_collection_initializer
3261         ;
3262
3263 object_or_collection_initializer
3264         : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion
3265           {
3266                 if ($2 == null) {
3267                         $$ = new CollectionOrObjectInitializers (GetLocation ($1));
3268                 } else {
3269                         $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
3270                 }
3271                 lbag.AddLocation ($$, GetLocation ($3));
3272           }
3273         | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE
3274           {
3275                 $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
3276                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4));
3277           }
3278         ;
3279
3280 opt_member_initializer_list
3281         : /* empty */           { $$ = null; }
3282         | member_initializer_list
3283         {
3284                 $$ = $1;
3285         }
3286         ;
3287
3288 member_initializer_list
3289         : member_initializer
3290           {
3291                 var a = new List<Expression> ();
3292                 a.Add ((Expression) $1);
3293                 $$ = a;
3294           }
3295         | member_initializer_list COMMA member_initializer
3296           {
3297                 var a = (List<Expression>)$1;
3298                 a.Add ((Expression) $3);
3299                 $$ = a;
3300           }
3301         | member_initializer_list error {
3302                 Error_SyntaxError (yyToken);
3303                 $$ = $1;
3304           }
3305         ;
3306
3307 member_initializer
3308         : IDENTIFIER ASSIGN initializer_value
3309           {
3310                 var lt = (LocatedToken) $1;
3311                 $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
3312                 lbag.AddLocation ($$, GetLocation ($2));
3313           }
3314         | AWAIT ASSIGN initializer_value
3315           {
3316                 var lt = (LocatedToken) Error_AwaitAsIdentifier ($1);
3317                 $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
3318                 lbag.AddLocation ($$, GetLocation ($2));
3319           }
3320         | GENERATE_COMPLETION 
3321           {
3322                 $$ = new CompletionElementInitializer (null, GetLocation ($1));
3323           }
3324         | non_assignment_expression opt_COMPLETE_COMPLETION  {
3325                 CompletionSimpleName csn = $1 as CompletionSimpleName;
3326                 if (csn == null)
3327                         $$ = new CollectionElementInitializer ((Expression)$1);
3328                 else
3329                         $$ = new CompletionElementInitializer (csn.Prefix, csn.Location);
3330           }
3331         | OPEN_BRACE expression_list CLOSE_BRACE
3332           {
3333                 if ($2 == null)
3334                         $$ = new CollectionElementInitializer (GetLocation ($1));
3335                 else
3336                         $$ = new CollectionElementInitializer ((List<Expression>)$2, GetLocation ($1));
3337
3338                 lbag.AddLocation ($$, GetLocation ($2));
3339           }
3340         | OPEN_BRACE CLOSE_BRACE
3341           {
3342                 report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
3343                 $$ = new CollectionElementInitializer (GetLocation ($1));
3344                 lbag.AddLocation ($$, GetLocation ($2));
3345           }
3346         ;
3347
3348 initializer_value
3349         : expression
3350         | object_or_collection_initializer
3351         ;
3352
3353 opt_argument_list
3354         : /* empty */           { $$ = null; }
3355         | argument_list
3356         ;
3357
3358 argument_list
3359         : argument_or_named_argument
3360           { 
3361                 Arguments list = new Arguments (4);
3362                 list.Add ((Argument) $1);
3363                 $$ = list;
3364           }
3365         | argument_list COMMA argument
3366           {
3367                 Arguments list = (Arguments) $1;
3368                 if (list [list.Count - 1] is NamedArgument)
3369                         Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]);
3370                 
3371                 list.Add ((Argument) $3);
3372                 $$ = list;
3373           }
3374         | argument_list COMMA named_argument
3375           {
3376                 Arguments list = (Arguments) $1;
3377                 NamedArgument a = (NamedArgument) $3;
3378                 for (int i = 0; i < list.Count; ++i) {
3379                         NamedArgument na = list [i] as NamedArgument;
3380                         if (na != null && na.Name == a.Name)
3381                                 report.Error (1740, na.Location, "Named argument `{0}' specified multiple times",
3382                                         na.Name);
3383                 }
3384                 
3385                 list.Add (a);
3386                 $$ = list;
3387           }
3388         | argument_list COMMA error
3389           {
3390                 if (lexer.putback_char == -1)
3391                         lexer.putback (')'); // TODO: Wrong but what can I do
3392                 Error_SyntaxError (yyToken);
3393                 $$ = $1;
3394           }
3395         | COMMA error
3396           {
3397                 report.Error (839, GetLocation ($1), "An argument is missing");
3398                 $$ = null;
3399           }
3400         ;
3401
3402 argument
3403         : expression
3404           {
3405                 $$ = new Argument ((Expression) $1);
3406           }
3407         | non_simple_argument
3408         ;
3409
3410 argument_or_named_argument
3411         : argument
3412         | named_argument
3413         ;
3414
3415 non_simple_argument
3416         : REF variable_reference 
3417           { 
3418                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3419                 lbag.AddLocation ($$, GetLocation ($1));
3420           }
3421         | OUT variable_reference 
3422           { 
3423                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
3424                 lbag.AddLocation ($$, GetLocation ($1));
3425           }
3426         | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
3427           {
3428                 $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1)));
3429                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3430           }
3431         | ARGLIST OPEN_PARENS CLOSE_PARENS
3432           {
3433                 $$ = new Argument (new Arglist (GetLocation ($1)));
3434                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
3435           }       
3436         ;
3437
3438 variable_reference
3439         : expression
3440         ;
3441
3442 element_access
3443         : primary_expression OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET  
3444           {
3445                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
3446                 lbag.AddLocation ($$, GetLocation ($4));
3447           }
3448         | primary_expression OPEN_BRACKET_EXPR expression_list_arguments error
3449           {
3450                 Error_SyntaxError (yyToken);
3451                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
3452           }
3453         | primary_expression OPEN_BRACKET_EXPR error
3454           {
3455                 Error_SyntaxError (yyToken);
3456                 $$ = new ElementAccess ((Expression) $1, null, GetLocation ($2));
3457           }
3458         ;
3459
3460 expression_list
3461         : expression_or_error
3462           {
3463                 var list = new List<Expression> (4);
3464                 list.Add ((Expression) $1);
3465                 $$ = list;
3466           }
3467         | expression_list COMMA expression_or_error
3468           {
3469                 var list = (List<Expression>) $1;
3470                 list.Add ((Expression) $3);
3471                 $$ = list;
3472           }
3473         ;
3474         
3475 expression_list_arguments
3476         : expression_list_argument
3477           {
3478                 Arguments args = new Arguments (4);
3479                 args.Add ((Argument) $1);
3480                 $$ = args;
3481           }
3482         | expression_list_arguments COMMA expression_list_argument
3483           {
3484                 Arguments args = (Arguments) $1;
3485                 if (args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
3486                         Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
3487           
3488                 args.Add ((Argument) $3);
3489                 $$ = args;        
3490           }
3491         ;
3492         
3493 expression_list_argument
3494         : expression
3495           {
3496                 $$ = new Argument ((Expression) $1);
3497           }
3498         | named_argument
3499         ;
3500
3501 this_access
3502         : THIS
3503           {
3504                 $$ = new This (GetLocation ($1));
3505           }
3506         ;
3507
3508 base_access
3509         : BASE OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
3510           {
3511                 $$ = new ElementAccess (new BaseThis (GetLocation ($1)), (Arguments) $3, GetLocation ($2));
3512                 lbag.AddLocation ($$, GetLocation ($4));
3513           }
3514         | BASE OPEN_BRACKET error
3515           {
3516                 Error_SyntaxError (yyToken);
3517                 $$ = new ElementAccess (null, null, GetLocation ($2));
3518           }
3519         ;
3520
3521 post_increment_expression
3522         : primary_expression OP_INC
3523           {
3524                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1, GetLocation ($2));
3525           }
3526         ;
3527
3528 post_decrement_expression
3529         : primary_expression OP_DEC
3530           {
3531                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1, GetLocation ($2));
3532           }
3533         ;
3534         
3535 object_or_delegate_creation_expression
3536         : NEW new_expr_type open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer
3537           {
3538                 if ($6 != null) {
3539                         if (lang_version <= LanguageVersion.ISO_2)
3540                                 FeatureIsNotAvailable (GetLocation ($1), "object initializers");
3541                                 
3542                         $$ = new NewInitialize ((FullNamedExpression) $2, (Arguments) $4, (CollectionOrObjectInitializers) $6, GetLocation ($1));
3543                 } else {
3544                         $$ = new New ((FullNamedExpression) $2, (Arguments) $4, GetLocation ($1));
3545                 }
3546                 
3547                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3548           }
3549         | NEW new_expr_type object_or_collection_initializer
3550           {
3551                 if (lang_version <= LanguageVersion.ISO_2)
3552                         FeatureIsNotAvailable (GetLocation ($1), "collection initializers");
3553           
3554                 $$ = new NewInitialize ((FullNamedExpression) $2, null, (CollectionOrObjectInitializers) $3, GetLocation ($1));
3555           }
3556         ;
3557
3558 array_creation_expression
3559         : NEW new_expr_type OPEN_BRACKET_EXPR expression_list CLOSE_BRACKET
3560           opt_rank_specifier
3561           opt_array_initializer
3562           {
3563                 $$ = new ArrayCreation ((FullNamedExpression) $2, (List<Expression>) $4,
3564                                 new ComposedTypeSpecifier (((List<Expression>) $4).Count, GetLocation ($3)) {
3565                                         Next = (ComposedTypeSpecifier) $6
3566                                 }, (ArrayInitializer) $7, GetLocation ($1));
3567                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3568           }
3569         | NEW new_expr_type rank_specifiers opt_array_initializer
3570           {
3571                 if ($4 == null)
3572                         report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer");
3573
3574                 $$ = new ArrayCreation ((FullNamedExpression) $2, (ComposedTypeSpecifier) $3, (ArrayInitializer) $4, GetLocation ($1));
3575           }
3576         | NEW rank_specifier array_initializer
3577           {
3578                 if (lang_version <= LanguageVersion.ISO_2)
3579                         FeatureIsNotAvailable (GetLocation ($1), "implicitly typed arrays");
3580           
3581                 $$ = new ImplicitlyTypedArrayCreation ((ComposedTypeSpecifier) $2, (ArrayInitializer) $3, GetLocation ($1));
3582           }
3583         | NEW new_expr_type OPEN_BRACKET CLOSE_BRACKET OPEN_BRACKET_EXPR error CLOSE_BRACKET
3584           {
3585                 report.Error (178, GetLocation ($6), "Invalid rank specifier, expecting `,' or `]'");
3586                 $$ = new ArrayCreation ((FullNamedExpression) $2, null, GetLocation ($1));
3587           }
3588         | NEW new_expr_type error
3589           {
3590                 Error_SyntaxError (yyToken);
3591                 // It can be any of new expression, create the most common one
3592                 $$ = new New ((FullNamedExpression) $2, null, GetLocation ($1));
3593           }
3594         ;
3595
3596 new_expr_type
3597         : {
3598                 ++lexer.parsing_type;
3599           }
3600           simple_type
3601           {
3602                 --lexer.parsing_type;
3603                 $$ = $2;
3604           }
3605         ;
3606
3607 anonymous_type_expression
3608         : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
3609           {
3610                 if (lang_version <= LanguageVersion.ISO_2)
3611                         FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
3612
3613                 $$ = new NewAnonymousType ((List<AnonymousTypeParameter>) $3, current_container, GetLocation ($1));
3614                 
3615                 // TODO: lbag comma location
3616                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3617           }
3618         ;
3619
3620 anonymous_type_parameters_opt_comma
3621         : anonymous_type_parameters_opt
3622         | anonymous_type_parameters COMMA
3623         ;
3624
3625 anonymous_type_parameters_opt
3626         : { $$ = null; }
3627         | anonymous_type_parameters
3628         ;
3629
3630 anonymous_type_parameters
3631         : anonymous_type_parameter
3632           {
3633                 var a = new List<AnonymousTypeParameter> (4);
3634                 a.Add ((AnonymousTypeParameter) $1);
3635                 $$ = a;
3636           }
3637         | anonymous_type_parameters COMMA anonymous_type_parameter
3638           {
3639                 var a = (List<AnonymousTypeParameter>) $1;
3640                 a.Add ((AnonymousTypeParameter) $3);
3641                 $$ = a;
3642           }
3643         ;
3644
3645 anonymous_type_parameter
3646         : identifier_inside_body ASSIGN variable_initializer
3647           {
3648                 var lt = (LocatedToken)$1;
3649                 $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
3650                 lbag.AddLocation ($$, GetLocation ($2));
3651           }
3652         | identifier_inside_body
3653           {
3654                 var lt = (LocatedToken)$1;
3655                 $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
3656                         lt.Value, lt.Location);
3657           }
3658         | member_access
3659           {
3660                 MemberAccess ma = (MemberAccess) $1;
3661                 $$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
3662           }
3663         | error
3664           {
3665                 report.Error (746, lexer.Location,
3666                         "Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression");
3667                 $$ = null;
3668           }
3669         ;
3670
3671 opt_rank_specifier
3672         : /* empty */
3673         | rank_specifiers
3674         ;
3675
3676 rank_specifiers
3677         : rank_specifier
3678         | rank_specifier rank_specifiers
3679           {
3680                 ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
3681                 $$ = $1;
3682           }
3683         ;
3684
3685 rank_specifier
3686         : OPEN_BRACKET CLOSE_BRACKET
3687           {
3688                 $$ = ComposedTypeSpecifier.CreateArrayDimension (1, GetLocation ($1));
3689                 lbag.AddLocation ($$, GetLocation ($2));
3690           }
3691         | OPEN_BRACKET dim_separators CLOSE_BRACKET
3692           {
3693                 $$ = ComposedTypeSpecifier.CreateArrayDimension ((int)$2, GetLocation ($1));
3694                 lbag.AddLocation ($$, GetLocation ($3));
3695           }
3696         ;
3697
3698 dim_separators
3699         : COMMA
3700           {
3701                 $$ = 2;
3702           }
3703         | dim_separators COMMA
3704           {
3705                 $$ = ((int) $1) + 1;
3706           }
3707         ;
3708
3709 opt_array_initializer
3710         : /* empty */
3711           {
3712                 $$ = null;
3713           }
3714         | array_initializer
3715           {
3716                 $$ = $1;
3717           }
3718         ;
3719
3720 array_initializer
3721         : OPEN_BRACE CLOSE_BRACE
3722           {
3723                 var ai = new ArrayInitializer (0, GetLocation ($1));
3724                 ai.VariableDeclaration = current_variable;
3725                 lbag.AddLocation (ai, GetLocation ($2));
3726                 $$ = ai;
3727           }
3728         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
3729           {
3730                 var ai = new ArrayInitializer ((List<Expression>) $2, GetLocation ($1));
3731                 ai.VariableDeclaration = current_variable;
3732                 if ($3 != null) {
3733                         lbag.AddLocation (ai, GetLocation ($3), GetLocation ($4));
3734                 } else {
3735                         lbag.AddLocation (ai, GetLocation ($4));
3736                 }
3737                 $$ = ai;
3738           }
3739         ;
3740
3741 variable_initializer_list
3742         : variable_initializer
3743           {
3744                 var list = new List<Expression> (4);
3745                 list.Add ((Expression) $1);
3746                 $$ = list;
3747           }
3748         | variable_initializer_list COMMA variable_initializer
3749           {
3750                 var list = (List<Expression>) $1;
3751                 list.Add ((Expression) $3);
3752                 $$ = list;
3753           }
3754         ;
3755
3756 typeof_expression
3757         : TYPEOF
3758       {
3759                 lexer.TypeOfParsing = true;
3760           }
3761           open_parens_any typeof_type_expression CLOSE_PARENS
3762           {
3763                 lexer.TypeOfParsing = false;
3764                 $$ = new TypeOf ((FullNamedExpression) $4, GetLocation ($1));
3765                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3766           }
3767         ;
3768         
3769 typeof_type_expression
3770         : type_and_void
3771         | unbound_type_name
3772         | error
3773          {
3774                 Error_TypeExpected (lexer.Location);
3775                 $$ = null;
3776          }
3777         ;
3778         
3779 unbound_type_name
3780         : identifier_inside_body generic_dimension
3781           {  
3782                 var lt = (LocatedToken) $1;
3783
3784                 $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
3785           }
3786         | qualified_alias_member identifier_inside_body generic_dimension
3787           {
3788                 var lt1 = (LocatedToken) $1;
3789                 var lt2 = (LocatedToken) $2;
3790
3791                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
3792                 lbag.AddLocation ($$, GetLocation ($2));
3793           }
3794         | unbound_type_name DOT identifier_inside_body
3795           {
3796                 var lt = (LocatedToken) $3;
3797                 
3798                 $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);         
3799           }
3800         | unbound_type_name DOT identifier_inside_body generic_dimension
3801           {
3802                 var lt = (LocatedToken) $3;
3803                 
3804                 $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);               
3805           }
3806         | namespace_or_type_expr DOT identifier_inside_body generic_dimension
3807           {
3808                 var tne = (ATypeNameExpression) $1;
3809                 if (tne.HasTypeArguments)
3810                         Error_TypeExpected (GetLocation ($4));
3811
3812                 var lt = (LocatedToken) $3;
3813                 $$ = new MemberAccess (tne, lt.Value, (int) $4, lt.Location);           
3814           }
3815         ;
3816
3817 generic_dimension
3818         : GENERIC_DIMENSION
3819           {
3820                 if (lang_version < LanguageVersion.ISO_2)
3821                         FeatureIsNotAvailable (GetLocation ($1), "generics");
3822
3823                 $$ = $1;
3824           }
3825         ;
3826         
3827 qualified_alias_member
3828         : IDENTIFIER DOUBLE_COLON
3829           {
3830                 var lt = (LocatedToken) $1;
3831                 if (lang_version == LanguageVersion.ISO_1)
3832                         FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
3833
3834                 $$ = lt;                
3835           }
3836         ;
3837
3838 sizeof_expression
3839         : SIZEOF open_parens_any type CLOSE_PARENS
3840           { 
3841                 $$ = new SizeOf ((Expression) $3, GetLocation ($1));
3842                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3843           }
3844         | SIZEOF open_parens_any type error
3845           {
3846                 Error_SyntaxError (yyToken);
3847
3848                 $$ = new SizeOf ((Expression) $3, GetLocation ($1));
3849                 lbag.AddLocation ($$, GetLocation ($2));
3850           }
3851         ;
3852
3853 checked_expression
3854         : CHECKED open_parens_any expression CLOSE_PARENS
3855           {
3856                 $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
3857                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3858           }
3859         | CHECKED error
3860           {
3861                 Error_SyntaxError (yyToken);
3862
3863                 $$ = new CheckedExpr (null, GetLocation ($1));
3864           }
3865         ;
3866
3867 unchecked_expression
3868         : UNCHECKED open_parens_any expression CLOSE_PARENS
3869           {
3870                 $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
3871                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3872           }
3873         | UNCHECKED error
3874           {
3875                 Error_SyntaxError (yyToken);
3876
3877                 $$ = new UnCheckedExpr (null, GetLocation ($1));
3878           }
3879         ;
3880
3881 pointer_member_access
3882         : primary_expression OP_PTR IDENTIFIER opt_type_argument_list
3883           {
3884                 var lt = (LocatedToken) $3;
3885                 $$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, (TypeArguments) $4, lt.Location);
3886           }
3887         ;
3888
3889 anonymous_method_expression
3890         : DELEGATE opt_anonymous_method_signature
3891           {
3892                 start_anonymous (false, (ParametersCompiled) $2, false, GetLocation ($1));
3893           }
3894           block
3895           {
3896                 $$ = end_anonymous ((ParametersBlock) $4);
3897           }
3898         | ASYNC DELEGATE opt_anonymous_method_signature
3899           {
3900                 start_anonymous (false, (ParametersCompiled) $3, true, GetLocation ($1));
3901           }
3902           block
3903           {
3904                 $$ = end_anonymous ((ParametersBlock) $5);
3905           }
3906         ;
3907
3908 opt_anonymous_method_signature
3909         : 
3910           {
3911                 $$ = ParametersCompiled.Undefined;
3912           } 
3913         | anonymous_method_signature
3914         ;
3915
3916 anonymous_method_signature
3917         : OPEN_PARENS
3918           {
3919                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
3920           }
3921           opt_formal_parameter_list CLOSE_PARENS
3922           {
3923                 valid_param_mod = 0;
3924                 $$ = $3;
3925           }
3926         ;
3927
3928 default_value_expression
3929         : DEFAULT open_parens_any type CLOSE_PARENS
3930           {
3931                 if (lang_version < LanguageVersion.ISO_2)
3932                         FeatureIsNotAvailable (GetLocation ($1), "default value expression");
3933
3934                 $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1));
3935                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3936           }
3937         ;
3938
3939 unary_expression
3940         : primary_expression
3941         | BANG prefixed_unary_expression
3942           {
3943                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1));
3944           }
3945         | TILDE prefixed_unary_expression
3946           {
3947                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
3948           }
3949         | OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
3950           {
3951                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3952                 lbag.AddLocation ($$, GetLocation ($3));
3953           }
3954         | AWAIT prefixed_unary_expression
3955           {
3956                 if (!async_block) {
3957                          if (current_anonymous_method is LambdaExpression) {
3958                                 report.Error (4034, GetLocation ($1),
3959                                         "The `await' operator can only be used when its containing lambda expression is marked with the `async' modifier");
3960                         } else if (current_anonymous_method != null) {
3961                                 report.Error (4035, GetLocation ($1),
3962                                         "The `await' operator can only be used when its containing anonymous method is marked with the `async' modifier");
3963                         } else if (interactive_async != null) {
3964                                 current_block.Explicit.RegisterAsyncAwait ();
3965                                 interactive_async = true;
3966                         } else {
3967                                 report.Error (4033, GetLocation ($1),
3968                                         "The `await' operator can only be used when its containing method is marked with the `async' modifier");
3969                         }
3970                 } else {
3971                         current_block.Explicit.RegisterAsyncAwait ();
3972                 }
3973                 
3974                 $$ = new Await ((Expression) $2, GetLocation ($1));
3975           }
3976         | BANG error
3977           {
3978                 Error_SyntaxError (yyToken);
3979
3980                 $$ = new Unary (Unary.Operator.LogicalNot, null, GetLocation ($1));
3981           }
3982         | TILDE error
3983           {
3984                 Error_SyntaxError (yyToken);
3985
3986                 $$ = new Unary (Unary.Operator.OnesComplement, null, GetLocation ($1));
3987           }
3988         | OPEN_PARENS_CAST type CLOSE_PARENS error
3989           {
3990                 Error_SyntaxError (yyToken);
3991
3992                 $$ = new Cast ((FullNamedExpression) $2, null, GetLocation ($1));
3993                 lbag.AddLocation ($$, GetLocation ($3));
3994           }
3995         | AWAIT error
3996           {
3997                 Error_SyntaxError (yyToken);
3998
3999                 $$ = new Await (null, GetLocation ($1));
4000           }
4001         ;
4002
4003         //
4004         // The idea to split this out is from Rhys' grammar
4005         // to solve the problem with casts.
4006         //
4007 prefixed_unary_expression
4008         : unary_expression
4009         | PLUS prefixed_unary_expression
4010           { 
4011                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
4012           } 
4013         | MINUS prefixed_unary_expression 
4014           { 
4015                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
4016           }
4017         | OP_INC prefixed_unary_expression 
4018           {
4019                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1));
4020           }
4021         | OP_DEC prefixed_unary_expression 
4022           {
4023                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1));
4024           }
4025         | STAR prefixed_unary_expression
4026           {
4027                 $$ = new Indirection ((Expression) $2, GetLocation ($1));
4028           }
4029         | BITWISE_AND prefixed_unary_expression
4030           {
4031                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1));
4032           }
4033         | PLUS error
4034           { 
4035                 Error_SyntaxError (yyToken);
4036
4037                 $$ = new Unary (Unary.Operator.UnaryPlus, null, GetLocation ($1));
4038           } 
4039         | MINUS error 
4040           { 
4041                 Error_SyntaxError (yyToken);
4042
4043                 $$ = new Unary (Unary.Operator.UnaryNegation, null, GetLocation ($1));
4044           }
4045         | OP_INC error 
4046           {
4047                 Error_SyntaxError (yyToken);
4048
4049                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, null, GetLocation ($1));
4050           }
4051         | OP_DEC error 
4052           {
4053                 Error_SyntaxError (yyToken);
4054
4055                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, null, GetLocation ($1));
4056           }
4057         | STAR error
4058           {
4059                 Error_SyntaxError (yyToken);
4060
4061                 $$ = new Indirection (null, GetLocation ($1));
4062           }
4063         | BITWISE_AND error
4064           {
4065                 Error_SyntaxError (yyToken);
4066
4067                 $$ = new Unary (Unary.Operator.AddressOf, null, GetLocation ($1));
4068           }
4069         ;
4070
4071 multiplicative_expression
4072         : prefixed_unary_expression
4073         | multiplicative_expression STAR prefixed_unary_expression
4074           {
4075                 $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
4076                 lbag.AddLocation ($$, GetLocation ($2));
4077           }
4078         | multiplicative_expression DIV prefixed_unary_expression
4079           {
4080                 $$ = new Binary (Binary.Operator.Division, (Expression) $1, (Expression) $3);
4081                 lbag.AddLocation ($$, GetLocation ($2));
4082           }
4083         | multiplicative_expression PERCENT prefixed_unary_expression 
4084           {
4085                 $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
4086                 lbag.AddLocation ($$, GetLocation ($2));
4087           }
4088         | multiplicative_expression STAR error
4089           {
4090                 Error_SyntaxError (yyToken);
4091
4092                 $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, null);
4093                 lbag.AddLocation ($$, GetLocation ($2));
4094           }
4095         | multiplicative_expression DIV error
4096           {
4097                 Error_SyntaxError (yyToken);
4098
4099                 $$ = new Binary (Binary.Operator.Division, (Expression) $1, null);
4100                 lbag.AddLocation ($$, GetLocation ($2));
4101           }
4102         | multiplicative_expression PERCENT error 
4103           {
4104                 Error_SyntaxError (yyToken);
4105
4106                 $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, null);
4107                 lbag.AddLocation ($$, GetLocation ($2));
4108           }
4109         ;
4110
4111 additive_expression
4112         : multiplicative_expression
4113         | additive_expression PLUS multiplicative_expression 
4114           {
4115                 $$ = new Binary (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
4116                 lbag.AddLocation ($$, GetLocation ($2));
4117           }
4118         | additive_expression MINUS multiplicative_expression
4119           {
4120                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
4121                 lbag.AddLocation ($$, GetLocation ($2));
4122           }
4123         | additive_expression AS type
4124           {
4125                 $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
4126           }
4127         | additive_expression IS type
4128           {
4129                 $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
4130           }       
4131         | additive_expression PLUS error 
4132           {
4133                 Error_SyntaxError (yyToken);
4134
4135                 $$ = new Binary (Binary.Operator.Addition, (Expression) $1, null);
4136                 lbag.AddLocation ($$, GetLocation ($2));
4137           }
4138         | additive_expression MINUS error
4139           {
4140                 Error_SyntaxError (yyToken);
4141
4142                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, null);
4143                 lbag.AddLocation ($$, GetLocation ($2));
4144           }
4145         | additive_expression AS error
4146           {
4147                 Error_SyntaxError (yyToken);
4148
4149                 $$ = new As ((Expression) $1, null, GetLocation ($2));
4150           }
4151         | additive_expression IS error
4152           {
4153                 Error_SyntaxError (yyToken);
4154
4155                 $$ = new Is ((Expression) $1, null, GetLocation ($2));
4156           }
4157         ;
4158
4159 shift_expression
4160         : additive_expression
4161         | shift_expression OP_SHIFT_LEFT additive_expression
4162           {
4163                 $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
4164                 lbag.AddLocation ($$, GetLocation ($2));
4165           }
4166         | shift_expression OP_SHIFT_RIGHT additive_expression
4167           {
4168                 $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
4169                 lbag.AddLocation ($$, GetLocation ($2));
4170           }
4171         | shift_expression OP_SHIFT_LEFT error
4172           {
4173                 Error_SyntaxError (yyToken);
4174
4175                 $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, null);
4176                 lbag.AddLocation ($$, GetLocation ($2));
4177           }
4178         | shift_expression OP_SHIFT_RIGHT error
4179           {
4180                 Error_SyntaxError (yyToken);
4181
4182                 $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, null);
4183                 lbag.AddLocation ($$, GetLocation ($2));
4184           }
4185         ; 
4186
4187 relational_expression
4188         : shift_expression
4189         | relational_expression OP_LT shift_expression
4190           {
4191                 $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, (Expression) $3);
4192                 lbag.AddLocation ($$, GetLocation ($2));
4193           }
4194         | relational_expression OP_GT shift_expression
4195           {
4196                 $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, (Expression) $3);
4197                 lbag.AddLocation ($$, GetLocation ($2));
4198           }
4199         | relational_expression OP_LE shift_expression
4200           {
4201                 $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, (Expression) $3);
4202                 lbag.AddLocation ($$, GetLocation ($2));
4203           }
4204         | relational_expression OP_GE shift_expression
4205           {
4206                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3);
4207                 lbag.AddLocation ($$, GetLocation ($2));
4208           }
4209         | relational_expression OP_LT error
4210           {
4211                 Error_SyntaxError (yyToken);
4212
4213                 $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, null);
4214                 lbag.AddLocation ($$, GetLocation ($2));
4215           }
4216         | relational_expression OP_GT error
4217           {
4218                 Error_SyntaxError (yyToken);
4219
4220                 $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, null);
4221                 lbag.AddLocation ($$, GetLocation ($2));
4222           }
4223         | relational_expression OP_LE error
4224           {
4225                 Error_SyntaxError (yyToken);
4226
4227                 $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, null);
4228                 lbag.AddLocation ($$, GetLocation ($2));
4229           }
4230         | relational_expression OP_GE error
4231           {
4232                 Error_SyntaxError (yyToken);
4233
4234                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, null);
4235                 lbag.AddLocation ($$, GetLocation ($2));
4236           }
4237         ;
4238
4239 equality_expression
4240         : relational_expression
4241         | equality_expression OP_EQ relational_expression
4242           {
4243                 $$ = new Binary (Binary.Operator.Equality, (Expression) $1, (Expression) $3);
4244                 lbag.AddLocation ($$, GetLocation ($2));
4245           }
4246         | equality_expression OP_NE relational_expression
4247           {
4248                 $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, (Expression) $3);
4249                 lbag.AddLocation ($$, GetLocation ($2));
4250           }
4251         | equality_expression OP_EQ error
4252           {
4253                 Error_SyntaxError (yyToken);
4254
4255                 $$ = new Binary (Binary.Operator.Equality, (Expression) $1, null);
4256                 lbag.AddLocation ($$, GetLocation ($2));
4257           }
4258         | equality_expression OP_NE error
4259           {
4260                 Error_SyntaxError (yyToken);
4261
4262                 $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, null);
4263                 lbag.AddLocation ($$, GetLocation ($2));
4264           }
4265         ; 
4266
4267 and_expression
4268         : equality_expression
4269         | and_expression BITWISE_AND equality_expression
4270           {
4271                 $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
4272                 lbag.AddLocation ($$, GetLocation ($2));
4273           }
4274         | and_expression BITWISE_AND error
4275           {
4276                 Error_SyntaxError (yyToken);
4277
4278                 $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, null);
4279                 lbag.AddLocation ($$, GetLocation ($2));
4280           }
4281         ;
4282
4283 exclusive_or_expression
4284         : and_expression
4285         | exclusive_or_expression CARRET and_expression
4286           {
4287                 $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
4288                 lbag.AddLocation ($$, GetLocation ($2));
4289           }
4290         | exclusive_or_expression CARRET error
4291           {
4292                 Error_SyntaxError (yyToken);
4293
4294                 $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, null);
4295                 lbag.AddLocation ($$, GetLocation ($2));
4296           }
4297         ;
4298
4299 inclusive_or_expression
4300         : exclusive_or_expression
4301         | inclusive_or_expression BITWISE_OR exclusive_or_expression
4302           {
4303                 $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
4304                 lbag.AddLocation ($$, GetLocation ($2));
4305           }
4306         | inclusive_or_expression BITWISE_OR error
4307           {
4308                 Error_SyntaxError (yyToken);
4309
4310                 $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, null);
4311                 lbag.AddLocation ($$, GetLocation ($2));
4312           }
4313         ;
4314
4315 conditional_and_expression
4316         : inclusive_or_expression
4317         | conditional_and_expression OP_AND inclusive_or_expression
4318           {
4319                 $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3);
4320                 lbag.AddLocation ($$, GetLocation ($2));
4321           }
4322         | conditional_and_expression OP_AND error
4323           {
4324                 Error_SyntaxError (yyToken);
4325
4326                 $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, null);
4327                 lbag.AddLocation ($$, GetLocation ($2));
4328           }
4329         ;
4330
4331 conditional_or_expression
4332         : conditional_and_expression
4333         | conditional_or_expression OP_OR conditional_and_expression
4334           {
4335                 $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3);
4336                 lbag.AddLocation ($$, GetLocation ($2));
4337           }
4338         | conditional_or_expression OP_OR error
4339           {
4340                 Error_SyntaxError (yyToken);
4341
4342                 $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, null);
4343                 lbag.AddLocation ($$, GetLocation ($2));
4344           }
4345         ;
4346         
4347 null_coalescing_expression
4348         : conditional_or_expression
4349         | conditional_or_expression OP_COALESCING null_coalescing_expression
4350           {
4351                 if (lang_version < LanguageVersion.ISO_2)
4352                         FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
4353                         
4354                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3);
4355                 lbag.AddLocation ($$, GetLocation ($2));
4356           }
4357         ;
4358
4359 conditional_expression
4360         : null_coalescing_expression
4361         | null_coalescing_expression INTERR expression COLON expression
4362           {
4363                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
4364                 lbag.AddLocation ($$, GetLocation ($4));
4365           }
4366         | null_coalescing_expression INTERR expression error
4367           {
4368                 Error_SyntaxError (yyToken);
4369
4370                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
4371           }
4372         | null_coalescing_expression INTERR expression COLON error
4373           {
4374                 Error_SyntaxError (yyToken);
4375
4376                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
4377                 lbag.AddLocation ($$, GetLocation ($4));
4378           }
4379         | null_coalescing_expression INTERR expression COLON CLOSE_BRACE
4380           {
4381                 Error_SyntaxError (Token.CLOSE_BRACE);
4382
4383                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
4384                 lbag.AddLocation ($$, GetLocation ($4));
4385                 lexer.putback ('}');
4386           }
4387         ;
4388
4389 assignment_expression
4390         : prefixed_unary_expression ASSIGN expression
4391           {
4392                 $$ = new SimpleAssign ((Expression) $1, (Expression) $3);
4393                 lbag.AddLocation ($$, GetLocation ($2));
4394           }
4395         | prefixed_unary_expression OP_MULT_ASSIGN expression
4396           {
4397                 $$ = new CompoundAssign (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
4398                 lbag.AddLocation ($$, GetLocation ($2));
4399           }
4400         | prefixed_unary_expression OP_DIV_ASSIGN expression
4401           {
4402                 $$ = new CompoundAssign (Binary.Operator.Division, (Expression) $1, (Expression) $3);
4403                 lbag.AddLocation ($$, GetLocation ($2));
4404           }
4405         | prefixed_unary_expression OP_MOD_ASSIGN expression
4406           {
4407                 $$ = new CompoundAssign (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
4408                 lbag.AddLocation ($$, GetLocation ($2));
4409           }
4410         | prefixed_unary_expression OP_ADD_ASSIGN expression
4411           {
4412                 $$ = new CompoundAssign (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
4413                 lbag.AddLocation ($$, GetLocation ($2));
4414           }
4415         | prefixed_unary_expression OP_SUB_ASSIGN expression
4416           {
4417                 $$ = new CompoundAssign (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
4418                 lbag.AddLocation ($$, GetLocation ($2));
4419           }
4420         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
4421           {
4422                 $$ = new CompoundAssign (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
4423                 lbag.AddLocation ($$, GetLocation ($2));
4424           }
4425         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
4426           {
4427                 $$ = new CompoundAssign (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
4428                 lbag.AddLocation ($$, GetLocation ($2));
4429           }
4430         | prefixed_unary_expression OP_AND_ASSIGN expression
4431           {
4432                 $$ = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
4433                 lbag.AddLocation ($$, GetLocation ($2));
4434           }
4435         | prefixed_unary_expression OP_OR_ASSIGN expression
4436           {
4437                 $$ = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
4438                 lbag.AddLocation ($$, GetLocation ($2));
4439           }
4440         | prefixed_unary_expression OP_XOR_ASSIGN expression
4441           {
4442                 $$ = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
4443                 lbag.AddLocation ($$, GetLocation ($2));
4444           }
4445         ;
4446
4447 lambda_parameter_list
4448         : lambda_parameter
4449           {
4450                 var pars = new List<Parameter> (4);
4451                 pars.Add ((Parameter) $1);
4452
4453                 $$ = pars;
4454           }
4455         | lambda_parameter_list COMMA lambda_parameter
4456           {
4457                 var pars = (List<Parameter>) $1;
4458                 Parameter p = (Parameter)$3;
4459                 if (pars[0].GetType () != p.GetType ()) {
4460                         report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
4461                 }
4462                 
4463                 pars.Add (p);
4464                 $$ = pars;
4465           }
4466         ;
4467
4468 lambda_parameter
4469         : parameter_modifier parameter_type identifier_inside_body
4470           {
4471                 var lt = (LocatedToken) $3;
4472
4473                 $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
4474           }
4475         | parameter_type identifier_inside_body
4476           {
4477                 var lt = (LocatedToken) $2;
4478
4479                 $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
4480           }
4481         | IDENTIFIER
4482           {
4483                 var lt = (LocatedToken) $1;
4484                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
4485           }
4486         | AWAIT
4487           {
4488                 var lt = (LocatedToken) Error_AwaitAsIdentifier ($1);
4489                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
4490           }
4491         ;
4492
4493 opt_lambda_parameter_list
4494         : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
4495         | lambda_parameter_list         { 
4496                 var pars_list = (List<Parameter>) $1;
4497                 $$ = new ParametersCompiled (pars_list.ToArray ());
4498           }
4499         ;
4500
4501 lambda_expression_body
4502         : {
4503                 start_block (Location.Null);
4504           }
4505           expression    // All expressions must handle error or current block won't be restored and breaking ast completely
4506           {
4507                 Block b = end_block (Location.Null);
4508                 b.IsCompilerGenerated = true;
4509                 b.AddStatement (new ContextualReturn ((Expression) $2));
4510                 $$ = b;
4511           } 
4512         | block
4513         | error
4514           {
4515                 // Handles only cases like foo = x.FirstOrDefault (l => );
4516                 // where we must restore current_variable
4517                 Block b = end_block (Location.Null);
4518                 b.IsCompilerGenerated = true;
4519
4520                 Error_SyntaxError (yyToken);
4521                 $$ = null;
4522           }
4523         ;
4524
4525 expression_or_error
4526         : expression
4527         | error
4528           {
4529                 Error_SyntaxError (yyToken);
4530                 $$ = null;
4531           }
4532         ;
4533         
4534 lambda_expression
4535         : IDENTIFIER ARROW 
4536           {
4537                 var lt = (LocatedToken) $1;     
4538                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4539                 start_anonymous (true, new ParametersCompiled (p), false, lt.Location);
4540           }
4541           lambda_expression_body
4542           {
4543                 $$ = end_anonymous ((ParametersBlock) $4);
4544                 lbag.AddLocation ($$, GetLocation ($2));
4545           }
4546         | AWAIT ARROW
4547           {
4548                 var lt = (LocatedToken) Error_AwaitAsIdentifier ($1);
4549                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4550                 start_anonymous (true, new ParametersCompiled (p), false, lt.Location);
4551           }
4552           lambda_expression_body
4553           {
4554                 $$ = end_anonymous ((ParametersBlock) $4);
4555                 lbag.AddLocation ($$, GetLocation ($2));
4556           }
4557         | ASYNC identifier_inside_body ARROW
4558           {
4559                 var lt = (LocatedToken) $2;
4560                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4561                 start_anonymous (true, new ParametersCompiled (p), true, lt.Location);
4562           }
4563           lambda_expression_body
4564           {
4565                 $$ = end_anonymous ((ParametersBlock) $5);
4566                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
4567           }
4568         | OPEN_PARENS_LAMBDA
4569           {
4570                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
4571           }
4572           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4573           {
4574                 valid_param_mod = 0;
4575                 start_anonymous (true, (ParametersCompiled) $3, false, GetLocation ($1));
4576           }
4577           lambda_expression_body
4578           {
4579                 $$ = end_anonymous ((ParametersBlock) $7);
4580                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($4), GetLocation ($5));
4581           }
4582         | ASYNC OPEN_PARENS_LAMBDA
4583           {
4584                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;          
4585           }
4586           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4587           {
4588                 valid_param_mod = 0;
4589                 start_anonymous (true, (ParametersCompiled) $4, true, GetLocation ($1));
4590           }
4591           lambda_expression_body
4592           {
4593                 $$ = end_anonymous ((ParametersBlock) $8);
4594                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($5), GetLocation ($6));
4595           }
4596         ;
4597
4598 expression
4599         : assignment_expression 
4600         | non_assignment_expression
4601         ;
4602         
4603 non_assignment_expression
4604         : conditional_expression
4605         | lambda_expression
4606         | query_expression
4607         | ARGLIST
4608           {
4609                 $$ = new ArglistAccess (GetLocation ($1));
4610           }
4611         ;
4612         
4613 undocumented_expressions
4614         : REFVALUE OPEN_PARENS non_assignment_expression COMMA type CLOSE_PARENS
4615           {
4616                 $$ = new RefValueExpr ((Expression) $3, (FullNamedExpression) $5, GetLocation ($1));
4617                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
4618           }
4619         | REFTYPE open_parens_any expression CLOSE_PARENS
4620           {
4621                 $$ = new RefTypeExpr ((Expression) $3, GetLocation ($1));
4622                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
4623           }
4624         | MAKEREF open_parens_any expression CLOSE_PARENS
4625           {
4626                 $$ = new MakeRefExpr ((Expression) $3, GetLocation ($1));
4627                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));        
4628           }
4629         ;
4630
4631 constant_expression
4632         : expression
4633         ;
4634
4635 boolean_expression
4636         : expression
4637           {
4638                 $$ = new BooleanExpression ((Expression) $1);
4639           }
4640         ;
4641
4642 opt_primary_parameters
4643         : /* empty */
4644           {
4645                 $$ = null;
4646           }
4647         | primary_parameters
4648         ;
4649
4650 primary_parameters
4651         : OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
4652           {
4653                 $$ = $2;
4654
4655                 // Cannot use opt_formal_parameter_list because it can be shared instance for empty parameters
4656                 lbag.AppendToMember (current_container, GetLocation ($1), GetLocation ($3));
4657           }
4658         ;
4659
4660 opt_primary_parameters_with_class_base
4661         : /* empty */
4662           {
4663                 $$ = null;
4664           }
4665         | class_base
4666           {
4667                 $$ = null;
4668           }
4669         | primary_parameters
4670           {
4671                 $$ = $1;
4672           }
4673         | primary_parameters class_base OPEN_PARENS
4674           {
4675                 ++lexer.parsing_block;
4676           }
4677           opt_argument_list CLOSE_PARENS
4678           {
4679                 lbag.AppendToMember (current_container, GetLocation ($3), GetLocation ($6));
4680                 ((Class)current_type).PrimaryConstructorBaseArguments = (Arguments) $5;
4681                 --lexer.parsing_block;
4682
4683                 $$ = $1;
4684           }
4685         ;
4686
4687 //
4688 // 10 classes
4689 //
4690 class_declaration
4691         : opt_attributes
4692           opt_modifiers
4693           opt_partial
4694           CLASS
4695           {
4696           }
4697           type_declaration_name
4698           {
4699                 lexer.ConstraintsParsing = true;
4700
4701                 Class c = new Class (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1);
4702                 if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) {
4703                         FeatureIsNotAvailable (c.Location, "static classes");
4704                 }
4705                         
4706                 push_current_container (c, $3);
4707                 valid_param_mod = ParameterModifierType.PrimaryConstructor;
4708           }
4709           opt_primary_parameters_with_class_base
4710           opt_type_parameter_constraints_clauses
4711           {
4712                 valid_param_mod = 0;
4713                 lexer.ConstraintsParsing = false;
4714
4715                 if ($8 != null)
4716                         current_type.PrimaryConstructorParameters = (ParametersCompiled) $8;
4717
4718                 if ($9 != null)
4719                         current_container.SetConstraints ((List<Constraints>) $9);
4720                 lbag.AddMember (current_container, mod_locations, GetLocation ($4));
4721
4722                 if (doc_support) {
4723                         current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
4724                         Lexer.doc_state = XmlCommentState.Allowed;
4725                 }
4726                 
4727                 lexer.parsing_modifiers = true;
4728           }
4729           OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
4730           {
4731                 --lexer.parsing_declaration;
4732                 if (doc_support)
4733                         Lexer.doc_state = XmlCommentState.Allowed;
4734           }
4735           opt_semicolon 
4736           {
4737                 if ($15 == null) {
4738                         lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13));
4739                 } else {
4740                         lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13), GetLocation ($15));
4741                 }
4742                 $$ = pop_current_class ();
4743           }
4744         ;       
4745
4746 opt_partial
4747         : /* empty */
4748           { $$ = null; }
4749         | PARTIAL
4750           { $$ = $1; } // location
4751         ;
4752
4753 opt_modifiers
4754         : /* empty */
4755           {
4756             mod_locations = null;
4757                 $$ = ModifierNone;
4758                 lexer.parsing_modifiers = false;
4759           }
4760         | modifiers
4761           {
4762                 lexer.parsing_modifiers = false;                
4763           }
4764         ;
4765
4766 modifiers
4767         : modifier
4768         | modifiers modifier
4769           { 
4770                 var m1 = (Modifiers) $1;
4771                 var m2 = (Modifiers) $2;
4772
4773                 if ((m1 & m2) != 0) {
4774                         report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length,
4775                                 "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2));
4776                 } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 &&
4777                         ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) {
4778                         report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length,
4779                                 "More than one protection modifier specified");
4780                 }
4781                 
4782                 $$ = m1 | m2;
4783           }
4784         ;
4785
4786 modifier
4787         : NEW
4788           {
4789                 $$ = Modifiers.NEW;
4790                 StoreModifierLocation ($$, GetLocation ($1));
4791                 
4792                 if (current_container.Kind == MemberKind.Namespace)
4793                         report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements");
4794           }
4795         | PUBLIC
4796           {
4797                 $$ = Modifiers.PUBLIC;
4798                 StoreModifierLocation ($$, GetLocation ($1));
4799           }
4800         | PROTECTED
4801           {
4802                 $$ = Modifiers.PROTECTED;
4803                 StoreModifierLocation ($$, GetLocation ($1));
4804           }
4805         | INTERNAL
4806           {
4807                 $$ = Modifiers.INTERNAL;
4808                 StoreModifierLocation ($$, GetLocation ($1));
4809           }
4810         | PRIVATE
4811           {
4812                 $$ = Modifiers.PRIVATE;
4813                 StoreModifierLocation ($$, GetLocation ($1));
4814           }
4815         | ABSTRACT
4816           {
4817                 $$ = Modifiers.ABSTRACT;
4818                 StoreModifierLocation ($$, GetLocation ($1));
4819           }
4820         | SEALED
4821           {
4822                 $$ = Modifiers.SEALED;
4823                 StoreModifierLocation ($$, GetLocation ($1));
4824           }
4825         | STATIC
4826           {
4827                 $$ = Modifiers.STATIC;
4828                 StoreModifierLocation ($$, GetLocation ($1));
4829           }
4830         | READONLY
4831           {
4832                 $$ = Modifiers.READONLY;
4833                 StoreModifierLocation ($$, GetLocation ($1));
4834           }
4835         | VIRTUAL
4836           {
4837                 $$ = Modifiers.VIRTUAL;
4838                 StoreModifierLocation ($$, GetLocation ($1));
4839           }
4840         | OVERRIDE
4841           {
4842                 $$ = Modifiers.OVERRIDE;
4843                 StoreModifierLocation ($$, GetLocation ($1));
4844           }
4845         | EXTERN
4846           {
4847                 $$ = Modifiers.EXTERN;
4848                 StoreModifierLocation ($$, GetLocation ($1));
4849           }
4850         | VOLATILE
4851           {
4852                 $$ = Modifiers.VOLATILE;
4853                 StoreModifierLocation ($$, GetLocation ($1));
4854           }
4855         | UNSAFE
4856           {
4857                 $$ = Modifiers.UNSAFE;
4858                 StoreModifierLocation ($$, GetLocation ($1));
4859                 if (!settings.Unsafe)
4860                         Error_UnsafeCodeNotAllowed (GetLocation ($1));
4861           }
4862         | ASYNC
4863           {
4864                 $$ = Modifiers.ASYNC;
4865                 StoreModifierLocation ($$, GetLocation ($1));
4866           }
4867         ;
4868         
4869 opt_class_base
4870         : /* empty */
4871         | class_base
4872         ;
4873
4874 class_base
4875         : COLON type_list
4876          {
4877                 current_type.SetBaseTypes ((List<FullNamedExpression>) $2);
4878          }
4879         | COLON type_list error
4880           {
4881                 Error_SyntaxError (yyToken);
4882
4883                 current_type.SetBaseTypes ((List<FullNamedExpression>) $2);
4884           }
4885         ;
4886
4887 opt_type_parameter_constraints_clauses
4888         : /* empty */
4889         | type_parameter_constraints_clauses 
4890           {
4891                 $$ = $1;
4892           }
4893         ;
4894
4895 type_parameter_constraints_clauses
4896         : type_parameter_constraints_clause
4897           {
4898                 var constraints = new List<Constraints> (1);
4899                 constraints.Add ((Constraints) $1);
4900                 $$ = constraints;
4901           }
4902         | type_parameter_constraints_clauses type_parameter_constraints_clause
4903           {
4904                 var constraints = (List<Constraints>) $1;
4905                 Constraints new_constraint = (Constraints)$2;
4906
4907                 foreach (Constraints c in constraints) {
4908                         if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) {
4909                                 report.Error (409, new_constraint.Location,
4910                                         "A constraint clause has already been specified for type parameter `{0}'",
4911                                         new_constraint.TypeParameter.Value);
4912                         }
4913                 }
4914
4915                 constraints.Add (new_constraint);
4916                 $$ = constraints;
4917           }
4918         ; 
4919
4920 type_parameter_constraints_clause
4921         : WHERE IDENTIFIER COLON type_parameter_constraints
4922           {
4923                 var lt = (LocatedToken) $2;
4924                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List<FullNamedExpression>) $4, GetLocation ($1));
4925                 lbag.AddLocation ($$, GetLocation ($3));
4926           }
4927         | WHERE IDENTIFIER error
4928           {
4929                 Error_SyntaxError (yyToken);
4930           
4931                 var lt = (LocatedToken) $2;
4932                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), null, GetLocation ($1));
4933           }
4934         ; 
4935
4936 type_parameter_constraints
4937         : type_parameter_constraint
4938           {
4939                 var constraints = new List<FullNamedExpression> (1);
4940                 constraints.Add ((FullNamedExpression) $1);
4941                 $$ = constraints;
4942           }
4943         | type_parameter_constraints COMMA type_parameter_constraint
4944           {
4945                 var constraints = (List<FullNamedExpression>) $1;
4946                 var prev = constraints [constraints.Count - 1] as SpecialContraintExpr;
4947                 if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) {                   
4948                         report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified");
4949                 }
4950                 
4951                 prev = $3 as SpecialContraintExpr;
4952                 if (prev != null) {
4953                         if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) {
4954                                 report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified");                 
4955                         } else {
4956                                 prev = constraints [0] as SpecialContraintExpr;
4957                                 if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) {                        
4958                                         report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint");
4959                                 }
4960                         }
4961                 }
4962
4963                 constraints.Add ((FullNamedExpression) $3);
4964                 $$ = constraints;
4965           }
4966         ;
4967
4968 type_parameter_constraint
4969         : type
4970           {
4971                 if ($1 is ComposedCast)
4972                         report.Error (706, GetLocation ($1), "Invalid constraint type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
4973           
4974                 $$ = $1;
4975           }
4976         | NEW OPEN_PARENS CLOSE_PARENS
4977           {
4978                 $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1));
4979                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
4980           }
4981         | CLASS
4982           {
4983                 $$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1));
4984           }
4985         | STRUCT
4986           {
4987                 $$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1));
4988           }
4989         ;
4990
4991 opt_type_parameter_variance
4992         : /* empty */
4993           {
4994                 $$ = null;
4995           }
4996         | type_parameter_variance
4997           {
4998                 if (lang_version <= LanguageVersion.V_3)
4999                         FeatureIsNotAvailable (lexer.Location, "generic type variance");
5000                 
5001                 $$ = $1;
5002           }
5003         ;
5004
5005 type_parameter_variance
5006         : OUT
5007           {
5008                 $$ = new VarianceDecl (Variance.Covariant, GetLocation ($1));
5009           }
5010         | IN
5011           {
5012                 $$ = new VarianceDecl (Variance.Contravariant, GetLocation ($1));
5013           }
5014         ;
5015
5016 //
5017 // Statements (8.2)
5018 //
5019
5020 //
5021 // A block is "contained" on the following places:
5022 //      method_body
5023 //      property_declaration as part of the accessor body (get/set)
5024 //      operator_declaration
5025 //      constructor_declaration
5026 //      destructor_declaration
5027 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
5028 //      
5029 block
5030         : OPEN_BRACE  
5031           {
5032                 ++lexer.parsing_block;
5033                 start_block (GetLocation ($1));
5034           } 
5035           opt_statement_list block_end
5036           {
5037                 $$ = $4;
5038           }
5039         ;
5040
5041 block_end 
5042         : CLOSE_BRACE 
5043           {
5044                 --lexer.parsing_block;
5045                 $$ = end_block (GetLocation ($1));
5046           }
5047         | COMPLETE_COMPLETION
5048           {
5049                 --lexer.parsing_block;
5050                 $$ = end_block (lexer.Location);
5051           }
5052         ;
5053
5054
5055 block_prepared
5056         : OPEN_BRACE
5057           {
5058                 ++lexer.parsing_block;
5059                 current_block.StartLocation = GetLocation ($1);
5060           }
5061           opt_statement_list CLOSE_BRACE 
5062           {
5063                 --lexer.parsing_block;
5064                 $$ = end_block (GetLocation ($4));
5065           }
5066         ;
5067
5068 opt_statement_list
5069         : /* empty */
5070         | statement_list 
5071         ;
5072
5073 statement_list
5074         : statement
5075         | statement_list statement
5076         ;
5077
5078 statement
5079         : block_variable_declaration
5080           {
5081                 current_block.AddStatement ((Statement) $1);
5082           }
5083         | valid_declaration_statement
5084           {
5085                 current_block.AddStatement ((Statement) $1);
5086           }
5087         | labeled_statement
5088         | error
5089           {
5090                 Error_SyntaxError (yyToken);
5091                 $$ = null;
5092           }
5093         ;
5094
5095 //
5096 // The interactive_statement and its derivatives are only 
5097 // used to provide a special version of `expression_statement'
5098 // that has a side effect of assigning the expression to
5099 // $retval
5100 //
5101 interactive_statement_list
5102         : interactive_statement
5103         | interactive_statement_list interactive_statement
5104         ;
5105
5106 interactive_statement
5107         : block_variable_declaration
5108           {
5109                 current_block.AddStatement ((Statement) $1);
5110           }
5111         | interactive_valid_declaration_statement
5112           {
5113                 current_block.AddStatement ((Statement) $1);
5114           }
5115         | labeled_statement
5116         ;
5117
5118 valid_declaration_statement
5119         : block
5120         | empty_statement
5121         | expression_statement
5122         | selection_statement
5123         | iteration_statement
5124         | jump_statement                  
5125         | try_statement
5126         | checked_statement
5127         | unchecked_statement
5128         | lock_statement
5129         | using_statement
5130         | unsafe_statement
5131         | fixed_statement
5132         ;
5133
5134 interactive_valid_declaration_statement
5135         : block
5136         | empty_statement
5137         | interactive_expression_statement
5138         | selection_statement
5139         | iteration_statement
5140         | jump_statement                  
5141         | try_statement
5142         | checked_statement
5143         | unchecked_statement
5144         | lock_statement
5145         | using_statement
5146         | unsafe_statement
5147         | fixed_statement
5148         ;
5149
5150 embedded_statement
5151         : valid_declaration_statement
5152         | block_variable_declaration
5153           {
5154                   report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
5155                   $$ = null;
5156           }
5157         | labeled_statement
5158           {
5159                   report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
5160                   $$ = null;
5161           }
5162         | error
5163           {
5164                 Error_SyntaxError (yyToken);
5165                 $$ = new EmptyStatement (GetLocation ($1));
5166           }
5167         ;
5168
5169 empty_statement
5170         : SEMICOLON
5171           {
5172                 // Uses lexer.Location because semicolon location is not kept in quick mode
5173                 $$ = new EmptyStatement (lexer.Location);
5174           }
5175         ;
5176
5177 labeled_statement
5178         : identifier_inside_body COLON 
5179           {
5180                 var lt = (LocatedToken) $1;
5181                 LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location);
5182                 lbag.AddLocation (labeled, GetLocation ($2));
5183                 current_block.AddLabel (labeled);
5184                 current_block.AddStatement (labeled);
5185           }
5186           statement
5187         ;
5188
5189 variable_type
5190         : variable_type_simple
5191         | variable_type_simple rank_specifiers
5192           {
5193                 if ($1 is VarExpr)
5194                         $1 = new SimpleName ("var", ((VarExpr) $1).Location);
5195           
5196                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
5197           }
5198         ;
5199
5200 /* 
5201  * The following is from Rhys' grammar:
5202  * > Types in local variable declarations must be recognized as 
5203  * > expressions to prevent reduce/reduce errors in the grammar.
5204  * > The expressions are converted into types during semantic analysis.
5205  */
5206 variable_type_simple
5207         : primary_expression_or_type opt_nullable
5208           { 
5209                 // Ok, the above "primary_expression" is there to get rid of
5210                 // both reduce/reduce and shift/reduces in the grammar, it should
5211                 // really just be "type_name".  If you use type_name, a reduce/reduce
5212                 // creeps up.  If you use namespace_or_type_name (which is all we need
5213                 // really) two shift/reduces appear.
5214                 // 
5215
5216                 // So the super-trick is that primary_expression
5217                 // can only be either a SimpleName or a MemberAccess. 
5218                 // The MemberAccess case arises when you have a fully qualified type-name like :
5219                 // Foo.Bar.Blah i;
5220                 // SimpleName is when you have
5221                 // Blah i;
5222                 
5223                 Expression expr = (Expression) $1;
5224                 if ($2 == null) {
5225                         SimpleName sn = expr as SimpleName;
5226                         if (sn != null && sn.Name == "var")
5227                                 $$ = new VarExpr (sn.Location);
5228                         else
5229                                 $$ = $1;
5230                 } else if (expr is ATypeNameExpression) {
5231                         $$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2);
5232                 } else {
5233                         Error_ExpectingTypeName (expr);
5234                         $$ = null;
5235                 }
5236           }
5237         | primary_expression_or_type pointer_stars
5238           {
5239                 ATypeNameExpression expr = $1 as ATypeNameExpression;
5240
5241                 if (expr != null) {
5242                         $$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2);
5243                 } else {
5244                         Error_ExpectingTypeName ((Expression)$1);
5245                         $$ = expr;
5246                 }
5247           }
5248         | builtin_types opt_nullable
5249           {
5250                 if ($2 == null)
5251                         $$ = $1;
5252                 else
5253                         $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
5254           }
5255         | builtin_types pointer_stars
5256           {
5257                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
5258           }
5259         | VOID pointer_stars
5260           {
5261                 $$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
5262           }       
5263         | VOID
5264           {
5265                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
5266                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
5267           }
5268         ;
5269         
5270 pointer_stars
5271         : pointer_star
5272         | pointer_star pointer_stars
5273           {
5274                 ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
5275                 $$ = $1;
5276           }       
5277         ;
5278
5279 pointer_star
5280         : STAR
5281           {
5282                 $$ = ComposedTypeSpecifier.CreatePointer (GetLocation ($1));
5283           }
5284         ;
5285
5286 identifier_inside_body
5287         : IDENTIFIER
5288         | AWAIT
5289           {
5290                 $$ = Error_AwaitAsIdentifier ($1);
5291           }
5292         ;
5293
5294 block_variable_declaration
5295         : variable_type identifier_inside_body
5296           {
5297                 var lt = (LocatedToken) $2;
5298                 var li = new LocalVariable (current_block, lt.Value, lt.Location);
5299                 current_block.AddLocalName (li);
5300                 current_variable = new BlockVariable ((FullNamedExpression) $1, li);
5301           }
5302           opt_local_variable_initializer opt_variable_declarators SEMICOLON
5303           {
5304                 $$ = current_variable;
5305                 current_variable = null;
5306                 if ($4 != null)
5307                         lbag.AddLocation ($$, PopLocation (), GetLocation ($6));
5308                 else
5309                         lbag.AddLocation ($$, GetLocation ($6));
5310           }
5311         | CONST variable_type identifier_inside_body
5312           {
5313                 var lt = (LocatedToken) $3;
5314                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
5315                 current_block.AddLocalName (li);
5316                 current_variable = new BlockConstant ((FullNamedExpression) $2, li);
5317           }
5318           const_variable_initializer opt_const_declarators SEMICOLON
5319           {
5320                 $$ = current_variable;
5321                 current_variable = null;
5322                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($7));
5323           }
5324         ;
5325
5326 opt_local_variable_initializer
5327         : /* empty */
5328         | ASSIGN block_variable_initializer
5329           {
5330                 current_variable.Initializer = (Expression) $2;
5331                 PushLocation (GetLocation ($1));
5332                 $$ = current_variable;
5333           }
5334         | error
5335           {
5336                 if (yyToken == Token.OPEN_BRACKET_EXPR) {
5337                         report.Error (650, lexer.Location,
5338                                 "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type");
5339                 } else {
5340                         Error_SyntaxError (yyToken);
5341                 }
5342           }
5343         ;
5344
5345 opt_variable_declarators
5346         : /* empty */
5347         | variable_declarators
5348         ;
5349         
5350 opt_using_or_fixed_variable_declarators
5351         : /* empty */
5352         | variable_declarators
5353           {
5354                 foreach (var d in current_variable.Declarators) {
5355                         if (d.Initializer == null)
5356                                 Error_MissingInitializer (d.Variable.Location);
5357                 }
5358           }
5359         ;       
5360         
5361 variable_declarators
5362         : variable_declarator
5363         | variable_declarators variable_declarator
5364         ;
5365         
5366 variable_declarator
5367         : COMMA identifier_inside_body
5368           {
5369                 var lt = (LocatedToken) $2;       
5370                 var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
5371                 var d = new BlockVariableDeclarator (li, null);
5372                 current_variable.AddDeclarator (d);
5373                 current_block.AddLocalName (li);
5374                 lbag.AddLocation (d, GetLocation ($1));
5375           }
5376         | COMMA identifier_inside_body ASSIGN block_variable_initializer
5377           {
5378                 var lt = (LocatedToken) $2;       
5379                 var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
5380                 var d = new BlockVariableDeclarator (li, (Expression) $4);
5381                 current_variable.AddDeclarator (d);
5382                 current_block.AddLocalName (li);
5383                 lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
5384           }
5385         ;
5386         
5387 const_variable_initializer
5388         : /* empty */
5389           {
5390                 report.Error (145, lexer.Location, "A const field requires a value to be provided");
5391           }
5392         | ASSIGN constant_initializer_expr 
5393           {
5394                 current_variable.Initializer = (Expression) $2;
5395           }
5396         ;
5397         
5398 opt_const_declarators
5399         : /* empty */
5400         | const_declarators
5401         ;
5402         
5403 const_declarators
5404         : const_declarator
5405         | const_declarators const_declarator
5406         ;
5407         
5408 const_declarator
5409         : COMMA identifier_inside_body ASSIGN constant_initializer_expr
5410           {
5411                 var lt = (LocatedToken) $2;       
5412                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
5413                 var d = new BlockVariableDeclarator (li, (Expression) $4);
5414                 current_variable.AddDeclarator (d);
5415                 current_block.AddLocalName (li);
5416                 lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
5417           }
5418         ;
5419         
5420 block_variable_initializer
5421         : variable_initializer
5422         | STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET
5423           {
5424                 $$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1));
5425                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
5426           }
5427         | STACKALLOC simple_type
5428           {
5429                 report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type");
5430                 $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1));          
5431           }
5432         ;
5433
5434 expression_statement
5435         : statement_expression SEMICOLON
5436           {
5437                 $$ = $1;
5438                 lbag.AddStatement ($$, GetLocation ($2));
5439           }
5440         | statement_expression COMPLETE_COMPLETION { $$ = $1; }
5441         | statement_expression CLOSE_BRACE
5442           {
5443                 $$ = $1;
5444                 report.Error (1002, GetLocation ($2), "; expected");
5445                 lexer.putback ('}');
5446           }
5447         ;
5448
5449 interactive_expression_statement
5450         : interactive_statement_expression SEMICOLON { $$ = $1; }
5451         | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; }
5452         ;
5453
5454         //
5455         // We have to do the wrapping here and not in the case above,
5456         // because statement_expression is used for example in for_statement
5457         //
5458 statement_expression
5459         : expression
5460           {
5461                 ExpressionStatement s = $1 as ExpressionStatement;
5462                 if (s == null) {
5463                         var expr = $1 as Expression;
5464                         $$ = new StatementErrorExpression (expr);
5465                 } else {
5466                         $$ = new StatementExpression (s);
5467                 }
5468           }
5469         ;
5470
5471 interactive_statement_expression
5472         : expression
5473           {
5474                 Expression expr = (Expression) $1;
5475                 $$ = new StatementExpression (new OptionalAssign (expr, lexer.Location));
5476           }
5477         | error
5478           {
5479                 Error_SyntaxError (yyToken);
5480                 $$ = new EmptyStatement (GetLocation ($1));
5481           }
5482         ;
5483         
5484 selection_statement
5485         : if_statement
5486         | switch_statement
5487         ; 
5488
5489 if_statement
5490         : IF open_parens_any boolean_expression CLOSE_PARENS 
5491           embedded_statement
5492           { 
5493                 if ($5 is EmptyStatement)
5494                         Warning_EmptyStatement (GetLocation ($5));
5495                 
5496                 $$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
5497                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5498           }
5499         | IF open_parens_any boolean_expression CLOSE_PARENS
5500           embedded_statement ELSE embedded_statement
5501           {
5502                 $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1));
5503                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
5504                 
5505                 if ($5 is EmptyStatement)
5506                         Warning_EmptyStatement (GetLocation ($5));
5507                 if ($7 is EmptyStatement)
5508                         Warning_EmptyStatement (GetLocation ($7));
5509           }
5510         | IF open_parens_any boolean_expression error
5511           {
5512                 Error_SyntaxError (yyToken);
5513                 
5514                 $$ = new If ((BooleanExpression) $3, null, GetLocation ($1));
5515                 lbag.AddStatement ($$, GetLocation ($2));
5516           }
5517         ;
5518
5519 switch_statement
5520         : SWITCH open_parens_any expression CLOSE_PARENS OPEN_BRACE
5521           {
5522                 start_block (GetLocation ($5));
5523           }
5524           opt_switch_sections CLOSE_BRACE
5525           {
5526                 $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, GetLocation ($1));    
5527                 end_block (GetLocation ($8));
5528                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5529           }
5530         | SWITCH open_parens_any expression error
5531           {
5532                 Error_SyntaxError (yyToken);
5533           
5534                 $$ = new Switch ((Expression) $3, null, GetLocation ($1));      
5535                 lbag.AddStatement ($$, GetLocation ($2));
5536           }
5537         ;
5538
5539 opt_switch_sections
5540         : /* empty */           
5541       {
5542                 report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); 
5543           }
5544         | switch_sections
5545         ;
5546
5547 switch_sections
5548         : switch_section 
5549         | switch_sections switch_section
5550         | error
5551           {
5552                 Error_SyntaxError (yyToken);
5553           } 
5554         ;
5555
5556 switch_section
5557         : switch_labels statement_list 
5558         ;
5559
5560 switch_labels
5561         : switch_label 
5562           {
5563                 var label = (SwitchLabel) $1;
5564                 label.SectionStart = true;
5565                 current_block.AddStatement (label);
5566           }
5567         | switch_labels switch_label 
5568           {
5569                 current_block.AddStatement ((Statement) $2);
5570           }
5571         ;
5572
5573 switch_label
5574         : CASE constant_expression COLON
5575          {
5576                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
5577                 lbag.AddLocation ($$, GetLocation ($3));
5578          }
5579         | CASE constant_expression error
5580           {
5581                 Error_SyntaxError (yyToken);
5582                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
5583           }
5584         | DEFAULT_COLON
5585           {
5586                 $$ = new SwitchLabel (null, GetLocation ($1));
5587           }
5588         ;
5589
5590 iteration_statement
5591         : while_statement
5592         | do_statement
5593         | for_statement
5594         | foreach_statement
5595         ;
5596
5597 while_statement
5598         : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement
5599           {
5600                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5601                         Warning_EmptyStatement (GetLocation ($5));
5602           
5603                 $$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
5604                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5605           }
5606         | WHILE open_parens_any boolean_expression error
5607           {
5608                 Error_SyntaxError (yyToken);
5609                 
5610                 $$ = new While ((BooleanExpression) $3, null, GetLocation ($1));
5611                 lbag.AddStatement ($$, GetLocation ($2));
5612           }
5613         ;
5614
5615 do_statement
5616         : DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
5617           {
5618                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
5619                 lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
5620           }
5621         | DO embedded_statement error
5622           {
5623                 Error_SyntaxError (yyToken);
5624                 $$ = new Do ((Statement) $2, null, GetLocation ($1), Location.Null);
5625           }
5626         | DO embedded_statement WHILE open_parens_any boolean_expression error
5627           {
5628                 Error_SyntaxError (yyToken);
5629           
5630                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
5631                 lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4));
5632           }
5633         ;
5634
5635 for_statement
5636         : FOR open_parens_any
5637           {
5638                 start_block (GetLocation ($2));
5639                 current_block.IsCompilerGenerated = true;
5640                 For f = new For (GetLocation ($1));
5641                 current_block.AddStatement (f);
5642                 $$ = f;
5643           }
5644           for_statement_cont
5645           {
5646                 $$ = $4;
5647           }
5648         ;
5649         
5650 // Has to use be extra rule to recover started block
5651 for_statement_cont
5652         : opt_for_initializer SEMICOLON
5653           {
5654                 ((For) $0).Initializer = (Statement) $1;
5655
5656                 // Pass the "For" object to the iterator_part4
5657                 oob_stack.Push ($0);
5658           }
5659           for_condition_and_iterator_part
5660           embedded_statement
5661           {
5662                 var locations = (Tuple<Location,Location>) $4;
5663                 oob_stack.Pop ();
5664                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5665                         Warning_EmptyStatement (GetLocation ($5));
5666           
5667                 For f = ((For) $0);
5668                 f.Statement = (Statement) $5;
5669                 lbag.AddStatement (f, current_block.StartLocation, GetLocation ($2), GetLocation (locations.Item1), GetLocation (locations.Item2));
5670
5671                 $$ = end_block (GetLocation ($2));
5672           }
5673         | error
5674           {
5675                 Error_SyntaxError (yyToken);
5676                 $$ = end_block (current_block.StartLocation);
5677           }
5678         ;
5679
5680 for_condition_and_iterator_part
5681         : opt_for_condition SEMICOLON
5682           {
5683                 For f = (For) oob_stack.Peek ();
5684                 f.Condition = (BooleanExpression) $1;
5685           }
5686           for_iterator_part {
5687                 $$ = new Tuple<Location,Location> (GetLocation ($2), (Location) $4);
5688           }
5689
5690         // Handle errors in the case of opt_for_condition being followed by
5691         // a close parenthesis
5692         | opt_for_condition close_parens_close_brace {
5693                 report.Error (1525, GetLocation ($2), "Unexpected symbol `}'");
5694                 For f = (For) oob_stack.Peek ();
5695                 f.Condition = (BooleanExpression) $1;
5696                 $$ = new Tuple<Location,Location> (GetLocation ($2), GetLocation ($2));
5697           }
5698         ;
5699
5700 for_iterator_part
5701         : opt_for_iterator CLOSE_PARENS {
5702                 For f = (For) oob_stack.Peek ();
5703                 f.Iterator = (Statement) $1;
5704                 $$ = GetLocation ($2);
5705           }
5706         | opt_for_iterator CLOSE_BRACE {
5707                 report.Error (1525, GetLocation ($2), "Unexpected symbol expected ')'");
5708                 For f = (For) oob_stack.Peek ();
5709                 f.Iterator = (Statement) $1;
5710                 $$ = GetLocation ($2);
5711           }
5712         ; 
5713
5714 close_parens_close_brace 
5715         : CLOSE_PARENS
5716         | CLOSE_BRACE { lexer.putback ('}'); }
5717         ;
5718
5719 opt_for_initializer
5720         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
5721         | for_initializer       
5722         ;
5723
5724 for_initializer
5725         : variable_type identifier_inside_body
5726           {
5727                 var lt = (LocatedToken) $2;
5728                 var li = new LocalVariable (current_block, lt.Value, lt.Location);
5729                 current_block.AddLocalName (li);
5730                 current_variable = new BlockVariable ((FullNamedExpression) $1, li);
5731           }
5732           opt_local_variable_initializer opt_variable_declarators
5733           {
5734                 $$ = current_variable;
5735                 if ($4 != null)
5736                         lbag.AddLocation (current_variable, PopLocation ());
5737
5738                 current_variable = null;
5739           }
5740         | statement_expression_list
5741         ;
5742
5743 opt_for_condition
5744         : /* empty */           { $$ = null; }
5745         | boolean_expression
5746         ;
5747
5748 opt_for_iterator
5749         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
5750         | for_iterator
5751         ;
5752
5753 for_iterator
5754         : statement_expression_list
5755         ;
5756
5757 statement_expression_list
5758         : statement_expression
5759         | statement_expression_list COMMA statement_expression
5760           {
5761                 var sl = $1 as StatementList;
5762                 if (sl == null) {
5763                         sl = new StatementList ((Statement) $1, (Statement) $3);
5764                         lbag.AddStatement (sl, GetLocation ($2));
5765                 } else {
5766                         sl.Add ((Statement) $3);
5767                         lbag.AppendTo (sl, GetLocation ($2));
5768                 }
5769                         
5770                 $$ = sl;
5771           }
5772         ;
5773
5774 foreach_statement
5775         : FOREACH open_parens_any type error
5776           {
5777                 report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement");
5778
5779                 start_block (GetLocation ($2));
5780                 current_block.IsCompilerGenerated = true;
5781                 
5782                 Foreach f = new Foreach ((Expression) $3, null, null, null, null, GetLocation ($1));
5783                 current_block.AddStatement (f);
5784                 
5785                 lbag.AddStatement (f, GetLocation ($2));
5786                 $$ = end_block (GetLocation ($4));
5787           }
5788         | FOREACH open_parens_any type identifier_inside_body error
5789           {
5790                 Error_SyntaxError (yyToken);
5791         
5792                 start_block (GetLocation ($2));
5793                 current_block.IsCompilerGenerated = true;
5794                 
5795                 var lt = (LocatedToken) $4;
5796                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
5797                 current_block.AddLocalName (li);
5798                 
5799                 Foreach f = new Foreach ((Expression) $3, li, null, null, null, GetLocation ($1));
5800                 current_block.AddStatement (f);
5801                 
5802                 lbag.AddStatement (f, GetLocation ($2));
5803                 $$ = end_block (GetLocation ($5));
5804           }
5805         | FOREACH open_parens_any type identifier_inside_body IN expression CLOSE_PARENS 
5806           {
5807                 start_block (GetLocation ($2));
5808                 current_block.IsCompilerGenerated = true;
5809                 
5810                 var lt = (LocatedToken) $4;
5811                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
5812                 current_block.AddLocalName (li);
5813                 $$ = li;
5814           } 
5815           embedded_statement
5816           {
5817                 if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5818                         Warning_EmptyStatement (GetLocation ($9));
5819                 
5820                 Foreach f = new Foreach ((Expression) $3, (LocalVariable) $8, (Expression) $6, (Statement) $9, current_block, GetLocation ($1));
5821                 lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
5822                 end_block (GetLocation ($7));
5823                 
5824                 $$ = f;
5825           }
5826         ;
5827
5828 jump_statement
5829         : break_statement
5830         | continue_statement
5831         | goto_statement
5832         | return_statement
5833         | throw_statement
5834         | yield_statement
5835         ;
5836
5837 break_statement
5838         : BREAK SEMICOLON
5839           {
5840                 $$ = new Break (GetLocation ($1));
5841                 lbag.AddStatement ($$, GetLocation ($2));
5842           }
5843         ;
5844
5845 continue_statement
5846         : CONTINUE SEMICOLON
5847           {
5848                 $$ = new Continue (GetLocation ($1));
5849                 lbag.AddStatement ($$, GetLocation ($2));
5850           }
5851         | CONTINUE error
5852           {
5853                 Error_SyntaxError (yyToken);
5854                 $$ = new Continue (GetLocation ($1));
5855           }
5856         ;
5857
5858 goto_statement
5859         : GOTO identifier_inside_body SEMICOLON 
5860           {
5861                 var lt = (LocatedToken) $2;
5862                 $$ = new Goto (lt.Value, GetLocation ($1));
5863                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5864           }
5865         | GOTO CASE constant_expression SEMICOLON
5866           {
5867                 $$ = new GotoCase ((Expression) $3, GetLocation ($1));
5868                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5869           }
5870         | GOTO DEFAULT SEMICOLON 
5871           {
5872                 $$ = new GotoDefault (GetLocation ($1));
5873                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5874           }
5875         ; 
5876
5877 return_statement
5878         : RETURN opt_expression SEMICOLON
5879           {
5880                 $$ = new Return ((Expression) $2, GetLocation ($1));
5881                 lbag.AddStatement ($$, GetLocation ($3));
5882           }
5883         | RETURN expression error
5884           {
5885                 Error_SyntaxError (yyToken);
5886                 $$ = new Return ((Expression) $2, GetLocation ($1));
5887           }
5888         | RETURN error
5889           {
5890                 Error_SyntaxError (yyToken);
5891                 $$ = new Return (null, GetLocation ($1));
5892           }
5893         ;
5894
5895 throw_statement
5896         : THROW opt_expression SEMICOLON
5897           {
5898                 $$ = new Throw ((Expression) $2, GetLocation ($1));
5899                 lbag.AddStatement ($$, GetLocation ($3));
5900           }
5901         | THROW expression error
5902           {
5903                 Error_SyntaxError (yyToken);
5904                 $$ = new Throw ((Expression) $2, GetLocation ($1));
5905           }
5906         | THROW error
5907           {
5908                 Error_SyntaxError (yyToken);
5909                 $$ = new Throw (null, GetLocation ($1));
5910           }
5911         ;
5912
5913 yield_statement 
5914         : identifier_inside_body RETURN opt_expression SEMICOLON
5915           {
5916                 var lt = (LocatedToken) $1;
5917                 string s = lt.Value;
5918                 if (s != "yield"){
5919                         report.Error (1003, lt.Location, "; expected");
5920                 } else if ($3 == null) {
5921                         report.Error (1627, GetLocation ($4), "Expression expected after yield return");
5922                 } else if (lang_version == LanguageVersion.ISO_1){
5923                         FeatureIsNotAvailable (lt.Location, "iterators");
5924                 }
5925                 
5926                 current_block.Explicit.RegisterIteratorYield ();
5927                 $$ = new Yield ((Expression) $3, lt.Location);
5928                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5929           }
5930         | identifier_inside_body RETURN expression error
5931           {
5932                 Error_SyntaxError (yyToken);
5933
5934                 var lt = (LocatedToken) $1;
5935                 string s = lt.Value;
5936                 if (s != "yield"){
5937                         report.Error (1003, lt.Location, "; expected");
5938                 } else if ($3 == null) {
5939                         report.Error (1627, GetLocation ($4), "Expression expected after yield return");
5940                 } else if (lang_version == LanguageVersion.ISO_1){
5941                         FeatureIsNotAvailable (lt.Location, "iterators");
5942                 }
5943                 
5944                 current_block.Explicit.RegisterIteratorYield ();
5945                 $$ = new Yield ((Expression) $3, lt.Location);
5946                 lbag.AddStatement ($$, GetLocation ($2));
5947           }
5948         | identifier_inside_body BREAK SEMICOLON
5949           {
5950                 var lt = (LocatedToken) $1;
5951                 string s = lt.Value;
5952                 if (s != "yield"){
5953                         report.Error (1003, lt.Location, "; expected");
5954                 } else if (lang_version == LanguageVersion.ISO_1){
5955                         FeatureIsNotAvailable (lt.Location, "iterators");
5956                 }
5957                 
5958                 current_block.ParametersBlock.TopBlock.IsIterator = true;
5959                 $$ = new YieldBreak (lt.Location);
5960                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5961           }
5962         ;
5963
5964 opt_expression
5965         : /* empty */
5966         | expression
5967         ;
5968
5969 try_statement
5970         : TRY block catch_clauses
5971           {
5972                 $$ = new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), false);
5973           }
5974         | TRY block FINALLY block
5975           {
5976                 $$ = new TryFinally ((Statement) $2, (ExplicitBlock) $4, GetLocation ($1));
5977                 lbag.AddStatement ($$, GetLocation ($3));
5978           }
5979         | TRY block catch_clauses FINALLY block
5980           {
5981                 $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, Location.Null, true), (ExplicitBlock) $5, GetLocation ($1));
5982                 lbag.AddStatement ($$, GetLocation ($4));
5983           }
5984         | TRY block error
5985           {
5986                 Error_SyntaxError (1524, yyToken);
5987                 $$ = new TryCatch ((Block) $2, null, GetLocation ($1), false);
5988           }
5989         ;
5990
5991 catch_clauses
5992         : catch_clause 
5993           {
5994                 var l = new List<Catch> (2);
5995
5996                 l.Add ((Catch) $1);
5997                 $$ = l;
5998           }
5999         | catch_clauses catch_clause
6000           {
6001                 var l = (List<Catch>) $1;
6002                 
6003                 Catch c = (Catch) $2;
6004                 var prev_catch = l [l.Count - 1];
6005                 if (prev_catch.IsGeneral && prev_catch.Filter == null) {
6006                         report.Error (1017, c.loc, "Try statement already has an empty catch block");
6007                 }
6008                 
6009                 l.Add (c);
6010                 $$ = l;
6011           }
6012         ;
6013
6014 opt_identifier
6015         : /* empty */
6016         | identifier_inside_body
6017         ;
6018
6019 catch_clause 
6020         : CATCH opt_catch_filter block
6021           {
6022                 var c = new Catch ((ExplicitBlock) $3, GetLocation ($1));
6023                 c.Filter = (CatchFilterExpression) $2;
6024                 $$ = c;
6025           }
6026         | CATCH open_parens_any type opt_identifier CLOSE_PARENS
6027           {
6028                 start_block (GetLocation ($2));
6029                 var c = new Catch ((ExplicitBlock) current_block, GetLocation ($1));
6030                 c.TypeExpression = (FullNamedExpression) $3;
6031
6032                 if ($4 != null) {
6033                         var lt = (LocatedToken) $4;
6034                         c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
6035                         current_block.AddLocalName (c.Variable);
6036                 }
6037                 
6038                 lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
6039                 $$ = c;
6040           }
6041           opt_catch_filter block_prepared
6042           {
6043                 ((Catch) $6).Filter = (CatchFilterExpression) $7;
6044                 $$ = $6;
6045           }
6046         | CATCH open_parens_any error
6047           {
6048                 if (yyToken == Token.CLOSE_PARENS) {
6049                         report.Error (1015, lexer.Location,
6050                                 "A type that derives from `System.Exception', `object', or `string' expected");
6051                 } else {
6052                         Error_SyntaxError (yyToken);
6053                 }
6054                 
6055                 $$ = new Catch (null, GetLocation ($1));
6056           }
6057         | CATCH open_parens_any type opt_identifier CLOSE_PARENS error
6058           {
6059                 Error_SyntaxError (yyToken);
6060
6061                 // Required otherwise missing block could not be detected because
6062                 // start_block is run early
6063                 var c = new Catch (null, GetLocation ($1));
6064                 c.TypeExpression = (FullNamedExpression) $3;
6065
6066                 if ($4 != null) {
6067                         var lt = (LocatedToken) $4;
6068                         c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
6069                 }
6070
6071                 lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
6072
6073                 $$ = c;
6074           }
6075         ;
6076
6077 opt_catch_filter
6078         : /* empty */
6079         | IF open_parens_any expression CLOSE_PARENS
6080           {
6081                 if (lang_version <= LanguageVersion.V_5)
6082                         FeatureIsNotAvailable (GetLocation ($1), "exception filter");
6083
6084                 $$ = new CatchFilterExpression ((Expression) $3, GetLocation ($1));
6085                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
6086           }
6087         ;
6088
6089 checked_statement
6090         : CHECKED block
6091           {
6092                 $$ = new Checked ((Block) $2, GetLocation ($1));
6093           }
6094         ;
6095
6096 unchecked_statement
6097         : UNCHECKED block
6098           {
6099                 $$ = new Unchecked ((Block) $2, GetLocation ($1));
6100           }
6101         ;
6102
6103 unsafe_statement
6104         : UNSAFE
6105           {
6106                 if (!settings.Unsafe)
6107                         Error_UnsafeCodeNotAllowed (GetLocation ($1));
6108           } block {
6109                 $$ = new Unsafe ((Block) $3, GetLocation ($1));
6110           }
6111         ;
6112
6113 lock_statement
6114         : LOCK open_parens_any expression CLOSE_PARENS embedded_statement
6115           {
6116                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
6117                         Warning_EmptyStatement (GetLocation ($5));
6118           
6119                 $$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1));
6120                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
6121           }
6122         | LOCK open_parens_any expression error
6123           {
6124                 Error_SyntaxError (yyToken);
6125
6126                 $$ = new Lock ((Expression) $3, null, GetLocation ($1));
6127                 lbag.AddStatement ($$, GetLocation ($2));
6128           }
6129         ;
6130
6131 fixed_statement
6132         : FIXED open_parens_any variable_type identifier_inside_body
6133           {
6134             start_block (GetLocation ($2));
6135             
6136                 current_block.IsCompilerGenerated = true;
6137                 var lt = (LocatedToken) $4;
6138                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location);
6139                 current_block.AddLocalName (li);
6140                 current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) $3, li);
6141           }
6142           using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators CLOSE_PARENS
6143           {
6144                 $$ = current_variable;
6145                 current_variable = null;
6146           }
6147           embedded_statement
6148           {
6149                 if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
6150                         Warning_EmptyStatement (GetLocation ($10));
6151           
6152                 Fixed f = new Fixed ((Fixed.VariableDeclaration) $9, (Statement) $10, GetLocation ($1));
6153                 current_block.AddStatement (f);
6154                 lbag.AddStatement (f, GetLocation ($2), GetLocation ($8));
6155                 $$ = end_block (GetLocation ($8));
6156           }
6157         ;
6158
6159 using_statement
6160         : USING open_parens_any variable_type identifier_inside_body
6161           {
6162             start_block (GetLocation ($2));
6163             
6164                 current_block.IsCompilerGenerated = true;
6165                 var lt = (LocatedToken) $4;
6166                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location);
6167                 current_block.AddLocalName (li);
6168                 current_variable = new Using.VariableDeclaration ((FullNamedExpression) $3, li);
6169           }
6170           using_initialization CLOSE_PARENS
6171           {
6172                 $$ = current_variable;    
6173                 current_variable = null;
6174           }
6175           embedded_statement
6176           {
6177                 if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
6178                         Warning_EmptyStatement (GetLocation ($9));
6179           
6180                 Using u = new Using ((Using.VariableDeclaration) $8, (Statement) $9, GetLocation ($1));
6181                 current_block.AddStatement (u);
6182                 $$ = end_block (GetLocation ($7));
6183           }
6184         | USING open_parens_any expression CLOSE_PARENS embedded_statement
6185           {
6186                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
6187                         Warning_EmptyStatement (GetLocation ($5));
6188           
6189                 $$ = new Using ((Expression) $3, (Statement) $5, GetLocation ($1));
6190                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
6191           }
6192         | USING open_parens_any expression error
6193           {
6194                 Error_SyntaxError (yyToken);
6195                 
6196                 $$ = new Using ((Expression) $3, null, GetLocation ($1));
6197                 lbag.AddStatement ($$, GetLocation ($2));
6198           }
6199         ;
6200         
6201 using_initialization
6202         : using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators
6203         | error
6204           {
6205                 // It has to be here for the parent to safely restore artificial block
6206                 Error_SyntaxError (yyToken);
6207           }
6208         ;
6209         
6210 using_or_fixed_variable_initializer
6211         : /* empty */
6212           {
6213                 Error_MissingInitializer (lexer.Location);
6214           }
6215         | ASSIGN variable_initializer
6216           {
6217                 current_variable.Initializer = (Expression) $2;
6218                 $$ = current_variable;
6219           }
6220         ;
6221
6222
6223 // LINQ
6224
6225 query_expression
6226         : first_from_clause query_body 
6227           {
6228                 lexer.query_parsing = false;
6229                         
6230                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
6231                         
6232                 from.Tail.Next = (Linq.AQueryClause)$2;
6233                 $$ = from;
6234                 
6235                 current_block.SetEndLocation (lexer.Location);
6236                 current_block = current_block.Parent;
6237           }
6238         | nested_from_clause query_body
6239           {
6240                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
6241                         
6242                 from.Tail.Next = (Linq.AQueryClause)$2;
6243                 $$ = from;
6244                 
6245                 current_block.SetEndLocation (lexer.Location);
6246                 current_block = current_block.Parent;
6247           }     
6248
6249         // Bubble up COMPLETE_COMPLETION productions
6250         | first_from_clause COMPLETE_COMPLETION {
6251                 lexer.query_parsing = false;
6252                 $$ = $1;
6253
6254                 current_block.SetEndLocation (lexer.Location);
6255                 current_block = current_block.Parent;
6256           }
6257         | nested_from_clause COMPLETE_COMPLETION {
6258                 $$ = $1;
6259                 current_block.SetEndLocation (lexer.Location);
6260                 current_block = current_block.Parent;
6261           }
6262         ;
6263         
6264 first_from_clause
6265         : FROM_FIRST identifier_inside_body IN expression
6266           {
6267                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6268           
6269                 var lt = (LocatedToken) $2;
6270                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
6271                 var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1));
6272                 lbag.AddLocation (clause, GetLocation ($3));
6273                 $$ = new Linq.QueryExpression (clause);
6274           }
6275         | FROM_FIRST type identifier_inside_body IN expression
6276           {
6277                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6278           
6279                 var lt = (LocatedToken) $3;
6280                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
6281                 var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
6282                                 IdentifierType = (FullNamedExpression)$2
6283                 };
6284                 lbag.AddLocation (clause, GetLocation ($4));
6285                 $$ = new Linq.QueryExpression (clause);
6286           }
6287         ;
6288
6289 nested_from_clause
6290         : FROM identifier_inside_body IN expression
6291           {
6292                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6293           
6294                 var lt = (LocatedToken) $2;
6295                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
6296                 var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1));
6297                 lbag.AddLocation (clause, GetLocation ($3));
6298                 $$ = new Linq.QueryExpression (clause);
6299           }
6300         | FROM type identifier_inside_body IN expression
6301           {
6302                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6303           
6304                 var lt = (LocatedToken) $3;
6305                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
6306                 var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
6307                                 IdentifierType = (FullNamedExpression)$2
6308                 };
6309                 lbag.AddLocation (clause, GetLocation ($4));
6310                 $$ = new Linq.QueryExpression (clause);
6311           }
6312         ;
6313         
6314 from_clause
6315         : FROM identifier_inside_body IN
6316           {
6317                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6318           }
6319           expression_or_error
6320           {
6321                 var lt = (LocatedToken) $2;
6322                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6323                 $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$5, GetLocation ($1));
6324                 
6325                 current_block.SetEndLocation (lexer.Location);
6326                 current_block = current_block.Parent;
6327                 
6328                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6329                 lbag.AddLocation ($$, GetLocation ($3));
6330           }       
6331         | FROM type identifier_inside_body IN
6332           {
6333                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6334           }
6335           expression_or_error
6336           {
6337                 var lt = (LocatedToken) $3;
6338                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6339
6340                 $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) {
6341                         IdentifierType = (FullNamedExpression)$2
6342                 };
6343                 
6344                 current_block.SetEndLocation (lexer.Location);
6345                 current_block = current_block.Parent;
6346                 
6347                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6348                 
6349                 lbag.AddLocation ($$, GetLocation ($4));
6350           }
6351         ;       
6352
6353 query_body
6354         : query_body_clauses select_or_group_clause opt_query_continuation 
6355           {
6356                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
6357                 
6358                 if ($3 != null)
6359                         head.Next = (Linq.AQueryClause)$3;
6360                                 
6361                 if ($1 != null) {
6362                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
6363                         clause.Tail.Next = head;
6364                         head = clause;
6365                 }
6366                 
6367                 $$ = head;
6368           }
6369         | select_or_group_clause opt_query_continuation
6370           {
6371                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
6372
6373                 if ($1 != null) {
6374                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
6375                         clause.Tail.Next = head;
6376                         head = clause;
6377                 }
6378                 
6379                 $$ = head;
6380           }
6381         | query_body_clauses COMPLETE_COMPLETION
6382         | query_body_clauses error
6383           {
6384                 report.Error (742, GetLocation ($2), "Unexpected symbol `{0}'. A query body must end with select or group clause", GetSymbolName (yyToken));
6385                 $$ = $1;
6386           }
6387         | error
6388           {
6389                 Error_SyntaxError (yyToken);
6390                 $$ = null;
6391           }
6392         ;
6393         
6394 select_or_group_clause
6395         : SELECT
6396           {
6397                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6398           }
6399           expression_or_error
6400           {
6401                 $$ = new Linq.Select ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
6402
6403                 current_block.SetEndLocation (lexer.Location);
6404                 current_block = current_block.Parent;
6405           }
6406         | GROUP
6407           {
6408                 if (linq_clause_blocks == null)
6409                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
6410                         
6411                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6412                 linq_clause_blocks.Push ((Linq.QueryBlock)current_block);
6413           }
6414           expression_or_error
6415           {
6416                 current_block.SetEndLocation (lexer.Location);
6417                 current_block = current_block.Parent;
6418           
6419                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6420           }
6421           by_expression
6422           {
6423                 var obj = (object[]) $5;
6424
6425                 $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)obj[0], GetLocation ($1));
6426                 lbag.AddLocation ($$, (Location) obj[1]);
6427                 
6428                 current_block.SetEndLocation (lexer.Location);
6429                 current_block = current_block.Parent;
6430           }
6431         ;
6432
6433 by_expression
6434         : BY expression_or_error
6435           {
6436                 $$ = new object[] { $2, GetLocation ($1) };
6437           }
6438         | error
6439           {
6440                 Error_SyntaxError (yyToken);
6441                 $$ = new object[2] { null, Location.Null };
6442           }
6443         ;
6444         
6445 query_body_clauses
6446         : query_body_clause
6447         | query_body_clauses query_body_clause
6448           {
6449                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
6450                 $$ = $1;
6451           }
6452         ;
6453         
6454 query_body_clause
6455         : from_clause
6456         | let_clause 
6457         | where_clause
6458         | join_clause
6459         | orderby_clause
6460         ;
6461         
6462 let_clause
6463         : LET identifier_inside_body ASSIGN 
6464           {
6465                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6466           }
6467           expression_or_error
6468           {
6469                 var lt = (LocatedToken) $2;
6470                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6471                 $$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1));
6472                 lbag.AddLocation ($$, GetLocation ($3));
6473                 
6474                 current_block.SetEndLocation (lexer.Location);
6475                 current_block = current_block.Parent;
6476                 
6477                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6478           }
6479         ;
6480
6481 where_clause
6482         : WHERE
6483           {
6484                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6485           }
6486           expression_or_error
6487           {
6488                 $$ = new Linq.Where ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
6489
6490                 current_block.SetEndLocation (lexer.Location);
6491                 current_block = current_block.Parent;
6492           }
6493         ;
6494         
6495 join_clause
6496         : JOIN identifier_inside_body IN
6497           {
6498                 if (linq_clause_blocks == null)
6499                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
6500                         
6501                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6502                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6503           }
6504           expression_or_error ON
6505           {
6506                 current_block.SetEndLocation (lexer.Location);
6507                 current_block = current_block.Parent;
6508
6509                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6510                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6511           }
6512           expression_or_error EQUALS
6513           {
6514                 current_block.AddStatement (new ContextualReturn ((Expression) $8));
6515                 current_block.SetEndLocation (lexer.Location);
6516                 current_block = current_block.Parent;
6517
6518                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6519           }
6520           expression_or_error opt_join_into
6521           {
6522                 current_block.AddStatement (new ContextualReturn ((Expression) $11));
6523                 current_block.SetEndLocation (lexer.Location);
6524           
6525                 var outer_selector = linq_clause_blocks.Pop ();
6526                 var block = linq_clause_blocks.Pop ();
6527
6528                 var lt = (LocatedToken) $2;     
6529                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6530                 Linq.RangeVariable into;
6531                 
6532                 if ($12 == null) {
6533                         into = sn;
6534                         $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1));
6535                         lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9));
6536                 } else {
6537                         //
6538                         // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
6539                         //
6540                         var parent = block.Parent;
6541                         while (parent is Linq.QueryBlock) {
6542                                 parent = parent.Parent;
6543                         }
6544                         current_block.Parent = parent;
6545                         
6546                         ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6547                 
6548                         lt = (LocatedToken) $12;
6549                         into = new Linq.RangeVariable (lt.Value, lt.Location);
6550
6551                         $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1));   
6552                         lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($12));
6553                 }
6554
6555                 current_block = block.Parent;
6556                 ((Linq.QueryBlock)current_block).AddRangeVariable (into);
6557           }
6558         | JOIN type identifier_inside_body IN
6559           {
6560                 if (linq_clause_blocks == null)
6561                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
6562                         
6563                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6564                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6565           }
6566           expression_or_error ON
6567           {
6568                 current_block.SetEndLocation (lexer.Location);
6569                 current_block = current_block.Parent;
6570
6571                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6572                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6573           }
6574           expression_or_error EQUALS
6575           {
6576                 current_block.AddStatement (new ContextualReturn ((Expression) $9));
6577                 current_block.SetEndLocation (lexer.Location);
6578                 current_block = current_block.Parent;
6579
6580                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6581           }
6582           expression_or_error opt_join_into
6583           {
6584                 current_block.AddStatement (new ContextualReturn ((Expression) $12));
6585                 current_block.SetEndLocation (lexer.Location);
6586           
6587                 var outer_selector = linq_clause_blocks.Pop ();
6588                 var block = linq_clause_blocks.Pop ();
6589                 
6590                 var lt = (LocatedToken) $3;
6591                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6592                 Linq.RangeVariable into;
6593                 
6594                 if ($13 == null) {
6595                         into = sn;              
6596                         $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) {
6597                                 IdentifierType = (FullNamedExpression)$2
6598                         };
6599                         lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9));
6600                 } else {
6601                         //
6602                         // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
6603                         //
6604                         var parent = block.Parent;
6605                         while (parent is Linq.QueryBlock) {
6606                                 parent = parent.Parent;
6607                         }
6608                         current_block.Parent = parent;
6609                 
6610                         ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6611                 
6612                         lt = (LocatedToken) $13;
6613                         into = new Linq.RangeVariable (lt.Value, lt.Location); // TODO:
6614                         
6615                         $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)) {
6616                                 IdentifierType = (FullNamedExpression)$2
6617                         };                      
6618                 }
6619                 
6620                 current_block = block.Parent;
6621                 ((Linq.QueryBlock)current_block).AddRangeVariable (into);               
6622           }
6623         ;
6624         
6625 opt_join_into
6626         : /* empty */
6627         | INTO identifier_inside_body
6628           {
6629                 $$ = $2;
6630           }
6631         ;
6632         
6633 orderby_clause
6634         : ORDERBY
6635           {
6636                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6637           }
6638           orderings
6639           {
6640                 current_block.SetEndLocation (lexer.Location);
6641                 current_block = current_block.Parent;
6642           
6643                 $$ = $3;
6644           }
6645         ;
6646         
6647 orderings
6648         : order_by
6649         | order_by COMMA
6650           {
6651                 current_block.SetEndLocation (lexer.Location);
6652                 current_block = current_block.Parent;
6653           
6654                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6655           }
6656           orderings_then_by
6657           {
6658                 ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4;
6659                 $$ = $1;
6660           }
6661         ;
6662         
6663 orderings_then_by
6664         : then_by
6665         | orderings_then_by COMMA
6666          {
6667                 current_block.SetEndLocation (lexer.Location);
6668                 current_block = current_block.Parent;
6669           
6670                 current_block = new Linq.QueryBlock ((Linq.QueryBlock) current_block, lexer.Location);   
6671          }
6672          then_by
6673          {
6674                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$4;
6675                 $$ = $1;
6676          }
6677         ;       
6678         
6679 order_by
6680         : expression
6681           {
6682                 $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
6683           }
6684         | expression ASCENDING
6685           {
6686                 $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
6687                 lbag.AddLocation ($$, GetLocation ($2));
6688           }
6689         | expression DESCENDING
6690           {
6691                 $$ = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)$1);      
6692                 lbag.AddLocation ($$, GetLocation ($2));
6693           }
6694         ;
6695
6696 then_by
6697         : expression
6698           {
6699                 $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
6700           }
6701         | expression ASCENDING
6702           {
6703                 $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
6704                 lbag.AddLocation ($$, GetLocation ($2));
6705           }
6706         | expression DESCENDING
6707           {
6708                 $$ = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)$1);       
6709                 lbag.AddLocation ($$, GetLocation ($2));
6710           }     
6711         ;
6712
6713
6714 opt_query_continuation
6715         : /* empty */
6716         | INTO identifier_inside_body
6717           {
6718                 // query continuation block is not linked with query block but with block
6719                 // before. This means each query can use same range variable names for
6720                 // different identifiers.
6721
6722                 current_block.SetEndLocation (GetLocation ($1));
6723                 current_block = current_block.Parent;
6724         
6725                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6726                 
6727                 if (linq_clause_blocks == null)
6728                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
6729                         
6730                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);              
6731           }
6732           query_body
6733           {
6734                 var current_block = linq_clause_blocks.Pop ();    
6735                 var lt = (LocatedToken) $2;
6736                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
6737                 $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation ($1)) {
6738                         next = (Linq.AQueryClause)$4
6739                 };
6740           }
6741         ;
6742         
6743 //
6744 // Support for using the compiler as an interactive parser
6745 //
6746 // The INTERACTIVE_PARSER token is first sent to parse our
6747 // productions;  If the result is a Statement, the parsing
6748 // is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
6749 // to setup the blocks in advance.
6750 //
6751 // This setup is here so that in the future we can add 
6752 // support for other constructs (type parsing, namespaces, etc)
6753 // that do not require a block to be setup in advance
6754 //
6755
6756 interactive_parsing
6757         : EVAL_STATEMENT_PARSER EOF 
6758         | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives opt_COMPLETE_COMPLETION
6759         | EVAL_STATEMENT_PARSER
6760          { 
6761                 current_container = current_type = new Class (current_container, new MemberName ("<InteractiveExpressionClass>"), Modifiers.PUBLIC, null);
6762
6763                 // (ref object retval)
6764                 Parameter [] mpar = new Parameter [1];
6765                 mpar [0] = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null);
6766
6767                 ParametersCompiled pars = new ParametersCompiled (mpar);
6768                 var mods = Modifiers.PUBLIC | Modifiers.STATIC;
6769                 if (settings.Unsafe)
6770                         mods |= Modifiers.UNSAFE;
6771
6772                 current_local_parameters = pars;
6773                 var method = new InteractiveMethod (
6774                         current_type,
6775                         new TypeExpression (compiler.BuiltinTypes.Void, Location.Null),
6776                         mods,
6777                         pars);
6778                         
6779                 current_type.AddMember (method);                        
6780                 oob_stack.Push (method);
6781
6782                 interactive_async = false;
6783
6784                 ++lexer.parsing_block;
6785                 start_block (lexer.Location);
6786           }             
6787           interactive_statement_list opt_COMPLETE_COMPLETION
6788           {
6789                 --lexer.parsing_block;
6790                 var method = (InteractiveMethod) oob_stack.Pop ();
6791                 method.Block = (ToplevelBlock) end_block(lexer.Location);
6792
6793                 if (interactive_async == true) {
6794                         method.ChangeToAsync ();
6795                 }
6796
6797                 InteractiveResult = (Class) pop_current_class ();
6798                 current_local_parameters = null;
6799           } 
6800         | EVAL_COMPILATION_UNIT_PARSER interactive_compilation_unit
6801         ;
6802
6803 interactive_compilation_unit
6804         : opt_extern_alias_directives opt_using_directives
6805         | opt_extern_alias_directives opt_using_directives namespace_or_type_declarations
6806         ;
6807
6808 opt_COMPLETE_COMPLETION
6809         : /* nothing */
6810         | COMPLETE_COMPLETION
6811         ;
6812
6813 close_brace_or_complete_completion
6814         : CLOSE_BRACE
6815         | COMPLETE_COMPLETION
6816         ;
6817         
6818 //
6819 // XML documentation code references micro parser
6820 //
6821 documentation_parsing
6822         : DOC_SEE doc_cref
6823           {
6824                 module.DocumentationBuilder.ParsedName = (MemberName) $2;
6825           }
6826         ;
6827
6828 doc_cref
6829         : doc_type_declaration_name opt_doc_method_sig
6830           {
6831                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$2;
6832           }
6833         | builtin_types opt_doc_method_sig
6834           {
6835                 module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
6836                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$2;
6837                 $$ = null;
6838           }
6839         | builtin_types DOT IDENTIFIER opt_doc_method_sig
6840           {
6841                 module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
6842                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$4;
6843                 var lt = (LocatedToken) $3;
6844                 $$ = new MemberName (lt.Value);
6845           }
6846         | doc_type_declaration_name DOT THIS
6847           {
6848                 $$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
6849           }
6850         | doc_type_declaration_name DOT THIS OPEN_BRACKET
6851           {
6852                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
6853           }
6854           opt_doc_parameters CLOSE_BRACKET
6855           {
6856                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$6;
6857                 $$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
6858           }
6859         | EXPLICIT OPERATOR type opt_doc_method_sig
6860           {
6861                 var p = (List<DocumentationParameter>)$4 ?? new List<DocumentationParameter> (1);
6862                 p.Add (new DocumentationParameter ((FullNamedExpression) $3));
6863                 module.DocumentationBuilder.ParsedParameters = p;
6864                 module.DocumentationBuilder.ParsedOperator = Operator.OpType.Explicit;
6865                 $$ = null;
6866           }
6867         | IMPLICIT OPERATOR type opt_doc_method_sig
6868           {
6869                 var p = (List<DocumentationParameter>)$4 ?? new List<DocumentationParameter> (1);
6870                 p.Add (new DocumentationParameter ((FullNamedExpression) $3));
6871                 module.DocumentationBuilder.ParsedParameters = p;
6872                 module.DocumentationBuilder.ParsedOperator = Operator.OpType.Implicit;
6873                 $$ = null;
6874           }       
6875         | OPERATOR overloadable_operator opt_doc_method_sig
6876           {
6877                 var p = (List<DocumentationParameter>)$3 ?? new List<DocumentationParameter> (1);
6878                 module.DocumentationBuilder.ParsedParameters = p;
6879                 module.DocumentationBuilder.ParsedOperator = (Operator.OpType) $2;
6880                 $$ = null;
6881           }
6882         ;
6883         
6884 doc_type_declaration_name
6885         : type_declaration_name
6886         | doc_type_declaration_name DOT type_declaration_name
6887           {
6888                 $$ = new MemberName (((MemberName) $1), (MemberName) $3);
6889           }
6890         ;
6891         
6892 opt_doc_method_sig
6893         : /* empty */
6894         | OPEN_PARENS
6895           {
6896                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
6897           }
6898           opt_doc_parameters CLOSE_PARENS
6899           {
6900                 $$ = $3;
6901           }
6902         ;
6903         
6904 opt_doc_parameters
6905         : /* empty */
6906           {
6907                 $$ = new List<DocumentationParameter> (0);
6908           }
6909         | doc_parameters
6910         ;
6911         
6912 doc_parameters
6913         : doc_parameter
6914           {
6915                 var parameters = new List<DocumentationParameter> ();
6916                 parameters.Add ((DocumentationParameter) $1);
6917                 $$ = parameters;
6918           }
6919         | doc_parameters COMMA doc_parameter
6920           {
6921                 var parameters = $1 as List<DocumentationParameter>;
6922                 parameters.Add ((DocumentationParameter) $3);
6923                 $$ = parameters;
6924           }
6925         ;
6926         
6927 doc_parameter
6928         : opt_parameter_modifier parameter_type
6929           {
6930                 if ($1 != null)
6931                         $$ = new DocumentationParameter ((Parameter.Modifier) $1, (FullNamedExpression) $2);
6932                 else
6933                         $$ = new DocumentationParameter ((FullNamedExpression) $2);
6934           }
6935         ;
6936         
6937 %%
6938
6939 // <summary>
6940 //  A class used to hold info about an operator declarator
6941 // </summary>
6942 class OperatorDeclaration {
6943         public readonly Operator.OpType optype;
6944         public readonly FullNamedExpression ret_type;
6945         public readonly Location location;
6946
6947         public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
6948         {
6949                 optype = op;
6950                 this.ret_type = ret_type;
6951                 this.location = location;
6952         }
6953 }
6954
6955 void Error_ExpectingTypeName (Expression expr)
6956 {
6957         if (expr is Invocation){
6958                 report.Error (1002, expr.Location, "Expecting `;'");
6959         } else {
6960                 expr.Error_InvalidExpressionStatement (report);
6961         }
6962 }
6963
6964 void Error_ParameterModifierNotValid (string modifier, Location loc)
6965 {
6966         report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
6967                                       modifier);
6968 }
6969
6970 void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
6971 {
6972         report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
6973                 Parameter.GetModifierSignature (mod));
6974 }
6975
6976 void Error_TypeExpected (Location loc)
6977 {
6978         report.Error (1031, loc, "Type expected");
6979 }
6980
6981 void Error_UnsafeCodeNotAllowed (Location loc)
6982 {
6983         report.Error (227, loc, "Unsafe code requires the `unsafe' command line option to be specified");
6984 }
6985
6986 void Warning_EmptyStatement (Location loc)
6987 {
6988         report.Warning (642, 3, loc, "Possible mistaken empty statement");
6989 }
6990
6991 void Error_NamedArgumentExpected (NamedArgument a)
6992 {
6993         report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
6994 }
6995
6996 void Error_MissingInitializer (Location loc)
6997 {
6998         report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration");
6999 }
7000
7001 object Error_AwaitAsIdentifier (object token)
7002 {
7003         if (async_block) {
7004                 report.Error (4003, GetLocation (token), "`await' cannot be used as an identifier within an async method or lambda expression");
7005                 return new LocatedToken ("await", GetLocation (token));
7006         }
7007
7008         return token;
7009 }
7010
7011 void push_current_container (TypeDefinition tc, object partial_token)
7012 {
7013         if (module.Evaluator != null){
7014                 tc.Definition.Modifiers = tc.ModFlags = (tc.ModFlags & ~Modifiers.AccessibilityMask) | Modifiers.PUBLIC;
7015                 if (undo == null)
7016                         undo = new Undo ();
7017
7018                 undo.AddTypeContainer (current_container, tc);
7019         }
7020         
7021         if (partial_token != null)
7022                 current_container.AddPartial (tc);
7023         else
7024                 current_container.AddTypeContainer (tc);
7025                 
7026         ++lexer.parsing_declaration;
7027         current_container = tc;
7028         current_type = tc;
7029 }
7030
7031 TypeContainer pop_current_class ()
7032 {
7033         var retval = current_container;
7034
7035         current_container = current_container.Parent;
7036         current_type = current_type.Parent as TypeDefinition;
7037
7038         return retval;
7039 }
7040
7041 [System.Diagnostics.Conditional ("FULL_AST")]
7042 void StoreModifierLocation (object token, Location loc)
7043 {
7044         if (lbag == null)
7045                 return;
7046
7047         if (mod_locations == null)
7048                 mod_locations = new List<Tuple<Modifiers, Location>> ();
7049
7050         mod_locations.Add (Tuple.Create ((Modifiers) token, loc));
7051 }
7052
7053 [System.Diagnostics.Conditional ("FULL_AST")]
7054 void PushLocation (Location loc)
7055 {
7056         if (location_stack == null)
7057                 location_stack = new Stack<Location> ();
7058
7059         location_stack.Push (loc);
7060 }
7061
7062 Location PopLocation ()
7063 {
7064         if (location_stack == null)
7065                 return Location.Null;
7066
7067         return location_stack.Pop ();
7068 }
7069
7070 string CheckAttributeTarget (int token, string a, Location l)
7071 {
7072         switch (a) {
7073         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
7074                         return a;
7075         }
7076
7077         if (!Tokenizer.IsValidIdentifier (a)) {
7078                 Error_SyntaxError (token);
7079         } else {
7080                 report.Warning (658, 1, l,
7081                          "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
7082         }
7083
7084         return string.Empty;
7085 }
7086
7087 static bool IsUnaryOperator (Operator.OpType op)
7088 {
7089         switch (op) {
7090                 
7091         case Operator.OpType.LogicalNot: 
7092         case Operator.OpType.OnesComplement: 
7093         case Operator.OpType.Increment:
7094         case Operator.OpType.Decrement:
7095         case Operator.OpType.True: 
7096         case Operator.OpType.False: 
7097         case Operator.OpType.UnaryPlus: 
7098         case Operator.OpType.UnaryNegation:
7099                 return true;
7100         }
7101         return false;
7102 }
7103
7104 void syntax_error (Location l, string msg)
7105 {
7106         report.Error (1003, l, "Syntax error, " + msg);
7107 }
7108
7109 Tokenizer lexer;
7110
7111 public Tokenizer Lexer {
7112         get {
7113                 return lexer;
7114         }
7115 }                  
7116
7117 public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, ParserSession session)
7118         : this (reader, file, file.Compiler.Report, session)
7119 {
7120 }
7121
7122 public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report, ParserSession session)
7123 {
7124         this.file = file;
7125         current_container = current_namespace = file;
7126         
7127         this.module = file.Module;
7128         this.compiler = file.Compiler;
7129         this.settings = compiler.Settings;
7130         this.report = report;
7131         
7132         lang_version = settings.Version;
7133         yacc_verbose_flag = settings.VerboseParserFlag;
7134         doc_support = settings.DocumentationFile != null;
7135         lexer = new Tokenizer (reader, file, session, report);
7136         oob_stack = new Stack<object> ();
7137         lbag = session.LocationsBag;
7138         use_global_stacks = session.UseJayGlobalArrays;
7139         parameters_bucket = session.ParametersStack;
7140 }
7141
7142 public void parse ()
7143 {
7144         eof_token = Token.EOF;
7145         
7146         try {
7147                 if (yacc_verbose_flag > 1)
7148                         yyparse (lexer, new yydebug.yyDebugSimple ());
7149                 else
7150                         yyparse (lexer);
7151                         
7152                 Tokenizer tokenizer = lexer as Tokenizer;
7153                 tokenizer.cleanup ();           
7154         } catch (Exception e){
7155                 if (e is yyParser.yyUnexpectedEof) {
7156                         Error_SyntaxError (yyToken);
7157                         UnexpectedEOF = true;
7158                         return;
7159                 }
7160                         
7161                 if (e is yyParser.yyException) {
7162                         if (report.Errors == 0)
7163                                 report.Error (-25, lexer.Location, "Parsing error");
7164                 } else {
7165                         // Used by compiler-tester to test internal errors
7166                         if (yacc_verbose_flag > 0 || e is FatalException)
7167                                 throw;
7168                 
7169                         report.Error (589, lexer.Location, "Internal compiler error during parsing" + e);
7170                 }
7171         }
7172 }
7173
7174 void CheckToken (int error, int yyToken, string msg, Location loc)
7175 {
7176         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
7177                 report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken));
7178         else
7179                 report.Error (error, loc, msg);
7180 }
7181
7182 string ConsumeStoredComment ()
7183 {
7184         string s = tmpComment;
7185         tmpComment = null;
7186         Lexer.doc_state = XmlCommentState.Allowed;
7187         return s;
7188 }
7189
7190 void FeatureIsNotAvailable (Location loc, string feature)
7191 {
7192         report.FeatureIsNotAvailable (compiler, loc, feature);
7193 }
7194
7195 Location GetLocation (object obj)
7196 {
7197         var lt = obj as LocatedToken;
7198         if (lt != null)
7199                 return lt.Location;
7200                 
7201         var mn = obj as MemberName;
7202         if (mn != null)
7203                 return mn.Location;
7204                 
7205         var expr = obj as Expression;
7206         if (expr != null)
7207                 return expr.Location;
7208
7209         return lexer.Location;
7210 }
7211
7212 void start_block (Location loc)
7213 {
7214         if (current_block == null) {
7215                 current_block = new ToplevelBlock (compiler, current_local_parameters, loc);
7216                 parsing_anonymous_method = false;
7217         } else if (parsing_anonymous_method) {
7218                 current_block = new ParametersBlock (current_block, current_local_parameters, loc);
7219                 parsing_anonymous_method = false;
7220         } else {
7221                 current_block = new ExplicitBlock (current_block, loc, Location.Null);
7222         }
7223 }
7224
7225 Block
7226 end_block (Location loc)
7227 {
7228         Block retval = current_block.Explicit;
7229         retval.SetEndLocation (loc);
7230         current_block = retval.Parent;
7231         return retval;
7232 }
7233
7234 void start_anonymous (bool isLambda, ParametersCompiled parameters, bool isAsync, Location loc)
7235 {
7236         oob_stack.Push (current_anonymous_method);
7237         oob_stack.Push (current_local_parameters);
7238         oob_stack.Push (current_variable);
7239         oob_stack.Push (async_block);
7240
7241         current_local_parameters = parameters;
7242         if (isLambda) {
7243                 if (lang_version <= LanguageVersion.ISO_2)
7244                         FeatureIsNotAvailable (loc, "lambda expressions");
7245
7246                 current_anonymous_method = new LambdaExpression (loc);
7247         } else {
7248                 if (lang_version == LanguageVersion.ISO_1)
7249                         FeatureIsNotAvailable (loc, "anonymous methods");
7250                         
7251                 current_anonymous_method = new AnonymousMethodExpression (loc);
7252         }
7253
7254         async_block = isAsync;
7255         // Force the next block to be created as a ToplevelBlock
7256         parsing_anonymous_method = true;
7257 }
7258
7259 /*
7260  * Completes the anonymous method processing, if lambda_expr is null, this
7261  * means that we have a Statement instead of an Expression embedded 
7262  */
7263 AnonymousMethodExpression end_anonymous (ParametersBlock anon_block)
7264 {
7265         AnonymousMethodExpression retval;
7266
7267         if (async_block)
7268                 anon_block.IsAsync = true;
7269
7270         current_anonymous_method.Block = anon_block;
7271         retval = current_anonymous_method;
7272
7273         async_block = (bool) oob_stack.Pop ();
7274         current_variable = (BlockVariable) oob_stack.Pop ();
7275         current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
7276         current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
7277
7278         return retval;
7279 }
7280
7281 void Error_SyntaxError (int token)
7282 {
7283         Error_SyntaxError (0, token);
7284 }
7285
7286 void Error_SyntaxError (int error_code, int token)
7287 {
7288         Error_SyntaxError (error_code, token, "Unexpected symbol");
7289 }
7290
7291 void Error_SyntaxError (int error_code, int token, string msg)
7292 {
7293         Lexer.CompleteOnEOF = false;
7294
7295         // An error message has been reported by tokenizer
7296         if (token == Token.ERROR)
7297                 return;
7298         
7299         // Avoid duplicit error message after unterminated string literals
7300         if (token == Token.LITERAL && lexer.Location.Column == 0)
7301                 return;
7302
7303         string symbol = GetSymbolName (token);
7304         string expecting = GetExpecting ();
7305         var loc = lexer.Location - symbol.Length;
7306         
7307         if (error_code == 0) {
7308                 if (expecting == "`identifier'") {
7309                         if (token > Token.FIRST_KEYWORD && token < Token.LAST_KEYWORD) {
7310                                 report.Error (1041, loc, "Identifier expected, `{0}' is a keyword", symbol);
7311                                 return;
7312                         }
7313                         
7314                         error_code = 1001;
7315                         expecting = "identifier";
7316                 } else if (expecting == "`)'") {
7317                         error_code = 1026;
7318                 } else {
7319                         error_code = 1525;
7320                 }
7321         }
7322         
7323         if (string.IsNullOrEmpty (expecting))
7324                 report.Error (error_code, loc, "{1} `{0}'", symbol, msg);
7325         else
7326                 report.Error (error_code, loc, "{2} `{0}', expecting {1}", symbol, expecting, msg);       
7327 }
7328
7329 string GetExpecting ()
7330 {
7331         int [] tokens = yyExpectingTokens (yyExpectingState);
7332         var names = new List<string> (tokens.Length);
7333         bool has_type = false;
7334         bool has_identifier = false;
7335         for (int i = 0; i < tokens.Length; i++){
7336                 int token = tokens [i];
7337                 has_identifier |= token == Token.IDENTIFIER;
7338                 
7339                 string name = GetTokenName (token);
7340                 if (name == "<internal>")
7341                         continue;
7342                         
7343                 has_type |= name == "type";
7344                 if (names.Contains (name))
7345                         continue;
7346                 
7347                 names.Add (name);
7348         }
7349
7350         //
7351         // Too many tokens to enumerate
7352         //
7353         if (names.Count > 8)
7354                 return null;
7355
7356         if (has_type && has_identifier)
7357                 names.Remove ("identifier");
7358
7359         if (names.Count == 1)
7360                 return "`" + GetTokenName (tokens [0]) + "'";
7361         
7362         StringBuilder sb = new StringBuilder ();
7363         names.Sort ();
7364         int count = names.Count;
7365         for (int i = 0; i < count; i++){
7366                 bool last = i + 1 == count;
7367                 if (last)
7368                         sb.Append ("or ");
7369                 sb.Append ('`');
7370                 sb.Append (names [i]);
7371                 sb.Append (last ? "'" : count < 3 ? "' " : "', ");
7372         }
7373         return sb.ToString ();
7374 }
7375
7376
7377 string GetSymbolName (int token)
7378 {
7379         switch (token){
7380         case Token.LITERAL:
7381                 return ((Constant)lexer.Value).GetValue ().ToString ();
7382         case Token.IDENTIFIER:
7383                 return ((LocatedToken)lexer.Value).Value;
7384
7385         case Token.BOOL:
7386                 return "bool";
7387         case Token.BYTE:
7388                 return "byte";
7389         case Token.CHAR:
7390                 return "char";
7391         case Token.VOID:
7392                 return "void";
7393         case Token.DECIMAL:
7394                 return "decimal";
7395         case Token.DOUBLE:
7396                 return "double";
7397         case Token.FLOAT:
7398                 return "float";
7399         case Token.INT:
7400                 return "int";
7401         case Token.LONG:
7402                 return "long";
7403         case Token.SBYTE:
7404                 return "sbyte";
7405         case Token.SHORT:
7406                 return "short";
7407         case Token.STRING:
7408                 return "string";
7409         case Token.UINT:
7410                 return "uint";
7411         case Token.ULONG:
7412                 return "ulong";
7413         case Token.USHORT:
7414                 return "ushort";
7415         case Token.OBJECT:
7416                 return "object";
7417                 
7418         case Token.PLUS:
7419                 return "+";
7420         case Token.UMINUS:
7421         case Token.MINUS:
7422                 return "-";
7423         case Token.BANG:
7424                 return "!";
7425         case Token.BITWISE_AND:
7426                 return "&";
7427         case Token.BITWISE_OR:
7428                 return "|";
7429         case Token.STAR:
7430                 return "*";
7431         case Token.PERCENT:
7432                 return "%";
7433         case Token.DIV:
7434                 return "/";
7435         case Token.CARRET:
7436                 return "^";
7437         case Token.OP_INC:
7438                 return "++";
7439         case Token.OP_DEC:
7440                 return "--";
7441         case Token.OP_SHIFT_LEFT:
7442                 return "<<";
7443         case Token.OP_SHIFT_RIGHT:
7444                 return ">>";
7445         case Token.OP_LT:
7446                 return "<";
7447         case Token.OP_GT:
7448                 return ">";
7449         case Token.OP_LE:
7450                 return "<=";
7451         case Token.OP_GE:
7452                 return ">=";
7453         case Token.OP_EQ:
7454                 return "==";
7455         case Token.OP_NE:
7456                 return "!=";
7457         case Token.OP_AND:
7458                 return "&&";
7459         case Token.OP_OR:
7460                 return "||";
7461         case Token.OP_PTR:
7462                 return "->";
7463         case Token.OP_COALESCING:       
7464                 return "??";
7465         case Token.OP_MULT_ASSIGN:
7466                 return "*=";
7467         case Token.OP_DIV_ASSIGN:
7468                 return "/=";
7469         case Token.OP_MOD_ASSIGN:
7470                 return "%=";
7471         case Token.OP_ADD_ASSIGN:
7472                 return "+=";
7473         case Token.OP_SUB_ASSIGN:
7474                 return "-=";
7475         case Token.OP_SHIFT_LEFT_ASSIGN:
7476                 return "<<=";
7477         case Token.OP_SHIFT_RIGHT_ASSIGN:
7478                 return ">>=";
7479         case Token.OP_AND_ASSIGN:
7480                 return "&=";
7481         case Token.OP_XOR_ASSIGN:
7482                 return "^=";
7483         case Token.OP_OR_ASSIGN:
7484                 return "|=";
7485         }
7486
7487         return GetTokenName (token);
7488 }
7489
7490 static string GetTokenName (int token)
7491 {
7492         switch (token){
7493         case Token.ABSTRACT:
7494                 return "abstract";
7495         case Token.AS:
7496                 return "as";
7497         case Token.ADD:
7498                 return "add";
7499         case Token.ASYNC:
7500                 return "async";
7501         case Token.BASE:
7502                 return "base";
7503         case Token.BREAK:
7504                 return "break";
7505         case Token.CASE:
7506                 return "case";
7507         case Token.CATCH:
7508                 return "catch";
7509         case Token.CHECKED:
7510                 return "checked";
7511         case Token.CLASS:
7512                 return "class";
7513         case Token.CONST:
7514                 return "const";
7515         case Token.CONTINUE:
7516                 return "continue";
7517         case Token.DEFAULT:
7518                 return "default";
7519         case Token.DELEGATE:
7520                 return "delegate";
7521         case Token.DO:
7522                 return "do";
7523         case Token.ELSE:
7524                 return "else";
7525         case Token.ENUM:
7526                 return "enum";
7527         case Token.EVENT:
7528                 return "event";
7529         case Token.EXPLICIT:
7530                 return "explicit";
7531         case Token.EXTERN:
7532         case Token.EXTERN_ALIAS:
7533                 return "extern";
7534         case Token.FALSE:
7535                 return "false";
7536         case Token.FINALLY:
7537                 return "finally";
7538         case Token.FIXED:
7539                 return "fixed";
7540         case Token.FOR:
7541                 return "for";
7542         case Token.FOREACH:
7543                 return "foreach";
7544         case Token.GOTO:
7545                 return "goto";
7546         case Token.IF:
7547                 return "if";
7548         case Token.IMPLICIT:
7549                 return "implicit";
7550         case Token.IN:
7551                 return "in";
7552         case Token.INTERFACE:
7553                 return "interface";
7554         case Token.INTERNAL:
7555                 return "internal";
7556         case Token.IS:
7557                 return "is";
7558         case Token.LOCK:
7559                 return "lock";
7560         case Token.NAMESPACE:
7561                 return "namespace";
7562         case Token.NEW:
7563                 return "new";
7564         case Token.NULL:
7565                 return "null";
7566         case Token.OPERATOR:
7567                 return "operator";
7568         case Token.OUT:
7569                 return "out";
7570         case Token.OVERRIDE:
7571                 return "override";
7572         case Token.PARAMS:
7573                 return "params";
7574         case Token.PRIVATE:
7575                 return "private";
7576         case Token.PROTECTED:
7577                 return "protected";
7578         case Token.PUBLIC:
7579                 return "public";
7580         case Token.READONLY:
7581                 return "readonly";
7582         case Token.REF:
7583                 return "ref";
7584         case Token.RETURN:
7585                 return "return";
7586         case Token.REMOVE:
7587                 return "remove";
7588         case Token.SEALED:
7589                 return "sealed";
7590         case Token.SIZEOF:
7591                 return "sizeof";
7592         case Token.STACKALLOC:
7593                 return "stackalloc";
7594         case Token.STATIC:
7595                 return "static";
7596         case Token.STRUCT:
7597                 return "struct";
7598         case Token.SWITCH:
7599                 return "switch";
7600         case Token.THIS:
7601                 return "this";
7602         case Token.THROW:
7603                 return "throw";
7604         case Token.TRUE:
7605                 return "true";
7606         case Token.TRY:
7607                 return "try";
7608         case Token.TYPEOF:
7609                 return "typeof";
7610         case Token.UNCHECKED:
7611                 return "unchecked";
7612         case Token.UNSAFE:
7613                 return "unsafe";
7614         case Token.USING:
7615                 return "using";
7616         case Token.VIRTUAL:
7617                 return "virtual";
7618         case Token.VOLATILE:
7619                 return "volatile";
7620         case Token.WHERE:
7621                 return "where";
7622         case Token.WHILE:
7623                 return "while";
7624         case Token.ARGLIST:
7625                 return "__arglist";
7626         case Token.REFVALUE:
7627                 return "__refvalue";
7628         case Token.REFTYPE:
7629                 return "__reftype";
7630         case Token.MAKEREF:
7631                 return "__makeref";
7632         case Token.PARTIAL:
7633                 return "partial";
7634         case Token.ARROW:
7635                 return "=>";
7636         case Token.FROM:
7637         case Token.FROM_FIRST:
7638                 return "from";
7639         case Token.JOIN:
7640                 return "join";
7641         case Token.ON:
7642                 return "on";
7643         case Token.EQUALS:
7644                 return "equals";
7645         case Token.SELECT:
7646                 return "select";
7647         case Token.GROUP:
7648                 return "group";
7649         case Token.BY:
7650                 return "by";
7651         case Token.LET:
7652                 return "let";
7653         case Token.ORDERBY:
7654                 return "orderby";
7655         case Token.ASCENDING:
7656                 return "ascending";
7657         case Token.DESCENDING:
7658                 return "descending";
7659         case Token.INTO:
7660                 return "into";
7661         case Token.GET:
7662                 return "get";
7663         case Token.SET:
7664                 return "set";
7665         case Token.OPEN_BRACE:
7666                 return "{";
7667         case Token.CLOSE_BRACE:
7668                 return "}";
7669         case Token.OPEN_BRACKET:
7670         case Token.OPEN_BRACKET_EXPR:
7671                 return "[";
7672         case Token.CLOSE_BRACKET:
7673                 return "]";
7674         case Token.OPEN_PARENS_CAST:
7675         case Token.OPEN_PARENS_LAMBDA:
7676         case Token.OPEN_PARENS:
7677                 return "(";
7678         case Token.CLOSE_PARENS:
7679                 return ")";
7680         case Token.DOT:
7681                 return ".";
7682         case Token.COMMA:
7683                 return ",";
7684         case Token.DEFAULT_COLON:
7685                 return "default:";
7686         case Token.COLON:
7687                 return ":";
7688         case Token.SEMICOLON:
7689                 return ";";
7690         case Token.TILDE:
7691                 return "~";
7692                 
7693         case Token.PLUS:
7694         case Token.UMINUS:
7695         case Token.MINUS:
7696         case Token.BANG:
7697         case Token.OP_LT:
7698         case Token.OP_GT:
7699         case Token.BITWISE_AND:
7700         case Token.BITWISE_OR:
7701         case Token.STAR:
7702         case Token.PERCENT:
7703         case Token.DIV:
7704         case Token.CARRET:
7705         case Token.OP_INC:
7706         case Token.OP_DEC:
7707         case Token.OP_SHIFT_LEFT:
7708         case Token.OP_SHIFT_RIGHT:
7709         case Token.OP_LE:
7710         case Token.OP_GE:
7711         case Token.OP_EQ:
7712         case Token.OP_NE:
7713         case Token.OP_AND:
7714         case Token.OP_OR:
7715         case Token.OP_PTR:
7716         case Token.OP_COALESCING:       
7717         case Token.OP_MULT_ASSIGN:
7718         case Token.OP_DIV_ASSIGN:
7719         case Token.OP_MOD_ASSIGN:
7720         case Token.OP_ADD_ASSIGN:
7721         case Token.OP_SUB_ASSIGN:
7722         case Token.OP_SHIFT_LEFT_ASSIGN:
7723         case Token.OP_SHIFT_RIGHT_ASSIGN:
7724         case Token.OP_AND_ASSIGN:
7725         case Token.OP_XOR_ASSIGN:
7726         case Token.OP_OR_ASSIGN:
7727                 return "<operator>";
7728
7729         case Token.BOOL:
7730         case Token.BYTE:
7731         case Token.CHAR:
7732         case Token.VOID:
7733         case Token.DECIMAL:
7734         case Token.DOUBLE:
7735         case Token.FLOAT:
7736         case Token.INT:
7737         case Token.LONG:
7738         case Token.SBYTE:
7739         case Token.SHORT:
7740         case Token.STRING:
7741         case Token.UINT:
7742         case Token.ULONG:
7743         case Token.USHORT:
7744         case Token.OBJECT:
7745                 return "type";
7746         
7747         case Token.ASSIGN:
7748                 return "=";
7749         case Token.OP_GENERICS_LT:
7750         case Token.GENERIC_DIMENSION:
7751                 return "<";
7752         case Token.OP_GENERICS_GT:
7753                 return ">";
7754         case Token.INTERR:
7755         case Token.INTERR_NULLABLE:
7756                 return "?";
7757         case Token.DOUBLE_COLON:
7758                 return "::";
7759         case Token.LITERAL:
7760                 return "value";
7761         case Token.IDENTIFIER:
7762         case Token.AWAIT:
7763                 return "identifier";
7764
7765         case Token.EOF:
7766                 return "end-of-file";
7767
7768                 // All of these are internal.
7769         case Token.NONE:
7770         case Token.ERROR:
7771         case Token.FIRST_KEYWORD:
7772         case Token.EVAL_COMPILATION_UNIT_PARSER:
7773         case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER:
7774         case Token.EVAL_STATEMENT_PARSER:
7775         case Token.LAST_KEYWORD:
7776         case Token.GENERATE_COMPLETION:
7777         case Token.COMPLETE_COMPLETION:
7778                 return "<internal>";
7779
7780                 // A bit more robust.
7781         default:
7782                 return yyNames [token];
7783         }
7784 }
7785
7786 /* end end end */
7787 }