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