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