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