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