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