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