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