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