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