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