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