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