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