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