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