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