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