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