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