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