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