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