Merge pull request #439 from mono-soc-2012/garyb/iconfix
[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                 lexer.putback (')'); // TODO: Wrong but what can I do
3240                 Error_SyntaxError (yyToken);
3241                 $$ = $1;
3242           }
3243         | COMMA error
3244           {
3245                 report.Error (839, GetLocation ($1), "An argument is missing");
3246                 $$ = null;
3247           }
3248         ;
3249
3250 argument
3251         : expression
3252           {
3253                 $$ = new Argument ((Expression) $1);
3254           }
3255         | non_simple_argument
3256         ;
3257
3258 argument_or_named_argument
3259         : argument
3260         | named_argument
3261         ;
3262
3263 non_simple_argument
3264         : REF variable_reference 
3265           { 
3266                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3267                 lbag.AddLocation ($$, GetLocation ($1));
3268           }
3269         | OUT variable_reference 
3270           { 
3271                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
3272                 lbag.AddLocation ($$, GetLocation ($1));
3273           }
3274         | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
3275           {
3276                 $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1)));
3277                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3278           }
3279         | ARGLIST OPEN_PARENS CLOSE_PARENS
3280           {
3281                 $$ = new Argument (new Arglist (GetLocation ($1)));
3282                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
3283           }       
3284         ;
3285
3286 variable_reference
3287         : expression
3288         ;
3289
3290 element_access
3291         : primary_expression OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET  
3292           {
3293                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
3294                 lbag.AddLocation ($$, GetLocation ($4));
3295           }
3296         | primary_expression OPEN_BRACKET_EXPR expression_list_arguments error
3297           {
3298                 Error_SyntaxError (yyToken);
3299                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
3300           }
3301         | primary_expression OPEN_BRACKET_EXPR error
3302           {
3303                 Error_SyntaxError (yyToken);
3304                 $$ = new ElementAccess ((Expression) $1, null, GetLocation ($2));
3305           }
3306         ;
3307
3308 expression_list
3309         : expression
3310           {
3311                 var list = new List<Expression> (4);
3312                 list.Add ((Expression) $1);
3313                 $$ = list;
3314           }
3315         | expression_list COMMA expression
3316           {
3317                 var list = (List<Expression>) $1;
3318                 list.Add ((Expression) $3);
3319                 $$ = list;
3320           }
3321         | expression_list error {
3322                 Error_SyntaxError (yyToken);
3323                 $$ = $1;
3324           }
3325         ;
3326         
3327 expression_list_arguments
3328         : expression_list_argument
3329           {
3330                 Arguments args = new Arguments (4);
3331                 args.Add ((Argument) $1);
3332                 $$ = args;
3333           }
3334         | expression_list_arguments COMMA expression_list_argument
3335           {
3336                 Arguments args = (Arguments) $1;
3337                 if (args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
3338                         Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
3339           
3340                 args.Add ((Argument) $3);
3341                 $$ = args;        
3342           }
3343         ;
3344         
3345 expression_list_argument
3346         : expression
3347           {
3348                 $$ = new Argument ((Expression) $1);
3349           }
3350         | named_argument
3351         ;
3352
3353 this_access
3354         : THIS
3355           {
3356                 $$ = new This (GetLocation ($1));
3357           }
3358         ;
3359
3360 base_access
3361         : BASE OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
3362           {
3363                 $$ = new ElementAccess (new BaseThis (GetLocation ($1)), (Arguments) $3, GetLocation ($2));
3364                 lbag.AddLocation ($$, GetLocation ($4));
3365           }
3366         | BASE OPEN_BRACKET error
3367           {
3368                 Error_SyntaxError (yyToken);
3369                 $$ = new ElementAccess (null, null, GetLocation ($2));
3370           }
3371         ;
3372
3373 post_increment_expression
3374         : primary_expression OP_INC
3375           {
3376                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1, GetLocation ($2));
3377           }
3378         ;
3379
3380 post_decrement_expression
3381         : primary_expression OP_DEC
3382           {
3383                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1, GetLocation ($2));
3384           }
3385         ;
3386         
3387 object_or_delegate_creation_expression
3388         : NEW new_expr_type open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer
3389           {
3390                 if ($6 != null) {
3391                         if (lang_version <= LanguageVersion.ISO_2)
3392                                 FeatureIsNotAvailable (GetLocation ($1), "object initializers");
3393                                 
3394                         $$ = new NewInitialize ((FullNamedExpression) $2, (Arguments) $4, (CollectionOrObjectInitializers) $6, GetLocation ($1));
3395                 } else {
3396                         $$ = new New ((FullNamedExpression) $2, (Arguments) $4, GetLocation ($1));
3397                 }
3398                 
3399                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3400           }
3401         | NEW new_expr_type object_or_collection_initializer
3402           {
3403                 if (lang_version <= LanguageVersion.ISO_2)
3404                         FeatureIsNotAvailable (GetLocation ($1), "collection initializers");
3405           
3406                 $$ = new NewInitialize ((FullNamedExpression) $2, null, (CollectionOrObjectInitializers) $3, GetLocation ($1));
3407           }
3408         ;
3409
3410 array_creation_expression
3411         : NEW new_expr_type OPEN_BRACKET_EXPR expression_list CLOSE_BRACKET
3412           opt_rank_specifier
3413           opt_array_initializer
3414           {
3415                 $$ = new ArrayCreation ((FullNamedExpression) $2, (List<Expression>) $4,
3416                                 new ComposedTypeSpecifier (((List<Expression>) $4).Count, GetLocation ($3)) {
3417                                         Next = (ComposedTypeSpecifier) $6
3418                                 }, (ArrayInitializer) $7, GetLocation ($1));
3419                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3420           }
3421         | NEW new_expr_type rank_specifiers opt_array_initializer
3422           {
3423                 if ($4 == null)
3424                         report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer");
3425
3426                 $$ = new ArrayCreation ((FullNamedExpression) $2, (ComposedTypeSpecifier) $3, (ArrayInitializer) $4, GetLocation ($1));
3427           }
3428         | NEW rank_specifier array_initializer
3429           {
3430                 if (lang_version <= LanguageVersion.ISO_2)
3431                         FeatureIsNotAvailable (GetLocation ($1), "implicitly typed arrays");
3432           
3433                 $$ = new ImplicitlyTypedArrayCreation ((ComposedTypeSpecifier) $2, (ArrayInitializer) $3, GetLocation ($1));
3434           }
3435         | NEW new_expr_type OPEN_BRACKET CLOSE_BRACKET OPEN_BRACKET_EXPR error CLOSE_BRACKET
3436           {
3437                 report.Error (178, GetLocation ($6), "Invalid rank specifier, expecting `,' or `]'");
3438                 $$ = new ArrayCreation ((FullNamedExpression) $2, null, GetLocation ($1));
3439           }
3440         | NEW new_expr_type error
3441           {
3442                 Error_SyntaxError (yyToken);
3443                 // It can be any of new expression, create the most common one
3444                 $$ = new New ((FullNamedExpression) $2, null, GetLocation ($1));
3445           }
3446         ;
3447
3448 new_expr_type
3449         : {
3450                 ++lexer.parsing_type;
3451           }
3452           simple_type
3453           {
3454                 --lexer.parsing_type;
3455                 $$ = $2;
3456           }
3457         ;
3458
3459 anonymous_type_expression
3460         : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
3461           {
3462                 if (lang_version <= LanguageVersion.ISO_2)
3463                         FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
3464
3465                 $$ = new NewAnonymousType ((List<AnonymousTypeParameter>) $3, current_container, GetLocation ($1));
3466                 
3467                 // TODO: lbag comma location
3468                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3469           }
3470         ;
3471
3472 anonymous_type_parameters_opt_comma
3473         : anonymous_type_parameters_opt
3474         | anonymous_type_parameters COMMA
3475         ;
3476
3477 anonymous_type_parameters_opt
3478         : { $$ = null; }
3479         | anonymous_type_parameters
3480         ;
3481
3482 anonymous_type_parameters
3483         : anonymous_type_parameter
3484           {
3485                 var a = new List<AnonymousTypeParameter> (4);
3486                 a.Add ((AnonymousTypeParameter) $1);
3487                 $$ = a;
3488           }
3489         | anonymous_type_parameters COMMA anonymous_type_parameter
3490           {
3491                 var a = (List<AnonymousTypeParameter>) $1;
3492                 a.Add ((AnonymousTypeParameter) $3);
3493                 $$ = a;
3494           }
3495         ;
3496
3497 anonymous_type_parameter
3498         : IDENTIFIER ASSIGN variable_initializer
3499           {
3500                 var lt = (Tokenizer.LocatedToken)$1;
3501                 $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
3502                 lbag.AddLocation ($$, GetLocation ($2));
3503           }
3504         | IDENTIFIER
3505           {
3506                 var lt = (Tokenizer.LocatedToken)$1;
3507                 $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
3508                         lt.Value, lt.Location);
3509           }
3510         | member_access
3511           {
3512                 MemberAccess ma = (MemberAccess) $1;
3513                 $$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
3514           }
3515         | error
3516           {
3517                 report.Error (746, lexer.Location,
3518                         "Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression");
3519                 $$ = null;
3520           }
3521         ;
3522
3523 opt_rank_specifier
3524         : /* empty */
3525         | rank_specifiers
3526         ;
3527
3528 rank_specifiers
3529         : rank_specifier
3530         | rank_specifier rank_specifiers
3531           {
3532                 ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
3533                 $$ = $1;
3534           }
3535         ;
3536
3537 rank_specifier
3538         : OPEN_BRACKET CLOSE_BRACKET
3539           {
3540                 $$ = ComposedTypeSpecifier.CreateArrayDimension (1, GetLocation ($1));
3541                 lbag.AddLocation ($$, GetLocation ($2));
3542           }
3543         | OPEN_BRACKET dim_separators CLOSE_BRACKET
3544           {
3545                 $$ = ComposedTypeSpecifier.CreateArrayDimension ((int)$2, GetLocation ($1));
3546                 lbag.AddLocation ($$, GetLocation ($3));
3547           }
3548         ;
3549
3550 dim_separators
3551         : COMMA
3552           {
3553                 $$ = 2;
3554           }
3555         | dim_separators COMMA
3556           {
3557                 $$ = ((int) $1) + 1;
3558           }
3559         ;
3560
3561 opt_array_initializer
3562         : /* empty */
3563           {
3564                 $$ = null;
3565           }
3566         | array_initializer
3567           {
3568                 $$ = $1;
3569           }
3570         ;
3571
3572 array_initializer
3573         : OPEN_BRACE CLOSE_BRACE
3574           {
3575                 var ai = new ArrayInitializer (0, GetLocation ($1));
3576                 ai.VariableDeclaration = current_variable;
3577                 lbag.AddLocation (ai, GetLocation ($2));
3578                 $$ = ai;
3579           }
3580         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
3581           {
3582                 var ai = new ArrayInitializer ((List<Expression>) $2, GetLocation ($1));
3583                 ai.VariableDeclaration = current_variable;
3584                 if ($3 != null) {
3585                         lbag.AddLocation (ai, GetLocation ($3), GetLocation ($4));
3586                 } else {
3587                         lbag.AddLocation (ai, GetLocation ($4));
3588                 }
3589                 $$ = ai;
3590           }
3591         ;
3592
3593 variable_initializer_list
3594         : variable_initializer
3595           {
3596                 var list = new List<Expression> (4);
3597                 list.Add ((Expression) $1);
3598                 $$ = list;
3599           }
3600         | variable_initializer_list COMMA variable_initializer
3601           {
3602                 var list = (List<Expression>) $1;
3603                 list.Add ((Expression) $3);
3604                 $$ = list;
3605           }
3606         ;
3607
3608 typeof_expression
3609         : TYPEOF
3610       {
3611                 lexer.TypeOfParsing = true;
3612           }
3613           open_parens_any typeof_type_expression CLOSE_PARENS
3614           {
3615                 lexer.TypeOfParsing = false;
3616                 $$ = new TypeOf ((FullNamedExpression) $4, GetLocation ($1));
3617                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3618           }
3619         ;
3620         
3621 typeof_type_expression
3622         : type_and_void
3623         | unbound_type_name
3624         | error
3625          {
3626                 Error_TypeExpected (lexer.Location);
3627                 $$ = null;
3628          }
3629         ;
3630         
3631 unbound_type_name
3632         : identifier_inside_body generic_dimension
3633           {  
3634                 var lt = (Tokenizer.LocatedToken) $1;
3635
3636                 $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
3637           }
3638         | qualified_alias_member identifier_inside_body generic_dimension
3639           {
3640                 var lt1 = (Tokenizer.LocatedToken) $1;
3641                 var lt2 = (Tokenizer.LocatedToken) $2;
3642
3643                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
3644                 lbag.AddLocation ($$, GetLocation ($2));
3645           }
3646         | unbound_type_name DOT identifier_inside_body
3647           {
3648                 var lt = (Tokenizer.LocatedToken) $3;
3649                 
3650                 $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);         
3651           }
3652         | unbound_type_name DOT identifier_inside_body generic_dimension
3653           {
3654                 var lt = (Tokenizer.LocatedToken) $3;
3655                 
3656                 $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);               
3657           }
3658         | namespace_or_type_expr DOT identifier_inside_body generic_dimension
3659           {
3660                 var tne = (ATypeNameExpression) $1;
3661                 if (tne.HasTypeArguments)
3662                         Error_TypeExpected (GetLocation ($4));
3663
3664                 var lt = (Tokenizer.LocatedToken) $3;
3665                 $$ = new MemberAccess (tne, lt.Value, (int) $4, lt.Location);           
3666           }
3667         ;
3668
3669 generic_dimension
3670         : GENERIC_DIMENSION
3671           {
3672                 if (lang_version < LanguageVersion.ISO_2)
3673                         FeatureIsNotAvailable (GetLocation ($1), "generics");
3674
3675                 $$ = $1;
3676           }
3677         ;
3678         
3679 qualified_alias_member
3680         : IDENTIFIER DOUBLE_COLON
3681           {
3682                 var lt = (Tokenizer.LocatedToken) $1;
3683                 if (lang_version == LanguageVersion.ISO_1)
3684                         FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
3685
3686                 $$ = lt;                
3687           }
3688         ;
3689
3690 sizeof_expression
3691         : SIZEOF open_parens_any type CLOSE_PARENS
3692           { 
3693                 $$ = new SizeOf ((Expression) $3, GetLocation ($1));
3694                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3695           }
3696         ;
3697
3698 checked_expression
3699         : CHECKED open_parens_any expression CLOSE_PARENS
3700           {
3701                 $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
3702                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3703           }
3704         ;
3705
3706 unchecked_expression
3707         : UNCHECKED open_parens_any expression CLOSE_PARENS
3708           {
3709                 $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
3710                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3711           }
3712         ;
3713
3714 pointer_member_access
3715         : primary_expression OP_PTR IDENTIFIER opt_type_argument_list
3716           {
3717                 var lt = (Tokenizer.LocatedToken) $3;
3718                 $$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, (TypeArguments) $4, lt.Location);
3719           }
3720         ;
3721
3722 anonymous_method_expression
3723         : DELEGATE opt_anonymous_method_signature
3724           {
3725                 start_anonymous (false, (ParametersCompiled) $2, false, GetLocation ($1));
3726           }
3727           block
3728           {
3729                 $$ = end_anonymous ((ParametersBlock) $4);
3730           }
3731         | ASYNC DELEGATE opt_anonymous_method_signature
3732           {
3733                 start_anonymous (false, (ParametersCompiled) $3, true, GetLocation ($1));
3734           }
3735           block
3736           {
3737                 $$ = end_anonymous ((ParametersBlock) $5);
3738           }
3739         ;
3740
3741 opt_anonymous_method_signature
3742         : 
3743           {
3744                 $$ = ParametersCompiled.Undefined;
3745           } 
3746         | anonymous_method_signature
3747         ;
3748
3749 anonymous_method_signature
3750         : OPEN_PARENS
3751           {
3752                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
3753           }
3754           opt_formal_parameter_list CLOSE_PARENS
3755           {
3756                 valid_param_mod = 0;
3757                 $$ = $3;
3758           }
3759         ;
3760
3761 default_value_expression
3762         : DEFAULT open_parens_any type CLOSE_PARENS
3763           {
3764                 if (lang_version < LanguageVersion.ISO_2)
3765                         FeatureIsNotAvailable (GetLocation ($1), "default value expression");
3766
3767                 $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1));
3768                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3769           }
3770         ;
3771
3772 unary_expression
3773         : primary_expression
3774         | BANG prefixed_unary_expression
3775           {
3776                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1));
3777           }
3778         | TILDE prefixed_unary_expression
3779           {
3780                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
3781           }
3782         | OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
3783           {
3784                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3785                 lbag.AddLocation ($$, GetLocation ($3));
3786           }
3787         | AWAIT prefixed_unary_expression
3788           {
3789                 if (!async_block) {
3790                          if (current_anonymous_method is LambdaExpression) {
3791                                 report.Error (4034, GetLocation ($1),
3792                                         "The `await' operator can only be used when its containing lambda expression is marked with the `async' modifier");
3793                         } else if (current_anonymous_method is AnonymousMethodExpression) {
3794                                 report.Error (4035, GetLocation ($1),
3795                                         "The `await' operator can only be used when its containing anonymous method is marked with the `async' modifier");
3796                         } else {
3797                                 report.Error (4033, GetLocation ($1),
3798                                         "The `await' operator can only be used when its containing method is marked with the `async' modifier");
3799                         }
3800                 } else {
3801                         current_block.Explicit.RegisterAsyncAwait ();
3802                 }
3803                 
3804                 $$ = new Await ((Expression) $2, GetLocation ($1));
3805           }
3806         ;
3807
3808         //
3809         // The idea to split this out is from Rhys' grammar
3810         // to solve the problem with casts.
3811         //
3812 prefixed_unary_expression
3813         : unary_expression
3814         | PLUS prefixed_unary_expression
3815           { 
3816                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
3817           } 
3818         | MINUS prefixed_unary_expression 
3819           { 
3820                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
3821           }
3822         | OP_INC prefixed_unary_expression 
3823           {
3824                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1));
3825           }
3826         | OP_DEC prefixed_unary_expression 
3827           {
3828                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1));
3829           }
3830         | STAR prefixed_unary_expression
3831           {
3832                 $$ = new Indirection ((Expression) $2, GetLocation ($1));
3833           }
3834         | BITWISE_AND prefixed_unary_expression
3835           {
3836                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1));
3837           }
3838         ;
3839
3840 multiplicative_expression
3841         : prefixed_unary_expression
3842         | multiplicative_expression STAR prefixed_unary_expression
3843           {
3844                 $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
3845                 lbag.AddLocation ($$, GetLocation ($2));
3846           }
3847         | multiplicative_expression DIV prefixed_unary_expression
3848           {
3849                 $$ = new Binary (Binary.Operator.Division, (Expression) $1, (Expression) $3);
3850                 lbag.AddLocation ($$, GetLocation ($2));
3851           }
3852         | multiplicative_expression PERCENT prefixed_unary_expression 
3853           {
3854                 $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
3855                 lbag.AddLocation ($$, GetLocation ($2));
3856           }
3857         ;
3858
3859 additive_expression
3860         : multiplicative_expression
3861         | additive_expression PLUS multiplicative_expression 
3862           {
3863                 $$ = new Binary (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
3864                 lbag.AddLocation ($$, GetLocation ($2));
3865           }
3866         | additive_expression MINUS multiplicative_expression
3867           {
3868                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
3869                 lbag.AddLocation ($$, GetLocation ($2));
3870           }
3871         | additive_expression AS type
3872           {
3873                 $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
3874           }
3875         | additive_expression IS type
3876           {
3877                 $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
3878           }       
3879         ;
3880
3881 shift_expression
3882         : additive_expression
3883         | shift_expression OP_SHIFT_LEFT additive_expression
3884           {
3885                 $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
3886                 lbag.AddLocation ($$, GetLocation ($2));
3887           }
3888         | shift_expression OP_SHIFT_RIGHT additive_expression
3889           {
3890                 $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
3891                 lbag.AddLocation ($$, GetLocation ($2));
3892           }
3893         ; 
3894
3895 relational_expression
3896         : shift_expression
3897         | relational_expression OP_LT shift_expression
3898           {
3899                 $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, (Expression) $3);
3900                 lbag.AddLocation ($$, GetLocation ($2));
3901           }
3902         | relational_expression OP_GT shift_expression
3903           {
3904                 $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, (Expression) $3);
3905                 lbag.AddLocation ($$, GetLocation ($2));
3906           }
3907         | relational_expression OP_LE shift_expression
3908           {
3909                 $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, (Expression) $3);
3910                 lbag.AddLocation ($$, GetLocation ($2));
3911           }
3912         | relational_expression OP_GE shift_expression
3913           {
3914                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3);
3915                 lbag.AddLocation ($$, GetLocation ($2));
3916           }
3917         ;
3918
3919 equality_expression
3920         : relational_expression
3921         | equality_expression OP_EQ relational_expression
3922           {
3923                 $$ = new Binary (Binary.Operator.Equality, (Expression) $1, (Expression) $3);
3924                 lbag.AddLocation ($$, GetLocation ($2));
3925           }
3926         | equality_expression OP_NE relational_expression
3927           {
3928                 $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, (Expression) $3);
3929                 lbag.AddLocation ($$, GetLocation ($2));
3930           }
3931         ; 
3932
3933 and_expression
3934         : equality_expression
3935         | and_expression BITWISE_AND equality_expression
3936           {
3937                 $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
3938                 lbag.AddLocation ($$, GetLocation ($2));
3939           }
3940         ;
3941
3942 exclusive_or_expression
3943         : and_expression
3944         | exclusive_or_expression CARRET and_expression
3945           {
3946                 $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
3947                 lbag.AddLocation ($$, GetLocation ($2));
3948           }
3949         ;
3950
3951 inclusive_or_expression
3952         : exclusive_or_expression
3953         | inclusive_or_expression BITWISE_OR exclusive_or_expression
3954           {
3955                 $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
3956                 lbag.AddLocation ($$, GetLocation ($2));
3957           }
3958         ;
3959
3960 conditional_and_expression
3961         : inclusive_or_expression
3962         | conditional_and_expression OP_AND inclusive_or_expression
3963           {
3964                 $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3);
3965                 lbag.AddLocation ($$, GetLocation ($2));
3966           }
3967         ;
3968
3969 conditional_or_expression
3970         : conditional_and_expression
3971         | conditional_or_expression OP_OR conditional_and_expression
3972           {
3973                 $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3);
3974                 lbag.AddLocation ($$, GetLocation ($2));
3975           }
3976         ;
3977         
3978 null_coalescing_expression
3979         : conditional_or_expression
3980         | conditional_or_expression OP_COALESCING null_coalescing_expression
3981           {
3982                 if (lang_version < LanguageVersion.ISO_2)
3983                         FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
3984                         
3985                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3);
3986                 lbag.AddLocation ($$, GetLocation ($2));
3987           }
3988         ;
3989
3990 conditional_expression
3991         : null_coalescing_expression
3992         | null_coalescing_expression INTERR expression COLON expression_or_error
3993           {
3994                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
3995                 lbag.AddLocation ($$, GetLocation ($4));
3996           }
3997         | null_coalescing_expression INTERR expression error
3998           {
3999                 Error_SyntaxError (yyToken);
4000                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
4001           }
4002         ;
4003
4004 assignment_expression
4005         : prefixed_unary_expression ASSIGN expression
4006           {
4007                 $$ = new SimpleAssign ((Expression) $1, (Expression) $3);
4008                 lbag.AddLocation ($$, GetLocation ($2));
4009           }
4010         | prefixed_unary_expression OP_MULT_ASSIGN expression
4011           {
4012                 $$ = new CompoundAssign (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
4013                 lbag.AddLocation ($$, GetLocation ($2));
4014           }
4015         | prefixed_unary_expression OP_DIV_ASSIGN expression
4016           {
4017                 $$ = new CompoundAssign (Binary.Operator.Division, (Expression) $1, (Expression) $3);
4018                 lbag.AddLocation ($$, GetLocation ($2));
4019           }
4020         | prefixed_unary_expression OP_MOD_ASSIGN expression
4021           {
4022                 $$ = new CompoundAssign (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
4023                 lbag.AddLocation ($$, GetLocation ($2));
4024           }
4025         | prefixed_unary_expression OP_ADD_ASSIGN expression
4026           {
4027                 $$ = new CompoundAssign (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
4028                 lbag.AddLocation ($$, GetLocation ($2));
4029           }
4030         | prefixed_unary_expression OP_SUB_ASSIGN expression
4031           {
4032                 $$ = new CompoundAssign (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
4033                 lbag.AddLocation ($$, GetLocation ($2));
4034           }
4035         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
4036           {
4037                 $$ = new CompoundAssign (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
4038                 lbag.AddLocation ($$, GetLocation ($2));
4039           }
4040         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
4041           {
4042                 $$ = new CompoundAssign (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
4043                 lbag.AddLocation ($$, GetLocation ($2));
4044           }
4045         | prefixed_unary_expression OP_AND_ASSIGN expression
4046           {
4047                 $$ = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
4048                 lbag.AddLocation ($$, GetLocation ($2));
4049           }
4050         | prefixed_unary_expression OP_OR_ASSIGN expression
4051           {
4052                 $$ = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
4053                 lbag.AddLocation ($$, GetLocation ($2));
4054           }
4055         | prefixed_unary_expression OP_XOR_ASSIGN expression
4056           {
4057                 $$ = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
4058                 lbag.AddLocation ($$, GetLocation ($2));
4059           }
4060         ;
4061
4062 lambda_parameter_list
4063         : lambda_parameter
4064           {
4065                 var pars = new List<Parameter> (4);
4066                 pars.Add ((Parameter) $1);
4067
4068                 $$ = pars;
4069           }
4070         | lambda_parameter_list COMMA lambda_parameter
4071           {
4072                 var pars = (List<Parameter>) $1;
4073                 Parameter p = (Parameter)$3;
4074                 if (pars[0].GetType () != p.GetType ()) {
4075                         report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
4076                 }
4077                 
4078                 pars.Add (p);
4079                 $$ = pars;
4080           }
4081         ;
4082
4083 lambda_parameter
4084         : parameter_modifier parameter_type identifier_inside_body
4085           {
4086                 var lt = (Tokenizer.LocatedToken) $3;
4087
4088                 $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
4089           }
4090         | parameter_type identifier_inside_body
4091           {
4092                 var lt = (Tokenizer.LocatedToken) $2;
4093
4094                 $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
4095           }
4096         | IDENTIFIER
4097           {
4098                 var lt = (Tokenizer.LocatedToken) $1;
4099                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
4100           }
4101         ;
4102
4103 opt_lambda_parameter_list
4104         : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
4105         | lambda_parameter_list         { 
4106                 var pars_list = (List<Parameter>) $1;
4107                 $$ = new ParametersCompiled (pars_list.ToArray ());
4108           }
4109         ;
4110
4111 lambda_expression_body
4112         : lambda_expression_body_simple
4113         | block
4114         ;
4115         
4116 lambda_expression_body_simple
4117         : {
4118                 start_block (Location.Null);
4119           }
4120           expression_or_error   // Have to close block when error occurs
4121           {
4122                 Block b = end_block (Location.Null);
4123                 b.IsCompilerGenerated = true;
4124                 b.AddStatement (new ContextualReturn ((Expression) $2));
4125                 $$ = b;
4126           } 
4127         ;
4128         
4129 expression_or_error
4130         : expression
4131         | error
4132           {
4133                 Error_SyntaxError (yyToken);    
4134                 $$ = EmptyExpression.Null;
4135           }
4136         ;
4137
4138 lambda_expression
4139         : IDENTIFIER ARROW 
4140           {
4141                 var lt = (Tokenizer.LocatedToken) $1;   
4142                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4143                 start_anonymous (true, new ParametersCompiled (p), false, lt.Location);
4144           }
4145           lambda_expression_body
4146           {
4147                 $$ = end_anonymous ((ParametersBlock) $4);
4148                 lbag.AddLocation ($$, GetLocation ($2));
4149           }
4150         | ASYNC identifier_inside_body ARROW
4151           {
4152                 var lt = (Tokenizer.LocatedToken) $2;
4153                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4154                 start_anonymous (true, new ParametersCompiled (p), true, lt.Location);
4155           }
4156           lambda_expression_body
4157           {
4158                 $$ = end_anonymous ((ParametersBlock) $5);
4159                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
4160           }
4161         | OPEN_PARENS_LAMBDA
4162           {
4163                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
4164           }
4165           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4166           {
4167                 valid_param_mod = 0;
4168                 start_anonymous (true, (ParametersCompiled) $3, false, GetLocation ($1));
4169           }
4170           lambda_expression_body
4171           {
4172                 $$ = end_anonymous ((ParametersBlock) $7);
4173                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($4), GetLocation ($5));
4174           }
4175         | ASYNC OPEN_PARENS_LAMBDA
4176           {
4177                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;          
4178           }
4179           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4180           {
4181                 valid_param_mod = 0;
4182                 start_anonymous (true, (ParametersCompiled) $4, true, GetLocation ($1));
4183           }
4184           lambda_expression_body
4185           {
4186                 $$ = end_anonymous ((ParametersBlock) $8);
4187                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($5), GetLocation ($6));
4188           }
4189         ;
4190
4191 expression
4192         : assignment_expression 
4193         | non_assignment_expression
4194         ;
4195         
4196 non_assignment_expression
4197         : conditional_expression
4198         | lambda_expression
4199         | query_expression
4200         | ARGLIST
4201           {
4202                 $$ = new ArglistAccess (GetLocation ($1));
4203           }
4204         ;
4205         
4206 undocumented_expressions
4207         : REFVALUE OPEN_PARENS non_assignment_expression COMMA type CLOSE_PARENS
4208           {
4209                 $$ = new RefValueExpr ((Expression) $3, (FullNamedExpression) $5, GetLocation ($1));
4210                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
4211           }
4212         | REFTYPE open_parens_any expression CLOSE_PARENS
4213           {
4214                 $$ = new RefTypeExpr ((Expression) $3, GetLocation ($1));
4215                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
4216           }
4217         | MAKEREF open_parens_any expression CLOSE_PARENS
4218           {
4219                 $$ = new MakeRefExpr ((Expression) $3, GetLocation ($1));
4220                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));        
4221           }
4222         ;
4223
4224 constant_expression
4225         : expression
4226         ;
4227
4228 boolean_expression
4229         : expression
4230           {
4231                 $$ = new BooleanExpression ((Expression) $1);
4232           }
4233         ;
4234
4235 //
4236 // 10 classes
4237 //
4238 class_declaration
4239         : opt_attributes
4240           opt_modifiers
4241           opt_partial
4242           CLASS
4243           {
4244                 lexer.ConstraintsParsing = true;
4245           }
4246           type_declaration_name
4247           {
4248                 Class c = new Class (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1);
4249                 if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) {
4250                         FeatureIsNotAvailable (c.Location, "static classes");
4251                 }
4252                         
4253                 push_current_container (c, $3);
4254           }
4255           opt_class_base
4256           opt_type_parameter_constraints_clauses
4257           {
4258                 lexer.ConstraintsParsing = false;
4259
4260                 if ($9 != null)
4261                         current_container.SetConstraints ((List<Constraints>) $9);
4262                 lbag.AddMember (current_container, mod_locations, GetLocation ($4));
4263
4264                 if (doc_support) {
4265                         current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
4266                         Lexer.doc_state = XmlCommentState.Allowed;
4267                 }
4268                 
4269                 lexer.parsing_modifiers = true;
4270           }
4271           OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
4272           {
4273                 --lexer.parsing_declaration;
4274                 if (doc_support)
4275                         Lexer.doc_state = XmlCommentState.Allowed;
4276           }
4277           opt_semicolon 
4278           {
4279                 lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13), GetLocation ($15));
4280                 $$ = pop_current_class ();
4281           }
4282         ;       
4283
4284 opt_partial
4285         : /* empty */
4286           { $$ = null; }
4287         | PARTIAL
4288           { $$ = $1; } // location
4289         ;
4290
4291 opt_modifiers
4292         : /* empty */
4293           {
4294             mod_locations = null;
4295                 $$ = ModifierNone;
4296                 lexer.parsing_modifiers = false;
4297           }
4298         | modifiers
4299           {
4300                 lexer.parsing_modifiers = false;                
4301           }
4302         ;
4303
4304 modifiers
4305         : modifier
4306         | modifiers modifier
4307           { 
4308                 var m1 = (Modifiers) $1;
4309                 var m2 = (Modifiers) $2;
4310
4311                 if ((m1 & m2) != 0) {
4312                         report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length,
4313                                 "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2));
4314                 } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 &&
4315                         ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) {
4316                         report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length,
4317                                 "More than one protection modifier specified");
4318                 }
4319                 
4320                 $$ = m1 | m2;
4321           }
4322         ;
4323
4324 modifier
4325         : NEW
4326           {
4327                 $$ = Modifiers.NEW;
4328                 StoreModifierLocation ($$, GetLocation ($1));
4329                 
4330                 if (current_container.Kind == MemberKind.Namespace)
4331                         report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements");
4332           }
4333         | PUBLIC
4334           {
4335                 $$ = Modifiers.PUBLIC;
4336                 StoreModifierLocation ($$, GetLocation ($1));
4337           }
4338         | PROTECTED
4339           {
4340                 $$ = Modifiers.PROTECTED;
4341                 StoreModifierLocation ($$, GetLocation ($1));
4342           }
4343         | INTERNAL
4344           {
4345                 $$ = Modifiers.INTERNAL;
4346                 StoreModifierLocation ($$, GetLocation ($1));
4347           }
4348         | PRIVATE
4349           {
4350                 $$ = Modifiers.PRIVATE;
4351                 StoreModifierLocation ($$, GetLocation ($1));
4352           }
4353         | ABSTRACT
4354           {
4355                 $$ = Modifiers.ABSTRACT;
4356                 StoreModifierLocation ($$, GetLocation ($1));
4357           }
4358         | SEALED
4359           {
4360                 $$ = Modifiers.SEALED;
4361                 StoreModifierLocation ($$, GetLocation ($1));
4362           }
4363         | STATIC
4364           {
4365                 $$ = Modifiers.STATIC;
4366                 StoreModifierLocation ($$, GetLocation ($1));
4367           }
4368         | READONLY
4369           {
4370                 $$ = Modifiers.READONLY;
4371                 StoreModifierLocation ($$, GetLocation ($1));
4372           }
4373         | VIRTUAL
4374           {
4375                 $$ = Modifiers.VIRTUAL;
4376                 StoreModifierLocation ($$, GetLocation ($1));
4377           }
4378         | OVERRIDE
4379           {
4380                 $$ = Modifiers.OVERRIDE;
4381                 StoreModifierLocation ($$, GetLocation ($1));
4382           }
4383         | EXTERN
4384           {
4385                 $$ = Modifiers.EXTERN;
4386                 StoreModifierLocation ($$, GetLocation ($1));
4387           }
4388         | VOLATILE
4389           {
4390                 $$ = Modifiers.VOLATILE;
4391                 StoreModifierLocation ($$, GetLocation ($1));
4392           }
4393         | UNSAFE
4394           {
4395                 $$ = Modifiers.UNSAFE;
4396                 StoreModifierLocation ($$, GetLocation ($1));
4397                 if (!settings.Unsafe)
4398                         Error_UnsafeCodeNotAllowed (GetLocation ($1));
4399           }
4400         | ASYNC
4401           {
4402                 $$ = Modifiers.ASYNC;
4403                 StoreModifierLocation ($$, GetLocation ($1));
4404           }
4405         ;
4406         
4407 opt_class_base
4408         : /* empty */
4409         | COLON type_list
4410          {
4411                 current_type.AddBasesForPart ((List<FullNamedExpression>) $2);
4412          }
4413         | COLON type_list error
4414           {
4415                 Error_SyntaxError (yyToken);
4416
4417                 current_type.AddBasesForPart ((List<FullNamedExpression>) $2);
4418           }
4419         ;
4420
4421 opt_type_parameter_constraints_clauses
4422         : /* empty */
4423         | type_parameter_constraints_clauses 
4424           {
4425                 $$ = $1;
4426           }
4427         ;
4428
4429 type_parameter_constraints_clauses
4430         : type_parameter_constraints_clause
4431           {
4432                 var constraints = new List<Constraints> (1);
4433                 constraints.Add ((Constraints) $1);
4434                 $$ = constraints;
4435           }
4436         | type_parameter_constraints_clauses type_parameter_constraints_clause
4437           {
4438                 var constraints = (List<Constraints>) $1;
4439                 Constraints new_constraint = (Constraints)$2;
4440
4441                 foreach (Constraints c in constraints) {
4442                         if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) {
4443                                 report.Error (409, new_constraint.Location,
4444                                         "A constraint clause has already been specified for type parameter `{0}'",
4445                                         new_constraint.TypeParameter.Value);
4446                         }
4447                 }
4448
4449                 constraints.Add (new_constraint);
4450                 $$ = constraints;
4451           }
4452         ; 
4453
4454 type_parameter_constraints_clause
4455         : WHERE IDENTIFIER COLON type_parameter_constraints
4456           {
4457                 var lt = (Tokenizer.LocatedToken) $2;
4458                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List<FullNamedExpression>) $4, GetLocation ($1));
4459                 lbag.AddLocation ($$, GetLocation ($3));
4460           }
4461         | WHERE IDENTIFIER error
4462           {
4463                 Error_SyntaxError (yyToken);
4464           
4465                 var lt = (Tokenizer.LocatedToken) $2;
4466                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), null, GetLocation ($1));
4467           }
4468         ; 
4469
4470 type_parameter_constraints
4471         : type_parameter_constraint
4472           {
4473                 var constraints = new List<FullNamedExpression> (1);
4474                 constraints.Add ((FullNamedExpression) $1);
4475                 $$ = constraints;
4476           }
4477         | type_parameter_constraints COMMA type_parameter_constraint
4478           {
4479                 var constraints = (List<FullNamedExpression>) $1;
4480                 var prev = constraints [constraints.Count - 1] as SpecialContraintExpr;
4481                 if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) {                   
4482                         report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified");
4483                 }
4484                 
4485                 prev = $3 as SpecialContraintExpr;
4486                 if (prev != null) {
4487                         if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) {
4488                                 report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified");                 
4489                         } else {
4490                                 prev = constraints [0] as SpecialContraintExpr;
4491                                 if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) {                        
4492                                         report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint");
4493                                 }
4494                         }
4495                 }
4496
4497                 constraints.Add ((FullNamedExpression) $3);
4498                 $$ = constraints;
4499           }
4500         ;
4501
4502 type_parameter_constraint
4503         : type
4504           {
4505                 if ($1 is ComposedCast)
4506                         report.Error (706, GetLocation ($1), "Invalid constraint type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
4507           
4508                 $$ = $1;
4509           }
4510         | NEW OPEN_PARENS CLOSE_PARENS
4511           {
4512                 $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1));
4513                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
4514           }
4515         | CLASS
4516           {
4517                 $$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1));
4518           }
4519         | STRUCT
4520           {
4521                 $$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1));
4522           }
4523         ;
4524
4525 opt_type_parameter_variance
4526         : /* empty */
4527           {
4528                 $$ = Variance.None;
4529           }
4530         | type_parameter_variance
4531           {
4532                 if (lang_version <= LanguageVersion.V_3)
4533                         FeatureIsNotAvailable (lexer.Location, "generic type variance");
4534                 
4535                 $$ = $1;
4536           }
4537         ;
4538
4539 type_parameter_variance
4540         : OUT
4541           {
4542                 $$ = Variance.Covariant;
4543           }
4544         | IN
4545           {
4546                 $$ = Variance.Contravariant;
4547           }
4548         ;
4549
4550 //
4551 // Statements (8.2)
4552 //
4553
4554 //
4555 // A block is "contained" on the following places:
4556 //      method_body
4557 //      property_declaration as part of the accessor body (get/set)
4558 //      operator_declaration
4559 //      constructor_declaration
4560 //      destructor_declaration
4561 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
4562 //      
4563 block
4564         : OPEN_BRACE  
4565           {
4566                 ++lexer.parsing_block;
4567                 start_block (GetLocation ($1));
4568           } 
4569           opt_statement_list block_end
4570           {
4571                 $$ = $4;
4572           }
4573         ;
4574
4575 block_end 
4576         : CLOSE_BRACE 
4577           {
4578                 --lexer.parsing_block;
4579                 $$ = end_block (GetLocation ($1));
4580           }
4581         | COMPLETE_COMPLETION
4582           {
4583                 --lexer.parsing_block;
4584                 $$ = end_block (lexer.Location);
4585           }
4586         ;
4587
4588
4589 block_prepared
4590         : OPEN_BRACE
4591           {
4592                 ++lexer.parsing_block;
4593                 current_block.StartLocation = GetLocation ($1);
4594           }
4595           opt_statement_list CLOSE_BRACE 
4596           {
4597                 --lexer.parsing_block;
4598                 $$ = end_block (GetLocation ($4));
4599           }
4600         ;
4601
4602 opt_statement_list
4603         : /* empty */
4604         | statement_list 
4605         ;
4606
4607 statement_list
4608         : statement
4609         | statement_list statement
4610         ;
4611
4612 statement
4613         : block_variable_declaration
4614           {
4615                 current_block.AddStatement ((Statement) $1);
4616           }
4617         | valid_declaration_statement
4618           {
4619                 current_block.AddStatement ((Statement) $1);
4620           }
4621         | labeled_statement
4622         | error
4623           {
4624                 Error_SyntaxError (yyToken);
4625                 $$ = null;
4626           }
4627         ;
4628
4629 //
4630 // The interactive_statement and its derivatives are only 
4631 // used to provide a special version of `expression_statement'
4632 // that has a side effect of assigning the expression to
4633 // $retval
4634 //
4635 interactive_statement_list
4636         : interactive_statement
4637         | interactive_statement_list interactive_statement
4638         ;
4639
4640 interactive_statement
4641         : block_variable_declaration
4642           {
4643                 current_block.AddStatement ((Statement) $1);
4644           }
4645         | interactive_valid_declaration_statement
4646           {
4647                 current_block.AddStatement ((Statement) $1);
4648           }
4649         | labeled_statement
4650         ;
4651
4652 valid_declaration_statement
4653         : block
4654         | empty_statement
4655         | expression_statement
4656         | selection_statement
4657         | iteration_statement
4658         | jump_statement                  
4659         | try_statement
4660         | checked_statement
4661         | unchecked_statement
4662         | lock_statement
4663         | using_statement
4664         | unsafe_statement
4665         | fixed_statement
4666         ;
4667
4668 interactive_valid_declaration_statement
4669         : block
4670         | empty_statement
4671         | interactive_expression_statement
4672         | selection_statement
4673         | iteration_statement
4674         | jump_statement                  
4675         | try_statement
4676         | checked_statement
4677         | unchecked_statement
4678         | lock_statement
4679         | using_statement
4680         | unsafe_statement
4681         | fixed_statement
4682         ;
4683
4684 embedded_statement
4685         : valid_declaration_statement
4686         | block_variable_declaration
4687           {
4688                   report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4689                   $$ = null;
4690           }
4691         | labeled_statement
4692           {
4693                   report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4694                   $$ = null;
4695           }
4696         | error
4697           {
4698                 Error_SyntaxError (yyToken);
4699                 $$ = new EmptyStatement (GetLocation ($1));
4700           }
4701         ;
4702
4703 empty_statement
4704         : SEMICOLON
4705           {
4706                 // Uses lexer.Location because semicolon location is not kept in quick mode
4707                 $$ = new EmptyStatement (lexer.Location);
4708           }
4709         ;
4710
4711 labeled_statement
4712         : identifier_inside_body COLON 
4713           {
4714                 var lt = (Tokenizer.LocatedToken) $1;
4715                 LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location);
4716                 lbag.AddLocation (labeled, GetLocation ($2));
4717                 current_block.AddLabel (labeled);
4718                 current_block.AddStatement (labeled);
4719           }
4720           statement
4721         ;
4722
4723 variable_type
4724         : variable_type_simple
4725         | variable_type_simple rank_specifiers
4726           {
4727                 if ($1 is VarExpr)
4728                         $1 = new SimpleName ("var", ((VarExpr) $1).Location);
4729           
4730                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
4731           }
4732         ;
4733
4734 /* 
4735  * The following is from Rhys' grammar:
4736  * > Types in local variable declarations must be recognized as 
4737  * > expressions to prevent reduce/reduce errors in the grammar.
4738  * > The expressions are converted into types during semantic analysis.
4739  */
4740 variable_type_simple
4741         : primary_expression_or_type opt_nullable
4742           { 
4743                 // Ok, the above "primary_expression" is there to get rid of
4744                 // both reduce/reduce and shift/reduces in the grammar, it should
4745                 // really just be "type_name".  If you use type_name, a reduce/reduce
4746                 // creeps up.  If you use namespace_or_type_name (which is all we need
4747                 // really) two shift/reduces appear.
4748                 // 
4749
4750                 // So the super-trick is that primary_expression
4751                 // can only be either a SimpleName or a MemberAccess. 
4752                 // The MemberAccess case arises when you have a fully qualified type-name like :
4753                 // Foo.Bar.Blah i;
4754                 // SimpleName is when you have
4755                 // Blah i;
4756                 
4757                 Expression expr = (Expression) $1;
4758                 if ($2 == null) {
4759                         SimpleName sn = expr as SimpleName;
4760                         if (sn != null && sn.Name == "var")
4761                                 $$ = new VarExpr (sn.Location);
4762                         else
4763                                 $$ = $1;
4764                 } else if (expr is ATypeNameExpression) {
4765                         $$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2);
4766                 } else {
4767                         Error_ExpectingTypeName (expr);
4768                         $$ = null;
4769                 }
4770           }
4771         | primary_expression_or_type pointer_stars
4772           {
4773                 ATypeNameExpression expr = $1 as ATypeNameExpression;
4774
4775                 if (expr != null) {
4776                         $$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2);
4777                 } else {
4778                         Error_ExpectingTypeName ((Expression)$1);
4779                         $$ = expr;
4780                 }
4781           }
4782         | builtin_types opt_nullable
4783           {
4784                 if ($2 == null)
4785                         $$ = $1;
4786                 else
4787                         $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
4788           }
4789         | builtin_types pointer_stars
4790           {
4791                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
4792           }
4793         | VOID pointer_stars
4794           {
4795                 $$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
4796           }       
4797         | VOID
4798           {
4799                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
4800                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
4801           }
4802         ;
4803         
4804 pointer_stars
4805         : pointer_star
4806         | pointer_star pointer_stars
4807           {
4808                 ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
4809                 $$ = $1;
4810           }       
4811         ;
4812
4813 pointer_star
4814         : STAR
4815           {
4816                 $$ = ComposedTypeSpecifier.CreatePointer (GetLocation ($1));
4817           }
4818         ;
4819
4820 identifier_inside_body
4821         : IDENTIFIER
4822         | AWAIT
4823           {
4824                 if (async_block) {
4825                         report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression");
4826                         $$ = new Tokenizer.LocatedToken ("await", GetLocation ($1));
4827                 }
4828           }
4829         ;
4830
4831 block_variable_declaration
4832         : variable_type identifier_inside_body
4833           {
4834                 var lt = (Tokenizer.LocatedToken) $2;
4835                 var li = new LocalVariable (current_block, lt.Value, lt.Location);
4836                 current_block.AddLocalName (li);
4837                 current_variable = new BlockVariableDeclaration ((FullNamedExpression) $1, li);
4838           }
4839           opt_local_variable_initializer opt_variable_declarators SEMICOLON
4840           {
4841                 $$ = current_variable;
4842                 current_variable = null;
4843                 lbag.AddLocation ($$, GetLocation ($6));
4844           }
4845         | CONST variable_type identifier_inside_body
4846           {
4847                 var lt = (Tokenizer.LocatedToken) $3;
4848                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
4849                 current_block.AddLocalName (li);
4850                 current_variable = new BlockConstantDeclaration ((FullNamedExpression) $2, li);
4851           }
4852           const_variable_initializer opt_const_declarators SEMICOLON
4853           {
4854                 $$ = current_variable;
4855                 current_variable = null;
4856                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($7));
4857           }
4858         ;
4859
4860 opt_local_variable_initializer
4861         : /* empty */
4862         | ASSIGN block_variable_initializer
4863           {
4864                 current_variable.Initializer = (Expression) $2;
4865                 // TODO: lbag
4866           }
4867         | error
4868           {
4869                 if (yyToken == Token.OPEN_BRACKET_EXPR) {
4870                         report.Error (650, lexer.Location,
4871                                 "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");
4872                 } else {
4873                         Error_SyntaxError (yyToken);
4874                 }
4875           }
4876         ;
4877
4878 opt_variable_declarators
4879         : /* empty */
4880         | variable_declarators
4881         ;
4882         
4883 opt_using_or_fixed_variable_declarators
4884         : /* empty */
4885         | variable_declarators
4886           {
4887                 foreach (var d in current_variable.Declarators) {
4888                         if (d.Initializer == null)
4889                                 Error_MissingInitializer (d.Variable.Location);
4890                 }
4891           }
4892         ;       
4893         
4894 variable_declarators
4895         : variable_declarator
4896         | variable_declarators variable_declarator
4897         ;
4898         
4899 variable_declarator
4900         : COMMA identifier_inside_body
4901           {
4902                 var lt = (Tokenizer.LocatedToken) $2;     
4903                 var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
4904                 var d = new BlockVariableDeclaration.Declarator (li, null);
4905                 current_variable.AddDeclarator (d);
4906                 current_block.AddLocalName (li);
4907                 lbag.AddLocation (d, GetLocation ($1));
4908           }
4909         | COMMA identifier_inside_body ASSIGN block_variable_initializer
4910           {
4911                 var lt = (Tokenizer.LocatedToken) $2;     
4912                 var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
4913                 var d = new BlockVariableDeclaration.Declarator (li, (Expression) $4);
4914                 current_variable.AddDeclarator (d);
4915                 current_block.AddLocalName (li);
4916                 lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
4917           }
4918         ;
4919         
4920 const_variable_initializer
4921         : /* empty */
4922           {
4923                 report.Error (145, lexer.Location, "A const field requires a value to be provided");
4924           }
4925         | ASSIGN constant_initializer_expr 
4926           {
4927                 current_variable.Initializer = (Expression) $2;
4928           }
4929         ;
4930         
4931 opt_const_declarators
4932         : /* empty */
4933         | const_declarators
4934         ;
4935         
4936 const_declarators
4937         : const_declarator
4938         | const_declarators const_declarator
4939         ;
4940         
4941 const_declarator
4942         : COMMA identifier_inside_body ASSIGN constant_initializer_expr
4943           {
4944                 var lt = (Tokenizer.LocatedToken) $2;     
4945                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
4946                 var d = new BlockVariableDeclaration.Declarator (li, (Expression) $4);
4947                 current_variable.AddDeclarator (d);
4948                 current_block.AddLocalName (li);
4949                 lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
4950           }
4951         ;
4952         
4953 block_variable_initializer
4954         : variable_initializer
4955         | STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET
4956           {
4957                 $$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1));
4958                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
4959           }
4960         | STACKALLOC simple_type
4961           {
4962                 report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type");
4963                 $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1));          
4964           }
4965         ;
4966
4967 expression_statement
4968         : statement_expression SEMICOLON
4969           {
4970                 $$ = $1;
4971                 lbag.AddStatement ($$, GetLocation ($2));
4972           }
4973         | statement_expression COMPLETE_COMPLETION { $$ = $1; }
4974         | statement_expression CLOSE_BRACE
4975           {
4976                 $$ = $1;
4977                 report.Error (1002, GetLocation ($2), "; expected");
4978                 lexer.putback ('}');
4979           }
4980         ;
4981
4982 interactive_expression_statement
4983         : interactive_statement_expression SEMICOLON { $$ = $1; }
4984         | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; }
4985         ;
4986
4987         //
4988         // We have to do the wrapping here and not in the case above,
4989         // because statement_expression is used for example in for_statement
4990         //
4991 statement_expression
4992         : expression
4993           {
4994                 ExpressionStatement s = $1 as ExpressionStatement;
4995                 if (s == null) {
4996                         Expression.Error_InvalidExpressionStatement (report, GetLocation ($1));
4997                         $$ = new StatementErrorExpression ($1 as Expression);
4998                 } else {
4999                         $$ = new StatementExpression (s);
5000                 }
5001           }
5002         ;
5003
5004 interactive_statement_expression
5005         : expression
5006           {
5007                 Expression expr = (Expression) $1;
5008                 ExpressionStatement s;
5009
5010                 s = new OptionalAssign (new SimpleName ("$retval", lexer.Location), expr, lexer.Location);
5011                 $$ = new StatementExpression (s);
5012           }
5013         | error
5014           {
5015                 Error_SyntaxError (yyToken);
5016                 $$ = new EmptyStatement (GetLocation ($1));
5017           }
5018         ;
5019         
5020 selection_statement
5021         : if_statement
5022         | switch_statement
5023         ; 
5024
5025 if_statement
5026         : IF open_parens_any boolean_expression CLOSE_PARENS 
5027           embedded_statement
5028           { 
5029                 if ($5 is EmptyStatement)
5030                         Warning_EmptyStatement (GetLocation ($5));
5031                 
5032                 $$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
5033                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5034           }
5035         | IF open_parens_any boolean_expression CLOSE_PARENS
5036           embedded_statement ELSE embedded_statement
5037           {
5038                 $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1));
5039                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
5040                 
5041                 if ($5 is EmptyStatement)
5042                         Warning_EmptyStatement (GetLocation ($5));
5043                 if ($7 is EmptyStatement)
5044                         Warning_EmptyStatement (GetLocation ($7));
5045           }
5046         | IF open_parens_any boolean_expression error
5047           {
5048                 Error_SyntaxError (yyToken);
5049                 
5050                 $$ = new If ((BooleanExpression) $3, null, GetLocation ($1));
5051                 lbag.AddStatement ($$, GetLocation ($2));
5052           }
5053         ;
5054
5055 switch_statement
5056         : SWITCH open_parens_any expression CLOSE_PARENS OPEN_BRACE
5057           {
5058                 start_block (GetLocation ($5));
5059           }
5060           opt_switch_sections CLOSE_BRACE
5061           {
5062                 $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, (List<SwitchSection>) $7, GetLocation ($1));  
5063                 end_block (GetLocation ($8));
5064                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5065           }
5066         | SWITCH open_parens_any expression error
5067           {
5068                 Error_SyntaxError (yyToken);
5069           
5070                 $$ = new Switch ((Expression) $3, null, null, GetLocation ($1));        
5071                 lbag.AddStatement ($$, GetLocation ($2));
5072           }
5073         ;
5074
5075 opt_switch_sections
5076         : /* empty */           
5077       {
5078                 report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); 
5079                 $$ = new List<SwitchSection> ();
5080           }
5081         | switch_sections
5082         ;
5083
5084 switch_sections
5085         : switch_section 
5086           {
5087                 var sections = new List<SwitchSection> (4);
5088
5089                 sections.Add ((SwitchSection) $1);
5090                 $$ = sections;
5091           }
5092         | switch_sections switch_section
5093           {
5094                 var sections = (List<SwitchSection>) $1;
5095
5096                 sections.Add ((SwitchSection) $2);
5097                 $$ = sections;
5098           }
5099         | error
5100           {
5101                 Error_SyntaxError (yyToken);
5102                 $$ = new List<SwitchSection> ();
5103           } 
5104         ;
5105
5106 switch_section
5107         : switch_labels
5108           {
5109                 current_block = current_block.CreateSwitchBlock (lexer.Location);
5110           }
5111           statement_list 
5112           {
5113                 $$ = new SwitchSection ((List<SwitchLabel>) $1, current_block);
5114           }
5115         ;
5116
5117 switch_labels
5118         : switch_label 
5119           {
5120                 var labels = new List<SwitchLabel> (2);
5121
5122                 labels.Add ((SwitchLabel) $1);
5123                 $$ = labels;
5124           }
5125         | switch_labels switch_label 
5126           {
5127                 var labels = (List<SwitchLabel>) ($1);
5128                 labels.Add ((SwitchLabel) $2);
5129
5130                 $$ = labels;
5131           }
5132         ;
5133
5134 switch_label
5135         : CASE constant_expression COLON
5136          {
5137                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
5138                 lbag.AddLocation ($$, GetLocation ($3));
5139          }
5140         | CASE constant_expression error
5141           {
5142                 Error_SyntaxError (yyToken);
5143                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
5144           }
5145         | DEFAULT_COLON
5146           {
5147                 $$ = new SwitchLabel (null, GetLocation ($1));
5148           }
5149         ;
5150
5151 iteration_statement
5152         : while_statement
5153         | do_statement
5154         | for_statement
5155         | foreach_statement
5156         ;
5157
5158 while_statement
5159         : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement
5160           {
5161                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5162                         Warning_EmptyStatement (GetLocation ($5));
5163           
5164                 $$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
5165                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5166           }
5167         | WHILE open_parens_any boolean_expression error
5168           {
5169                 Error_SyntaxError (yyToken);
5170                 
5171                 $$ = new While ((BooleanExpression) $3, null, GetLocation ($1));
5172                 lbag.AddStatement ($$, GetLocation ($2));
5173           }
5174         ;
5175
5176 do_statement
5177         : DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
5178           {
5179                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
5180                 lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
5181           }
5182         | DO embedded_statement error
5183           {
5184                 Error_SyntaxError (yyToken);
5185                 $$ = new Do ((Statement) $2, null, GetLocation ($1), Location.Null);
5186           }
5187         | DO embedded_statement WHILE open_parens_any boolean_expression error
5188           {
5189                 Error_SyntaxError (yyToken);
5190           
5191                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
5192                 lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4));
5193           }
5194         ;
5195
5196 for_statement
5197         : FOR open_parens_any
5198           {
5199                 start_block (GetLocation ($2));
5200                 current_block.IsCompilerGenerated = true;
5201                 For f = new For (GetLocation ($1));
5202                 current_block.AddStatement (f);
5203                 $$ = f;
5204           }
5205           for_statement_cont
5206           {
5207                 $$ = $4;
5208           }
5209         ;
5210         
5211 // Has to use be extra rule to recover started block
5212 for_statement_cont
5213         : opt_for_initializer SEMICOLON
5214           {
5215                 ((For) $0).Initializer = (Statement) $1;
5216
5217                 // Pass the "For" object to the iterator_part4
5218                 oob_stack.Push ($0);
5219           }
5220           for_condition_and_iterator_part
5221           embedded_statement
5222           {
5223                 var locations = (Tuple<Location,Location>) $4;
5224                 oob_stack.Pop ();
5225                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5226                         Warning_EmptyStatement (GetLocation ($5));
5227           
5228                 For f = ((For) $0);
5229                 f.Statement = (Statement) $5;
5230                 lbag.AddStatement (f, current_block.StartLocation, GetLocation ($2), GetLocation (locations.Item1), GetLocation (locations.Item2));
5231
5232                 $$ = end_block (GetLocation ($2));
5233           }
5234         | error
5235           {
5236                 Error_SyntaxError (yyToken);
5237                 $$ = end_block (current_block.StartLocation);
5238           }
5239         ;
5240
5241 for_condition_and_iterator_part
5242         : opt_for_condition SEMICOLON
5243           {
5244                 For f = (For) oob_stack.Peek ();
5245                 f.Condition = (BooleanExpression) $1;
5246           }
5247           for_iterator_part {
5248                 $$ = new Tuple<Location,Location> (GetLocation ($2), (Location) $4);
5249           }
5250
5251         // Handle errors in the case of opt_for_condition being followed by
5252         // a close parenthesis
5253         | opt_for_condition close_parens_close_brace {
5254                 report.Error (1525, GetLocation ($2), "Unexpected symbol `}'");
5255                 For f = (For) oob_stack.Peek ();
5256                 f.Condition = (BooleanExpression) $1;
5257                 $$ = new Tuple<Location,Location> (GetLocation ($2), GetLocation ($2));
5258           }
5259         ;
5260
5261 for_iterator_part
5262         : opt_for_iterator CLOSE_PARENS {
5263                 For f = (For) oob_stack.Peek ();
5264                 f.Iterator = (Statement) $1;
5265                 $$ = GetLocation ($2);
5266           }
5267         | opt_for_iterator CLOSE_BRACE {
5268                 report.Error (1525, GetLocation ($2), "Unexpected symbol expected ')'");
5269                 For f = (For) oob_stack.Peek ();
5270                 f.Iterator = (Statement) $1;
5271                 $$ = GetLocation ($2);
5272           }
5273         ; 
5274
5275 close_parens_close_brace 
5276         : CLOSE_PARENS
5277         | CLOSE_BRACE { lexer.putback ('}'); }
5278         ;
5279
5280 opt_for_initializer
5281         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
5282         | for_initializer       
5283         ;
5284
5285 for_initializer
5286         : variable_type identifier_inside_body
5287           {
5288                 var lt = (Tokenizer.LocatedToken) $2;
5289                 var li = new LocalVariable (current_block, lt.Value, lt.Location);
5290                 current_block.AddLocalName (li);
5291                 current_variable = new BlockVariableDeclaration ((FullNamedExpression) $1, li);
5292           }
5293           opt_local_variable_initializer opt_variable_declarators
5294           {
5295                 $$ = current_variable;
5296                 current_variable = null;
5297           }
5298         | statement_expression_list
5299         ;
5300
5301 opt_for_condition
5302         : /* empty */           { $$ = null; }
5303         | boolean_expression
5304         ;
5305
5306 opt_for_iterator
5307         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
5308         | for_iterator
5309         ;
5310
5311 for_iterator
5312         : statement_expression_list
5313         ;
5314
5315 statement_expression_list
5316         : statement_expression
5317         | statement_expression_list COMMA statement_expression
5318           {
5319                 var sl = $1 as StatementList;
5320                 if (sl == null) {
5321                         sl = new StatementList ((Statement) $1, (Statement) $3);
5322                         lbag.AddStatement (sl, GetLocation ($2));
5323                 } else {
5324                         sl.Add ((Statement) $3);
5325                         lbag.AppendTo (sl, GetLocation ($2));
5326                 }
5327                         
5328                 $$ = sl;
5329           }
5330         ;
5331
5332 foreach_statement
5333         : FOREACH open_parens_any type error
5334           {
5335                 report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement");
5336
5337                 start_block (GetLocation ($2));
5338                 current_block.IsCompilerGenerated = true;
5339                 
5340                 Foreach f = new Foreach ((Expression) $3, null, null, null, null, GetLocation ($1));
5341                 current_block.AddStatement (f);
5342                 
5343                 lbag.AddStatement (f, GetLocation ($2));
5344                 $$ = end_block (GetLocation ($4));
5345           }
5346         | FOREACH open_parens_any type identifier_inside_body error
5347           {
5348                 Error_SyntaxError (yyToken);
5349         
5350                 start_block (GetLocation ($2));
5351                 current_block.IsCompilerGenerated = true;
5352                 
5353                 var lt = (Tokenizer.LocatedToken) $4;
5354                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
5355                 current_block.AddLocalName (li);
5356                 
5357                 Foreach f = new Foreach ((Expression) $3, li, null, null, null, GetLocation ($1));
5358                 current_block.AddStatement (f);
5359                 
5360                 lbag.AddStatement (f, GetLocation ($2));
5361                 $$ = end_block (GetLocation ($5));
5362           }
5363         | FOREACH open_parens_any type identifier_inside_body IN expression CLOSE_PARENS 
5364           {
5365                 start_block (GetLocation ($2));
5366                 current_block.IsCompilerGenerated = true;
5367                 
5368                 var lt = (Tokenizer.LocatedToken) $4;
5369                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
5370                 current_block.AddLocalName (li);
5371                 $$ = li;
5372           } 
5373           embedded_statement
5374           {
5375                 if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5376                         Warning_EmptyStatement (GetLocation ($9));
5377                 
5378                 Foreach f = new Foreach ((Expression) $3, (LocalVariable) $8, (Expression) $6, (Statement) $9, current_block, GetLocation ($1));
5379                 lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
5380                 end_block (GetLocation ($7));
5381                 
5382                 $$ = f;
5383           }
5384         ;
5385
5386 jump_statement
5387         : break_statement
5388         | continue_statement
5389         | goto_statement
5390         | return_statement
5391         | throw_statement
5392         | yield_statement
5393         ;
5394
5395 break_statement
5396         : BREAK SEMICOLON
5397           {
5398                 $$ = new Break (GetLocation ($1));
5399                 lbag.AddStatement ($$, GetLocation ($2));
5400           }
5401         ;
5402
5403 continue_statement
5404         : CONTINUE SEMICOLON
5405           {
5406                 $$ = new Continue (GetLocation ($1));
5407                 lbag.AddStatement ($$, GetLocation ($2));
5408           }
5409         | CONTINUE error
5410           {
5411                 Error_SyntaxError (yyToken);
5412                 $$ = new Continue (GetLocation ($1));
5413           }
5414         ;
5415
5416 goto_statement
5417         : GOTO identifier_inside_body SEMICOLON 
5418           {
5419                 var lt = (Tokenizer.LocatedToken) $2;
5420                 $$ = new Goto (lt.Value, GetLocation ($1));
5421                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5422           }
5423         | GOTO CASE constant_expression SEMICOLON
5424           {
5425                 $$ = new GotoCase ((Expression) $3, GetLocation ($1));
5426                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5427           }
5428         | GOTO DEFAULT SEMICOLON 
5429           {
5430                 $$ = new GotoDefault (GetLocation ($1));
5431                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5432           }
5433         ; 
5434
5435 return_statement
5436         : RETURN opt_expression SEMICOLON
5437           {
5438                 $$ = new Return ((Expression) $2, GetLocation ($1));
5439                 lbag.AddStatement ($$, GetLocation ($3));
5440           }
5441         | RETURN expression error
5442           {
5443                 Error_SyntaxError (yyToken);
5444                 $$ = new Return ((Expression) $2, GetLocation ($1));
5445           }
5446         | RETURN error
5447           {
5448                 Error_SyntaxError (yyToken);
5449                 $$ = new Return (null, GetLocation ($1));
5450           }
5451         ;
5452
5453 throw_statement
5454         : THROW opt_expression SEMICOLON
5455           {
5456                 $$ = new Throw ((Expression) $2, GetLocation ($1));
5457                 lbag.AddStatement ($$, GetLocation ($3));
5458           }
5459         | THROW error
5460           {
5461                 Error_SyntaxError (yyToken);
5462                 $$ = new Throw (null, GetLocation ($1));
5463           }
5464         ;
5465
5466 yield_statement 
5467         : identifier_inside_body RETURN opt_expression SEMICOLON
5468           {
5469                 var lt = (Tokenizer.LocatedToken) $1;
5470                 string s = lt.Value;
5471                 if (s != "yield"){
5472                         report.Error (1003, lt.Location, "; expected");
5473                 } else if ($3 == null) {
5474                         report.Error (1627, GetLocation ($4), "Expression expected after yield return");
5475                 } else if (lang_version == LanguageVersion.ISO_1){
5476                         FeatureIsNotAvailable (lt.Location, "iterators");
5477                 }
5478                 
5479                 current_block.Explicit.RegisterIteratorYield ();
5480                 $$ = new Yield ((Expression) $3, lt.Location);
5481                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5482           }
5483         | identifier_inside_body RETURN expression error
5484           {
5485                 Error_SyntaxError (yyToken);
5486
5487                 var lt = (Tokenizer.LocatedToken) $1;
5488                 string s = lt.Value;
5489                 if (s != "yield"){
5490                         report.Error (1003, lt.Location, "; expected");
5491                 } else if ($3 == null) {
5492                         report.Error (1627, GetLocation ($4), "Expression expected after yield return");
5493                 } else if (lang_version == LanguageVersion.ISO_1){
5494                         FeatureIsNotAvailable (lt.Location, "iterators");
5495                 }
5496                 
5497                 current_block.Explicit.RegisterIteratorYield ();
5498                 $$ = new Yield ((Expression) $3, lt.Location);
5499                 lbag.AddStatement ($$, GetLocation ($2));
5500           }
5501         | identifier_inside_body BREAK SEMICOLON
5502           {
5503                 var lt = (Tokenizer.LocatedToken) $1;
5504                 string s = lt.Value;
5505                 if (s != "yield"){
5506                         report.Error (1003, lt.Location, "; expected");
5507                 } else if (lang_version == LanguageVersion.ISO_1){
5508                         FeatureIsNotAvailable (lt.Location, "iterators");
5509                 }
5510                 
5511                 current_block.Explicit.RegisterIteratorYield ();
5512                 $$ = new YieldBreak (lt.Location);
5513                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5514           }
5515         ;
5516
5517 opt_expression
5518         : /* empty */
5519         | expression
5520         ;
5521
5522 try_statement
5523         : TRY block catch_clauses
5524           {
5525                 $$ = new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), false);
5526           }
5527         | TRY block FINALLY block
5528           {
5529                 $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1));
5530                 lbag.AddStatement ($$, GetLocation ($3));
5531           }
5532         | TRY block catch_clauses FINALLY block
5533           {
5534                 $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, Location.Null, true), (Block) $5, GetLocation ($1));
5535                 lbag.AddStatement ($$, GetLocation ($4));
5536           }
5537         | TRY block error
5538           {
5539                 Error_SyntaxError (1524, yyToken);
5540                 $$ = new TryCatch ((Block) $2, null, GetLocation ($1), false);
5541           }
5542         ;
5543
5544 catch_clauses
5545         : catch_clause 
5546           {
5547                 var l = new List<Catch> (2);
5548
5549                 l.Add ((Catch) $1);
5550                 $$ = l;
5551           }
5552         | catch_clauses catch_clause
5553           {
5554                 var l = (List<Catch>) $1;
5555                 
5556                 Catch c = (Catch) $2;
5557                 if (l [l.Count - 1].IsGeneral) {
5558                         report.Error (1017, c.loc, "Try statement already has an empty catch block");
5559                 }
5560                 
5561                 l.Add (c);
5562                 $$ = l;
5563           }
5564         ;
5565
5566 opt_identifier
5567         : /* empty */
5568         | identifier_inside_body
5569         ;
5570
5571 catch_clause 
5572         : CATCH block
5573           {
5574                 $$ = new Catch ((Block) $2, GetLocation ($1));
5575           }
5576         | CATCH open_parens_any type opt_identifier CLOSE_PARENS
5577           {
5578                 start_block (GetLocation ($2));
5579                 var c = new Catch (current_block, GetLocation ($1));
5580                 c.TypeExpression = (FullNamedExpression) $3;
5581
5582                 if ($4 != null) {
5583                         var lt = (Tokenizer.LocatedToken) $4;
5584                         c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
5585                         current_block.AddLocalName (c.Variable);
5586                 }
5587                 
5588                 lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
5589                 $$ = c;
5590           }
5591           block_prepared
5592           {
5593                 $$ = $6;
5594           }
5595         | CATCH open_parens_any error
5596           {
5597                 if (yyToken == Token.CLOSE_PARENS) {
5598                         report.Error (1015, lexer.Location,
5599                                 "A type that derives from `System.Exception', `object', or `string' expected");
5600                 } else {
5601                         Error_SyntaxError (yyToken);
5602                 }
5603                 
5604                 $$ = new Catch (null, GetLocation ($1));
5605           }
5606         ;
5607
5608 checked_statement
5609         : CHECKED block
5610           {
5611                 $$ = new Checked ((Block) $2, GetLocation ($1));
5612           }
5613         ;
5614
5615 unchecked_statement
5616         : UNCHECKED block
5617           {
5618                 $$ = new Unchecked ((Block) $2, GetLocation ($1));
5619           }
5620         ;
5621
5622 unsafe_statement
5623         : UNSAFE
5624           {
5625                 if (!settings.Unsafe)
5626                         Error_UnsafeCodeNotAllowed (GetLocation ($1));
5627           } block {
5628                 $$ = new Unsafe ((Block) $3, GetLocation ($1));
5629           }
5630         ;
5631
5632 lock_statement
5633         : LOCK open_parens_any expression CLOSE_PARENS embedded_statement
5634           {
5635                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5636                         Warning_EmptyStatement (GetLocation ($5));
5637           
5638                 $$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1));
5639                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5640           }
5641         | LOCK open_parens_any expression error
5642           {
5643                 Error_SyntaxError (yyToken);
5644
5645                 $$ = new Lock ((Expression) $3, null, GetLocation ($1));
5646                 lbag.AddStatement ($$, GetLocation ($2));
5647           }
5648         ;
5649
5650 fixed_statement
5651         : FIXED open_parens_any variable_type identifier_inside_body
5652           {
5653             start_block (GetLocation ($2));
5654             
5655                 current_block.IsCompilerGenerated = true;
5656                 var lt = (Tokenizer.LocatedToken) $4;
5657                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location);
5658                 current_block.AddLocalName (li);
5659                 current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) $3, li);
5660           }
5661           using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators CLOSE_PARENS
5662           {
5663                 $$ = current_variable;
5664                 current_variable = null;
5665           }
5666           embedded_statement
5667           {
5668                 if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5669                         Warning_EmptyStatement (GetLocation ($10));
5670           
5671                 Fixed f = new Fixed ((Fixed.VariableDeclaration) $9, (Statement) $10, GetLocation ($1));
5672                 current_block.AddStatement (f);
5673                 $$ = end_block (GetLocation ($8));
5674           }
5675         ;
5676
5677 using_statement
5678         : USING open_parens_any variable_type identifier_inside_body
5679           {
5680             start_block (GetLocation ($2));
5681             
5682                 current_block.IsCompilerGenerated = true;
5683                 var lt = (Tokenizer.LocatedToken) $4;
5684                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location);
5685                 current_block.AddLocalName (li);
5686                 current_variable = new Using.VariableDeclaration ((FullNamedExpression) $3, li);
5687           }
5688           using_initialization CLOSE_PARENS
5689           {
5690                 $$ = current_variable;    
5691                 current_variable = null;
5692           }
5693           embedded_statement
5694           {
5695                 if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5696                         Warning_EmptyStatement (GetLocation ($9));
5697           
5698                 Using u = new Using ((Using.VariableDeclaration) $8, (Statement) $9, GetLocation ($1));
5699                 current_block.AddStatement (u);
5700                 $$ = end_block (GetLocation ($7));
5701           }
5702         | USING open_parens_any expression CLOSE_PARENS embedded_statement
5703           {
5704                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5705                         Warning_EmptyStatement (GetLocation ($5));
5706           
5707                 $$ = new Using ((Expression) $3, (Statement) $5, GetLocation ($1));
5708                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5709           }
5710         | USING open_parens_any expression error
5711           {
5712                 Error_SyntaxError (yyToken);
5713                 
5714                 $$ = new Using ((Expression) $3, null, GetLocation ($1));
5715                 lbag.AddStatement ($$, GetLocation ($2));
5716           }
5717         ;
5718         
5719 using_initialization
5720         : using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators
5721         | error
5722           {
5723                 // It has to be here for the parent to safely restore artificial block
5724                 Error_SyntaxError (yyToken);
5725           }
5726         ;
5727         
5728 using_or_fixed_variable_initializer
5729         : /* empty */
5730           {
5731                 Error_MissingInitializer (lexer.Location);
5732           }
5733         | ASSIGN variable_initializer
5734           {
5735                 current_variable.Initializer = (Expression) $2;
5736                 $$ = current_variable;
5737           }
5738         ;
5739
5740
5741 // LINQ
5742
5743 query_expression
5744         : first_from_clause query_body 
5745           {
5746                 lexer.query_parsing = false;
5747                         
5748                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5749                         
5750                 from.Tail.Next = (Linq.AQueryClause)$2;
5751                 $$ = from;
5752                 
5753                 current_block.SetEndLocation (lexer.Location);
5754                 current_block = current_block.Parent;
5755           }
5756         | nested_from_clause query_body
5757           {
5758                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5759                         
5760                 from.Tail.Next = (Linq.AQueryClause)$2;
5761                 $$ = from;
5762                 
5763                 current_block.SetEndLocation (lexer.Location);
5764                 current_block = current_block.Parent;
5765           }     
5766
5767         // Bubble up COMPLETE_COMPLETION productions
5768         | first_from_clause COMPLETE_COMPLETION {
5769                 lexer.query_parsing = false;
5770                 $$ = $1;
5771
5772                 current_block.SetEndLocation (lexer.Location);
5773                 current_block = current_block.Parent;
5774           }
5775         | nested_from_clause COMPLETE_COMPLETION {
5776                 $$ = $1;
5777                 current_block.SetEndLocation (lexer.Location);
5778                 current_block = current_block.Parent;
5779           }
5780         ;
5781         
5782 first_from_clause
5783         : FROM_FIRST identifier_inside_body IN expression
5784           {
5785                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5786           
5787                 var lt = (Tokenizer.LocatedToken) $2;
5788                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
5789                 $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)));
5790           }
5791         | FROM_FIRST type identifier_inside_body IN expression
5792           {
5793                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5794           
5795                 var lt = (Tokenizer.LocatedToken) $3;
5796                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
5797                 $$ = new Linq.QueryExpression (
5798                         new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
5799                                 IdentifierType = (FullNamedExpression)$2
5800                         }
5801                 );
5802           }
5803         ;
5804
5805 nested_from_clause
5806         : FROM identifier_inside_body IN expression
5807           {
5808                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5809           
5810                 var lt = (Tokenizer.LocatedToken) $2;
5811                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
5812                 $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)));
5813           }
5814         | FROM type identifier_inside_body IN expression
5815           {
5816                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5817           
5818                 var lt = (Tokenizer.LocatedToken) $3;
5819                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
5820                 $$ = new Linq.QueryExpression (
5821                         new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
5822                                 IdentifierType = (FullNamedExpression)$2
5823                         }
5824                 );
5825           }
5826         ;
5827         
5828 from_clause
5829         : FROM identifier_inside_body IN
5830           {
5831                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5832           }
5833           expression_or_error
5834           {
5835                 var lt = (Tokenizer.LocatedToken) $2;
5836                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
5837                 $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$5, GetLocation ($1));
5838                 
5839                 current_block.SetEndLocation (lexer.Location);
5840                 current_block = current_block.Parent;
5841                 
5842                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5843           }       
5844         | FROM type identifier_inside_body IN
5845           {
5846                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5847           }
5848           expression_or_error
5849           {
5850                 var lt = (Tokenizer.LocatedToken) $3;
5851                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
5852
5853                 $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) {
5854                         IdentifierType = (FullNamedExpression)$2
5855                 };
5856                 
5857                 current_block.SetEndLocation (lexer.Location);
5858                 current_block = current_block.Parent;
5859                 
5860                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5861           }
5862         ;       
5863
5864 query_body
5865         : query_body_clauses select_or_group_clause opt_query_continuation 
5866           {
5867                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5868                 
5869                 if ($3 != null)
5870                         head.Next = (Linq.AQueryClause)$3;
5871                                 
5872                 if ($1 != null) {
5873                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5874                         clause.Tail.Next = head;
5875                         head = clause;
5876                 }
5877                 
5878                 $$ = head;
5879           }
5880         | select_or_group_clause opt_query_continuation
5881           {
5882                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5883
5884                 if ($1 != null) {
5885                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5886                         clause.Tail.Next = head;
5887                         head = clause;
5888                 }
5889                 
5890                 $$ = head;
5891           }
5892         | query_body_clauses COMPLETE_COMPLETION
5893         | query_body_clauses error
5894           {
5895                 report.Error (742, GetLocation ($2), "Unexpected symbol `{0}'. A query body must end with select or group clause", GetSymbolName (yyToken));
5896                 $$ = $1;
5897           }
5898         | error
5899           {
5900                 Error_SyntaxError (yyToken);
5901                 $$ = null;
5902           }
5903         ;
5904         
5905 select_or_group_clause
5906         : SELECT
5907           {
5908                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5909           }
5910           expression_or_error
5911           {
5912                 $$ = new Linq.Select ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
5913
5914                 current_block.SetEndLocation (lexer.Location);
5915                 current_block = current_block.Parent;
5916           }
5917         | GROUP
5918           {
5919                 if (linq_clause_blocks == null)
5920                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
5921                         
5922                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5923                 linq_clause_blocks.Push ((Linq.QueryBlock)current_block);
5924           }
5925           expression_or_error
5926           {
5927                 current_block.SetEndLocation (lexer.Location);
5928                 current_block = current_block.Parent;
5929           
5930                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5931           }
5932           BY expression_or_error
5933           {
5934                 $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1));
5935                 lbag.AddLocation ($$, GetLocation ($5));
5936                 
5937                 current_block.SetEndLocation (lexer.Location);
5938                 current_block = current_block.Parent;
5939           }
5940         ;
5941         
5942 query_body_clauses
5943         : query_body_clause
5944         | query_body_clauses query_body_clause
5945           {
5946                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
5947                 $$ = $1;
5948           }
5949         ;
5950         
5951 query_body_clause
5952         : from_clause
5953         | let_clause 
5954         | where_clause
5955         | join_clause
5956         | orderby_clause
5957         ;
5958         
5959 let_clause
5960         : LET identifier_inside_body ASSIGN 
5961           {
5962                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5963           }
5964           expression_or_error
5965           {
5966                 var lt = (Tokenizer.LocatedToken) $2;
5967                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
5968                 $$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1));
5969                 lbag.AddLocation ($$, GetLocation ($3));
5970                 
5971                 current_block.SetEndLocation (lexer.Location);
5972                 current_block = current_block.Parent;
5973                 
5974                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5975           }
5976         ;
5977
5978 where_clause
5979         : WHERE
5980           {
5981                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5982           }
5983           expression_or_error
5984           {
5985                 $$ = new Linq.Where ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
5986
5987                 current_block.SetEndLocation (lexer.Location);
5988                 current_block = current_block.Parent;
5989           }
5990         ;
5991         
5992 join_clause
5993         : JOIN identifier_inside_body IN
5994           {
5995                 if (linq_clause_blocks == null)
5996                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
5997                         
5998                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5999                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6000           }
6001           expression_or_error ON
6002           {
6003                 current_block.SetEndLocation (lexer.Location);
6004                 current_block = current_block.Parent;
6005
6006                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6007                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6008           }
6009           expression_or_error EQUALS
6010           {
6011                 current_block.AddStatement (new ContextualReturn ((Expression) $8));
6012                 current_block.SetEndLocation (lexer.Location);
6013                 current_block = current_block.Parent;
6014
6015                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6016           }
6017           expression_or_error opt_join_into
6018           {
6019                 current_block.AddStatement (new ContextualReturn ((Expression) $11));
6020                 current_block.SetEndLocation (lexer.Location);
6021           
6022                 var outer_selector = linq_clause_blocks.Pop ();
6023                 var block = linq_clause_blocks.Pop ();
6024
6025                 var lt = (Tokenizer.LocatedToken) $2;   
6026                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6027                 Linq.RangeVariable into;
6028                 
6029                 if ($12 == null) {
6030                         into = sn;
6031                         $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1));
6032                         lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9));
6033                 } else {
6034                         //
6035                         // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
6036                         //
6037                         var parent = block.Parent;
6038                         while (parent is Linq.QueryBlock) {
6039                                 parent = parent.Parent;
6040                         }
6041                         current_block.Parent = parent;
6042                         
6043                         ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6044                 
6045                         lt = (Tokenizer.LocatedToken) $12;
6046                         into = new Linq.RangeVariable (lt.Value, lt.Location);
6047
6048                         $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1));   
6049                         lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($12));
6050                 }
6051
6052                 current_block = block.Parent;
6053                 ((Linq.QueryBlock)current_block).AddRangeVariable (into);
6054           }
6055         | JOIN type identifier_inside_body IN
6056           {
6057                 if (linq_clause_blocks == null)
6058                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
6059                         
6060                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6061                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6062           }
6063           expression_or_error ON
6064           {
6065                 current_block.SetEndLocation (lexer.Location);
6066                 current_block = current_block.Parent;
6067
6068                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6069                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6070           }
6071           expression_or_error EQUALS
6072           {
6073                 current_block.AddStatement (new ContextualReturn ((Expression) $9));
6074                 current_block.SetEndLocation (lexer.Location);
6075                 current_block = current_block.Parent;
6076
6077                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6078           }
6079           expression_or_error opt_join_into
6080           {
6081                 current_block.AddStatement (new ContextualReturn ((Expression) $12));
6082                 current_block.SetEndLocation (lexer.Location);
6083           
6084                 var outer_selector = linq_clause_blocks.Pop ();
6085                 var block = linq_clause_blocks.Pop ();
6086                 
6087                 var lt = (Tokenizer.LocatedToken) $3;
6088                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6089                 Linq.RangeVariable into;
6090                 
6091                 if ($13 == null) {
6092                         into = sn;              
6093                         $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) {
6094                                 IdentifierType = (FullNamedExpression)$2
6095                         };
6096                 } else {
6097                         //
6098                         // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
6099                         //
6100                         var parent = block.Parent;
6101                         while (parent is Linq.QueryBlock) {
6102                                 parent = parent.Parent;
6103                         }
6104                         current_block.Parent = parent;
6105                 
6106                         ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6107                 
6108                         lt = (Tokenizer.LocatedToken) $13;
6109                         into = new Linq.RangeVariable (lt.Value, lt.Location); // TODO:
6110                         
6111                         $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)) {
6112                                 IdentifierType = (FullNamedExpression)$2
6113                         };                      
6114                 }
6115                 
6116                 current_block = block.Parent;
6117                 ((Linq.QueryBlock)current_block).AddRangeVariable (into);               
6118           }
6119         ;
6120         
6121 opt_join_into
6122         : /* empty */
6123         | INTO identifier_inside_body
6124           {
6125                 $$ = $2;
6126           }
6127         ;
6128         
6129 orderby_clause
6130         : ORDERBY
6131           {
6132                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6133           }
6134           orderings
6135           {
6136                 current_block.SetEndLocation (lexer.Location);
6137                 current_block = current_block.Parent;
6138           
6139                 $$ = $3;
6140           }
6141         ;
6142         
6143 orderings
6144         : order_by
6145         | order_by COMMA
6146           {
6147                 current_block.SetEndLocation (lexer.Location);
6148                 current_block = current_block.Parent;
6149           
6150                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6151           }
6152           orderings_then_by
6153           {
6154                 ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4;
6155                 $$ = $1;
6156           }
6157         ;
6158         
6159 orderings_then_by
6160         : then_by
6161         | orderings_then_by COMMA
6162          {
6163                 current_block.SetEndLocation (lexer.Location);
6164                 current_block = current_block.Parent;
6165           
6166                 current_block = new Linq.QueryBlock ((Linq.QueryBlock) current_block, lexer.Location);   
6167          }
6168          then_by
6169          {
6170                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$4;
6171                 $$ = $1;
6172          }
6173         ;       
6174         
6175 order_by
6176         : expression
6177           {
6178                 $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
6179           }
6180         | expression ASCENDING
6181           {
6182                 $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
6183                 lbag.AddLocation ($$, GetLocation ($2));
6184           }
6185         | expression DESCENDING
6186           {
6187                 $$ = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)$1);      
6188                 lbag.AddLocation ($$, GetLocation ($2));
6189           }
6190         ;
6191
6192 then_by
6193         : expression
6194           {
6195                 $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
6196           }
6197         | expression ASCENDING
6198           {
6199                 $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
6200                 lbag.AddLocation ($$, GetLocation ($2));
6201           }
6202         | expression DESCENDING
6203           {
6204                 $$ = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)$1);       
6205                 lbag.AddLocation ($$, GetLocation ($2));
6206           }     
6207         ;
6208
6209
6210 opt_query_continuation
6211         : /* empty */
6212         | INTO identifier_inside_body
6213           {
6214                 // query continuation block is not linked with query block but with block
6215                 // before. This means each query can use same range variable names for
6216                 // different identifiers.
6217
6218                 current_block.SetEndLocation (GetLocation ($1));
6219                 current_block = current_block.Parent;
6220         
6221                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6222                 
6223                 if (linq_clause_blocks == null)
6224                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
6225                         
6226                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);              
6227           }
6228           query_body
6229           {
6230                 var current_block = linq_clause_blocks.Pop ();    
6231                 var lt = (Tokenizer.LocatedToken) $2;
6232                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
6233                 $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation ($1)) {
6234                         next = (Linq.AQueryClause)$4
6235                 };
6236           }
6237         ;
6238         
6239 //
6240 // Support for using the compiler as an interactive parser
6241 //
6242 // The INTERACTIVE_PARSER token is first sent to parse our
6243 // productions;  If the result is a Statement, the parsing
6244 // is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
6245 // to setup the blocks in advance.
6246 //
6247 // This setup is here so that in the future we can add 
6248 // support for other constructs (type parsing, namespaces, etc)
6249 // that do not require a block to be setup in advance
6250 //
6251
6252 interactive_parsing
6253         : EVAL_STATEMENT_PARSER EOF 
6254         | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives opt_COMPLETE_COMPLETION
6255         | EVAL_STATEMENT_PARSER
6256          { 
6257                 current_container = current_type = new Class (current_container, new MemberName ("<InteractiveExpressionClass>"), Modifiers.PUBLIC, null);
6258
6259                 // (ref object retval)
6260                 Parameter [] mpar = new Parameter [1];
6261                 mpar [0] = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null);
6262
6263                 ParametersCompiled pars = new ParametersCompiled (mpar);
6264                 var mods = Modifiers.PUBLIC | Modifiers.STATIC;
6265                 if (settings.Unsafe)
6266                         mods |= Modifiers.UNSAFE;
6267
6268                 current_local_parameters = pars;
6269                 Method method = new Method (
6270                         current_type,
6271                         new TypeExpression (compiler.BuiltinTypes.Void, Location.Null),
6272                         mods,
6273                         new MemberName ("Host"),
6274                         pars,
6275                         null /* attributes */);
6276                         
6277                 current_type.AddMember (method);                        
6278
6279                 oob_stack.Push (method);
6280                 ++lexer.parsing_block;
6281                 start_block (lexer.Location);
6282           }             
6283           interactive_statement_list opt_COMPLETE_COMPLETION
6284           {
6285                 --lexer.parsing_block;
6286                 Method method = (Method) oob_stack.Pop ();
6287
6288                 method.Block = (ToplevelBlock) end_block(lexer.Location);
6289
6290                 InteractiveResult = (Class) pop_current_class ();
6291                 current_local_parameters = null;
6292           } 
6293         | EVAL_COMPILATION_UNIT_PARSER interactive_compilation_unit
6294         ;
6295
6296 interactive_compilation_unit
6297         : opt_extern_alias_directives opt_using_directives
6298         | opt_extern_alias_directives opt_using_directives namespace_or_type_declarations
6299         ;
6300
6301 opt_COMPLETE_COMPLETION
6302         : /* nothing */
6303         | COMPLETE_COMPLETION
6304         ;
6305
6306 close_brace_or_complete_completion
6307         : CLOSE_BRACE
6308         | COMPLETE_COMPLETION
6309         ;
6310         
6311 //
6312 // XML documentation code references micro parser
6313 //
6314 documentation_parsing
6315         : DOC_SEE doc_cref
6316           {
6317                 module.DocumentationBuilder.ParsedName = (MemberName) $2;
6318           }
6319         ;
6320
6321 doc_cref
6322         : doc_type_declaration_name opt_doc_method_sig
6323           {
6324                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$2;
6325           }
6326         | builtin_types opt_doc_method_sig
6327           {
6328                 module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
6329                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$2;
6330                 $$ = null;
6331           }
6332         | builtin_types DOT IDENTIFIER opt_doc_method_sig
6333           {
6334                 module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
6335                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$4;
6336                 var lt = (Tokenizer.LocatedToken) $3;
6337                 $$ = new MemberName (lt.Value);
6338           }
6339         | doc_type_declaration_name DOT THIS
6340           {
6341                 $$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
6342           }
6343         | doc_type_declaration_name DOT THIS OPEN_BRACKET
6344           {
6345                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
6346           }
6347           opt_doc_parameters CLOSE_BRACKET
6348           {
6349                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$6;
6350                 $$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
6351           }
6352         | EXPLICIT OPERATOR type opt_doc_method_sig
6353           {
6354                 var p = (List<DocumentationParameter>)$4 ?? new List<DocumentationParameter> (1);
6355                 p.Add (new DocumentationParameter ((FullNamedExpression) $3));
6356                 module.DocumentationBuilder.ParsedParameters = p;
6357                 module.DocumentationBuilder.ParsedOperator = Operator.OpType.Explicit;
6358                 $$ = null;
6359           }
6360         | IMPLICIT OPERATOR type opt_doc_method_sig
6361           {
6362                 var p = (List<DocumentationParameter>)$4 ?? new List<DocumentationParameter> (1);
6363                 p.Add (new DocumentationParameter ((FullNamedExpression) $3));
6364                 module.DocumentationBuilder.ParsedParameters = p;
6365                 module.DocumentationBuilder.ParsedOperator = Operator.OpType.Implicit;
6366                 $$ = null;
6367           }       
6368         | OPERATOR overloadable_operator opt_doc_method_sig
6369           {
6370                 var p = (List<DocumentationParameter>)$3 ?? new List<DocumentationParameter> (1);
6371                 module.DocumentationBuilder.ParsedParameters = p;
6372                 module.DocumentationBuilder.ParsedOperator = (Operator.OpType) $2;
6373                 $$ = null;
6374           }
6375         ;
6376         
6377 doc_type_declaration_name
6378         : type_declaration_name
6379         | doc_type_declaration_name DOT type_declaration_name
6380           {
6381                 $$ = new MemberName (((MemberName) $1), (MemberName) $3);
6382           }
6383         ;
6384         
6385 opt_doc_method_sig
6386         : /* empty */
6387         | OPEN_PARENS
6388           {
6389                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
6390           }
6391           opt_doc_parameters CLOSE_PARENS
6392           {
6393                 $$ = $3;
6394           }
6395         ;
6396         
6397 opt_doc_parameters
6398         : /* empty */
6399           {
6400                 $$ = new List<DocumentationParameter> (0);
6401           }
6402         | doc_parameters
6403         ;
6404         
6405 doc_parameters
6406         : doc_parameter
6407           {
6408                 var parameters = new List<DocumentationParameter> ();
6409                 parameters.Add ((DocumentationParameter) $1);
6410                 $$ = parameters;
6411           }
6412         | doc_parameters COMMA doc_parameter
6413           {
6414                 var parameters = $1 as List<DocumentationParameter>;
6415                 parameters.Add ((DocumentationParameter) $3);
6416                 $$ = parameters;
6417           }
6418         ;
6419         
6420 doc_parameter
6421         : opt_parameter_modifier parameter_type
6422           {
6423                 if ($1 != null)
6424                         $$ = new DocumentationParameter ((Parameter.Modifier) $1, (FullNamedExpression) $2);
6425                 else
6426                         $$ = new DocumentationParameter ((FullNamedExpression) $2);
6427           }
6428         ;
6429         
6430 %%
6431
6432 // <summary>
6433 //  A class used to hold info about an operator declarator
6434 // </summary>
6435 class OperatorDeclaration {
6436         public readonly Operator.OpType optype;
6437         public readonly FullNamedExpression ret_type;
6438         public readonly Location location;
6439
6440         public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
6441         {
6442                 optype = op;
6443                 this.ret_type = ret_type;
6444                 this.location = location;
6445         }
6446 }
6447
6448 void Error_ExpectingTypeName (Expression expr)
6449 {
6450         if (expr is Invocation){
6451                 report.Error (1002, expr.Location, "Expecting `;'");
6452         } else {
6453                 Expression.Error_InvalidExpressionStatement (report, expr.Location);
6454         }
6455 }
6456
6457 void Error_ParameterModifierNotValid (string modifier, Location loc)
6458 {
6459         report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
6460                                       modifier);
6461 }
6462
6463 void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
6464 {
6465         report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
6466                 Parameter.GetModifierSignature (mod));
6467 }
6468
6469 void Error_TypeExpected (Location loc)
6470 {
6471         report.Error (1031, loc, "Type expected");
6472 }
6473
6474 void Error_UnsafeCodeNotAllowed (Location loc)
6475 {
6476         report.Error (227, loc, "Unsafe code requires the `unsafe' command line option to be specified");
6477 }
6478
6479 void Warning_EmptyStatement (Location loc)
6480 {
6481         report.Warning (642, 3, loc, "Possible mistaken empty statement");
6482 }
6483
6484 void Error_NamedArgumentExpected (NamedArgument a)
6485 {
6486         report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
6487 }
6488
6489 void Error_MissingInitializer (Location loc)
6490 {
6491         report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration");
6492 }
6493
6494 void push_current_container (TypeDefinition tc, object partial_token)
6495 {
6496         if (module.Evaluator != null){
6497                 tc.Definition.Modifiers = tc.ModFlags = (tc.ModFlags & ~Modifiers.AccessibilityMask) | Modifiers.PUBLIC;
6498                 if (undo == null)
6499                         undo = new Undo ();
6500
6501                 undo.AddTypeContainer (current_container, tc);
6502         }
6503         
6504         if (partial_token != null)
6505                 current_container.AddPartial (tc);
6506         else
6507                 current_container.AddTypeContainer (tc);
6508                 
6509         ++lexer.parsing_declaration;
6510         current_container = tc;
6511         current_type = tc;
6512 }
6513
6514 TypeContainer pop_current_class ()
6515 {
6516         var retval = current_container;
6517
6518         current_container = current_container.Parent;
6519         current_type = current_type.Parent as TypeDefinition;
6520
6521         return retval;
6522 }
6523
6524 [System.Diagnostics.Conditional ("FULL_AST")]
6525 void StoreModifierLocation (object token, Location loc)
6526 {
6527         if (lbag == null)
6528                 return;
6529
6530         if (mod_locations == null)
6531                 mod_locations = new List<Tuple<Modifiers, Location>> ();
6532
6533         mod_locations.Add (Tuple.Create ((Modifiers) token, loc));
6534 }
6535
6536 string CheckAttributeTarget (string a, Location l)
6537 {
6538         switch (a) {
6539         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
6540                         return a;
6541         }
6542
6543         report.Warning (658, 1, l,
6544                  "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
6545         return string.Empty;
6546 }
6547
6548 static bool IsUnaryOperator (Operator.OpType op)
6549 {
6550         switch (op) {
6551                 
6552         case Operator.OpType.LogicalNot: 
6553         case Operator.OpType.OnesComplement: 
6554         case Operator.OpType.Increment:
6555         case Operator.OpType.Decrement:
6556         case Operator.OpType.True: 
6557         case Operator.OpType.False: 
6558         case Operator.OpType.UnaryPlus: 
6559         case Operator.OpType.UnaryNegation:
6560                 return true;
6561         }
6562         return false;
6563 }
6564
6565 void syntax_error (Location l, string msg)
6566 {
6567         report.Error (1003, l, "Syntax error, " + msg);
6568 }
6569
6570 Tokenizer lexer;
6571
6572 public Tokenizer Lexer {
6573         get {
6574                 return lexer;
6575         }
6576 }                  
6577
6578 public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, ParserSession session)
6579         : this (reader, file, file.Compiler.Report, session)
6580 {
6581 }
6582
6583 public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report, ParserSession session)
6584 {
6585         this.file = file;
6586         current_container = current_namespace = file;
6587         
6588         this.module = file.Module;
6589         this.compiler = file.Compiler;
6590         this.settings = compiler.Settings;
6591         this.report = report;
6592         
6593         lang_version = settings.Version;
6594         yacc_verbose_flag = settings.VerboseParserFlag;
6595         doc_support = settings.DocumentationFile != null;
6596         lexer = new Tokenizer (reader, file, session);
6597         oob_stack = new Stack<object> ();
6598         lbag = session.LocationsBag;
6599         use_global_stacks = session.UseJayGlobalArrays;
6600         parameters_bucket = session.ParametersStack;
6601 }
6602
6603 public void parse ()
6604 {
6605         eof_token = Token.EOF;
6606         
6607         try {
6608                 if (yacc_verbose_flag > 1)
6609                         yyparse (lexer, new yydebug.yyDebugSimple ());
6610                 else
6611                         yyparse (lexer);
6612                         
6613                 Tokenizer tokenizer = lexer as Tokenizer;
6614                 tokenizer.cleanup ();           
6615         } catch (Exception e){
6616                 if (e is yyParser.yyUnexpectedEof) {
6617                         Error_SyntaxError (yyToken);
6618                         UnexpectedEOF = true;
6619                         return;
6620                 }
6621                         
6622                 if (e is yyParser.yyException) {
6623                         report.Error (-25, lexer.Location, "Parsing error");
6624                 } else {
6625                         // Used by compiler-tester to test internal errors
6626                         if (yacc_verbose_flag > 0 || e is FatalException)
6627                                 throw;
6628                 
6629                         report.Error (589, lexer.Location, "Internal compiler error during parsing" + e);
6630                 }
6631         }
6632 }
6633
6634 void CheckToken (int error, int yyToken, string msg, Location loc)
6635 {
6636         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
6637                 report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken));
6638         else
6639                 report.Error (error, loc, msg);
6640 }
6641
6642 string ConsumeStoredComment ()
6643 {
6644         string s = tmpComment;
6645         tmpComment = null;
6646         Lexer.doc_state = XmlCommentState.Allowed;
6647         return s;
6648 }
6649
6650 void FeatureIsNotAvailable (Location loc, string feature)
6651 {
6652         report.FeatureIsNotAvailable (compiler, loc, feature);
6653 }
6654
6655 Location GetLocation (object obj)
6656 {
6657         var lt = obj as Tokenizer.LocatedToken;
6658         if (lt != null)
6659                 return lt.Location;
6660                 
6661         var mn = obj as MemberName;
6662         if (mn != null)
6663                 return mn.Location;
6664                 
6665         var expr = obj as Expression;
6666         if (expr != null)
6667                 return expr.Location;
6668
6669         return lexer.Location;
6670 }
6671
6672 void start_block (Location loc)
6673 {
6674         if (current_block == null) {
6675                 current_block = new ToplevelBlock (compiler, current_local_parameters, loc);
6676                 parsing_anonymous_method = false;
6677         } else if (parsing_anonymous_method) {
6678                 current_block = new ParametersBlock (current_block, current_local_parameters, loc);
6679                 parsing_anonymous_method = false;
6680         } else {
6681                 current_block = new ExplicitBlock (current_block, loc, Location.Null);
6682         }
6683 }
6684
6685 Block
6686 end_block (Location loc)
6687 {
6688         Block retval = current_block.Explicit;
6689         retval.SetEndLocation (loc);
6690         current_block = retval.Parent;
6691         return retval;
6692 }
6693
6694 void start_anonymous (bool isLambda, ParametersCompiled parameters, bool isAsync, Location loc)
6695 {
6696         oob_stack.Push (current_anonymous_method);
6697         oob_stack.Push (current_local_parameters);
6698         oob_stack.Push (current_variable);
6699         oob_stack.Push (async_block);
6700
6701         current_local_parameters = parameters;
6702         if (isLambda) {
6703                 if (lang_version <= LanguageVersion.ISO_2)
6704                         FeatureIsNotAvailable (loc, "lambda expressions");
6705
6706                 current_anonymous_method = new LambdaExpression (loc);
6707         } else {
6708                 if (lang_version == LanguageVersion.ISO_1)
6709                         FeatureIsNotAvailable (loc, "anonymous methods");
6710                         
6711                 current_anonymous_method = new AnonymousMethodExpression (loc);
6712         }
6713
6714         async_block = isAsync;
6715         // Force the next block to be created as a ToplevelBlock
6716         parsing_anonymous_method = true;
6717 }
6718
6719 /*
6720  * Completes the anonymous method processing, if lambda_expr is null, this
6721  * means that we have a Statement instead of an Expression embedded 
6722  */
6723 AnonymousMethodExpression end_anonymous (ParametersBlock anon_block)
6724 {
6725         AnonymousMethodExpression retval;
6726
6727         if (async_block)
6728                 anon_block.IsAsync = true;
6729
6730         current_anonymous_method.Block = anon_block;
6731         retval = current_anonymous_method;
6732
6733         async_block = (bool) oob_stack.Pop ();
6734         current_variable = (BlockVariableDeclaration) oob_stack.Pop ();
6735         current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
6736         current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
6737
6738         return retval;
6739 }
6740
6741 void Error_SyntaxError (int token)
6742 {
6743         Error_SyntaxError (0, token);
6744 }
6745
6746 void Error_SyntaxError (int error_code, int token)
6747 {
6748         Error_SyntaxError (error_code, token, "Unexpected symbol");
6749 }
6750
6751 void Error_SyntaxError (int error_code, int token, string msg)
6752 {
6753         Lexer.CompleteOnEOF = false;
6754
6755         // An error message has been reported by tokenizer
6756         if (token == Token.ERROR)
6757                 return;
6758
6759         string symbol = GetSymbolName (token);
6760         string expecting = GetExpecting ();
6761         var loc = lexer.Location - symbol.Length;
6762         
6763         if (error_code == 0) {
6764                 if (expecting == "`identifier'") {
6765                         if (token > Token.FIRST_KEYWORD && token < Token.LAST_KEYWORD) {
6766                                 report.Error (1041, loc, "Identifier expected, `{0}' is a keyword", symbol);
6767                                 return;
6768                         }
6769                         
6770                         error_code = 1001;
6771                         expecting = "identifier";
6772                 } else if (expecting == "`)'") {
6773                         error_code = 1026;
6774                 } else {
6775                         error_code = 1525;
6776                 }
6777         }
6778         
6779         if (string.IsNullOrEmpty (expecting))
6780                 report.Error (error_code, loc, "{1} `{0}'", symbol, msg);
6781         else
6782                 report.Error (error_code, loc, "{2} `{0}', expecting {1}", symbol, expecting, msg);       
6783 }
6784
6785 string GetExpecting ()
6786 {
6787         int [] tokens = yyExpectingTokens (yyExpectingState);
6788         var names = new List<string> (tokens.Length);
6789         bool has_type = false;
6790         bool has_identifier = false;
6791         for (int i = 0; i < tokens.Length; i++){
6792                 int token = tokens [i];
6793                 has_identifier |= token == Token.IDENTIFIER;
6794                 
6795                 string name = GetTokenName (token);
6796                 if (name == "<internal>")
6797                         continue;
6798                         
6799                 has_type |= name == "type";
6800                 if (names.Contains (name))
6801                         continue;
6802                 
6803                 names.Add (name);
6804         }
6805
6806         //
6807         // Too many tokens to enumerate
6808         //
6809         if (names.Count > 8)
6810                 return null;
6811
6812         if (has_type && has_identifier)
6813                 names.Remove ("identifier");
6814
6815         if (names.Count == 1)
6816                 return "`" + GetTokenName (tokens [0]) + "'";
6817         
6818         StringBuilder sb = new StringBuilder ();
6819         names.Sort ();
6820         int count = names.Count;
6821         for (int i = 0; i < count; i++){
6822                 bool last = i + 1 == count;
6823                 if (last)
6824                         sb.Append ("or ");
6825                 sb.Append ('`');
6826                 sb.Append (names [i]);
6827                 sb.Append (last ? "'" : count < 3 ? "' " : "', ");
6828         }
6829         return sb.ToString ();
6830 }
6831
6832
6833 string GetSymbolName (int token)
6834 {
6835         switch (token){
6836         case Token.LITERAL:
6837                 return ((Constant)lexer.Value).GetValue ().ToString ();
6838         case Token.IDENTIFIER:
6839                 return ((Tokenizer.LocatedToken)lexer.Value).Value;
6840
6841         case Token.BOOL:
6842                 return "bool";
6843         case Token.BYTE:
6844                 return "byte";
6845         case Token.CHAR:
6846                 return "char";
6847         case Token.VOID:
6848                 return "void";
6849         case Token.DECIMAL:
6850                 return "decimal";
6851         case Token.DOUBLE:
6852                 return "double";
6853         case Token.FLOAT:
6854                 return "float";
6855         case Token.INT:
6856                 return "int";
6857         case Token.LONG:
6858                 return "long";
6859         case Token.SBYTE:
6860                 return "sbyte";
6861         case Token.SHORT:
6862                 return "short";
6863         case Token.STRING:
6864                 return "string";
6865         case Token.UINT:
6866                 return "uint";
6867         case Token.ULONG:
6868                 return "ulong";
6869         case Token.USHORT:
6870                 return "ushort";
6871         case Token.OBJECT:
6872                 return "object";
6873                 
6874         case Token.PLUS:
6875                 return "+";
6876         case Token.UMINUS:
6877         case Token.MINUS:
6878                 return "-";
6879         case Token.BANG:
6880                 return "!";
6881         case Token.BITWISE_AND:
6882                 return "&";
6883         case Token.BITWISE_OR:
6884                 return "|";
6885         case Token.STAR:
6886                 return "*";
6887         case Token.PERCENT:
6888                 return "%";
6889         case Token.DIV:
6890                 return "/";
6891         case Token.CARRET:
6892                 return "^";
6893         case Token.OP_INC:
6894                 return "++";
6895         case Token.OP_DEC:
6896                 return "--";
6897         case Token.OP_SHIFT_LEFT:
6898                 return "<<";
6899         case Token.OP_SHIFT_RIGHT:
6900                 return ">>";
6901         case Token.OP_LT:
6902                 return "<";
6903         case Token.OP_GT:
6904                 return ">";
6905         case Token.OP_LE:
6906                 return "<=";
6907         case Token.OP_GE:
6908                 return ">=";
6909         case Token.OP_EQ:
6910                 return "==";
6911         case Token.OP_NE:
6912                 return "!=";
6913         case Token.OP_AND:
6914                 return "&&";
6915         case Token.OP_OR:
6916                 return "||";
6917         case Token.OP_PTR:
6918                 return "->";
6919         case Token.OP_COALESCING:       
6920                 return "??";
6921         case Token.OP_MULT_ASSIGN:
6922                 return "*=";
6923         case Token.OP_DIV_ASSIGN:
6924                 return "/=";
6925         case Token.OP_MOD_ASSIGN:
6926                 return "%=";
6927         case Token.OP_ADD_ASSIGN:
6928                 return "+=";
6929         case Token.OP_SUB_ASSIGN:
6930                 return "-=";
6931         case Token.OP_SHIFT_LEFT_ASSIGN:
6932                 return "<<=";
6933         case Token.OP_SHIFT_RIGHT_ASSIGN:
6934                 return ">>=";
6935         case Token.OP_AND_ASSIGN:
6936                 return "&=";
6937         case Token.OP_XOR_ASSIGN:
6938                 return "^=";
6939         case Token.OP_OR_ASSIGN:
6940                 return "|=";
6941         }
6942
6943         return GetTokenName (token);
6944 }
6945
6946 static string GetTokenName (int token)
6947 {
6948         switch (token){
6949         case Token.ABSTRACT:
6950                 return "abstract";
6951         case Token.AS:
6952                 return "as";
6953         case Token.ADD:
6954                 return "add";
6955         case Token.ASYNC:
6956                 return "async";
6957         case Token.BASE:
6958                 return "base";
6959         case Token.BREAK:
6960                 return "break";
6961         case Token.CASE:
6962                 return "case";
6963         case Token.CATCH:
6964                 return "catch";
6965         case Token.CHECKED:
6966                 return "checked";
6967         case Token.CLASS:
6968                 return "class";
6969         case Token.CONST:
6970                 return "const";
6971         case Token.CONTINUE:
6972                 return "continue";
6973         case Token.DEFAULT:
6974                 return "default";
6975         case Token.DELEGATE:
6976                 return "delegate";
6977         case Token.DO:
6978                 return "do";
6979         case Token.ELSE:
6980                 return "else";
6981         case Token.ENUM:
6982                 return "enum";
6983         case Token.EVENT:
6984                 return "event";
6985         case Token.EXPLICIT:
6986                 return "explicit";
6987         case Token.EXTERN:
6988         case Token.EXTERN_ALIAS:
6989                 return "extern";
6990         case Token.FALSE:
6991                 return "false";
6992         case Token.FINALLY:
6993                 return "finally";
6994         case Token.FIXED:
6995                 return "fixed";
6996         case Token.FOR:
6997                 return "for";
6998         case Token.FOREACH:
6999                 return "foreach";
7000         case Token.GOTO:
7001                 return "goto";
7002         case Token.IF:
7003                 return "if";
7004         case Token.IMPLICIT:
7005                 return "implicit";
7006         case Token.IN:
7007                 return "in";
7008         case Token.INTERFACE:
7009                 return "interface";
7010         case Token.INTERNAL:
7011                 return "internal";
7012         case Token.IS:
7013                 return "is";
7014         case Token.LOCK:
7015                 return "lock";
7016         case Token.NAMESPACE:
7017                 return "namespace";
7018         case Token.NEW:
7019                 return "new";
7020         case Token.NULL:
7021                 return "null";
7022         case Token.OPERATOR:
7023                 return "operator";
7024         case Token.OUT:
7025                 return "out";
7026         case Token.OVERRIDE:
7027                 return "override";
7028         case Token.PARAMS:
7029                 return "params";
7030         case Token.PRIVATE:
7031                 return "private";
7032         case Token.PROTECTED:
7033                 return "protected";
7034         case Token.PUBLIC:
7035                 return "public";
7036         case Token.READONLY:
7037                 return "readonly";
7038         case Token.REF:
7039                 return "ref";
7040         case Token.RETURN:
7041                 return "return";
7042         case Token.REMOVE:
7043                 return "remove";
7044         case Token.SEALED:
7045                 return "sealed";
7046         case Token.SIZEOF:
7047                 return "sizeof";
7048         case Token.STACKALLOC:
7049                 return "stackalloc";
7050         case Token.STATIC:
7051                 return "static";
7052         case Token.STRUCT:
7053                 return "struct";
7054         case Token.SWITCH:
7055                 return "switch";
7056         case Token.THIS:
7057                 return "this";
7058         case Token.THROW:
7059                 return "throw";
7060         case Token.TRUE:
7061                 return "true";
7062         case Token.TRY:
7063                 return "try";
7064         case Token.TYPEOF:
7065                 return "typeof";
7066         case Token.UNCHECKED:
7067                 return "unchecked";
7068         case Token.UNSAFE:
7069                 return "unsafe";
7070         case Token.USING:
7071                 return "using";
7072         case Token.VIRTUAL:
7073                 return "virtual";
7074         case Token.VOLATILE:
7075                 return "volatile";
7076         case Token.WHERE:
7077                 return "where";
7078         case Token.WHILE:
7079                 return "while";
7080         case Token.ARGLIST:
7081                 return "__arglist";
7082         case Token.REFVALUE:
7083                 return "__refvalue";
7084         case Token.REFTYPE:
7085                 return "__reftype";
7086         case Token.MAKEREF:
7087                 return "__makeref";
7088         case Token.PARTIAL:
7089                 return "partial";
7090         case Token.ARROW:
7091                 return "=>";
7092         case Token.FROM:
7093         case Token.FROM_FIRST:
7094                 return "from";
7095         case Token.JOIN:
7096                 return "join";
7097         case Token.ON:
7098                 return "on";
7099         case Token.EQUALS:
7100                 return "equals";
7101         case Token.SELECT:
7102                 return "select";
7103         case Token.GROUP:
7104                 return "group";
7105         case Token.BY:
7106                 return "by";
7107         case Token.LET:
7108                 return "let";
7109         case Token.ORDERBY:
7110                 return "orderby";
7111         case Token.ASCENDING:
7112                 return "ascending";
7113         case Token.DESCENDING:
7114                 return "descending";
7115         case Token.INTO:
7116                 return "into";
7117         case Token.GET:
7118                 return "get";
7119         case Token.SET:
7120                 return "set";
7121         case Token.OPEN_BRACE:
7122                 return "{";
7123         case Token.CLOSE_BRACE:
7124                 return "}";
7125         case Token.OPEN_BRACKET:
7126         case Token.OPEN_BRACKET_EXPR:
7127                 return "[";
7128         case Token.CLOSE_BRACKET:
7129                 return "]";
7130         case Token.OPEN_PARENS_CAST:
7131         case Token.OPEN_PARENS_LAMBDA:
7132         case Token.OPEN_PARENS:
7133                 return "(";
7134         case Token.CLOSE_PARENS:
7135                 return ")";
7136         case Token.DOT:
7137                 return ".";
7138         case Token.COMMA:
7139                 return ",";
7140         case Token.DEFAULT_COLON:
7141                 return "default:";
7142         case Token.COLON:
7143                 return ":";
7144         case Token.SEMICOLON:
7145                 return ";";
7146         case Token.TILDE:
7147                 return "~";
7148                 
7149         case Token.PLUS:
7150         case Token.UMINUS:
7151         case Token.MINUS:
7152         case Token.BANG:
7153         case Token.OP_LT:
7154         case Token.OP_GT:
7155         case Token.BITWISE_AND:
7156         case Token.BITWISE_OR:
7157         case Token.STAR:
7158         case Token.PERCENT:
7159         case Token.DIV:
7160         case Token.CARRET:
7161         case Token.OP_INC:
7162         case Token.OP_DEC:
7163         case Token.OP_SHIFT_LEFT:
7164         case Token.OP_SHIFT_RIGHT:
7165         case Token.OP_LE:
7166         case Token.OP_GE:
7167         case Token.OP_EQ:
7168         case Token.OP_NE:
7169         case Token.OP_AND:
7170         case Token.OP_OR:
7171         case Token.OP_PTR:
7172         case Token.OP_COALESCING:       
7173         case Token.OP_MULT_ASSIGN:
7174         case Token.OP_DIV_ASSIGN:
7175         case Token.OP_MOD_ASSIGN:
7176         case Token.OP_ADD_ASSIGN:
7177         case Token.OP_SUB_ASSIGN:
7178         case Token.OP_SHIFT_LEFT_ASSIGN:
7179         case Token.OP_SHIFT_RIGHT_ASSIGN:
7180         case Token.OP_AND_ASSIGN:
7181         case Token.OP_XOR_ASSIGN:
7182         case Token.OP_OR_ASSIGN:
7183                 return "<operator>";
7184
7185         case Token.BOOL:
7186         case Token.BYTE:
7187         case Token.CHAR:
7188         case Token.VOID:
7189         case Token.DECIMAL:
7190         case Token.DOUBLE:
7191         case Token.FLOAT:
7192         case Token.INT:
7193         case Token.LONG:
7194         case Token.SBYTE:
7195         case Token.SHORT:
7196         case Token.STRING:
7197         case Token.UINT:
7198         case Token.ULONG:
7199         case Token.USHORT:
7200         case Token.OBJECT:
7201                 return "type";
7202         
7203         case Token.ASSIGN:
7204                 return "=";
7205         case Token.OP_GENERICS_LT:
7206         case Token.GENERIC_DIMENSION:
7207                 return "<";
7208         case Token.OP_GENERICS_GT:
7209                 return ">";
7210         case Token.INTERR:
7211         case Token.INTERR_NULLABLE:
7212                 return "?";
7213         case Token.DOUBLE_COLON:
7214                 return "::";
7215         case Token.LITERAL:
7216                 return "value";
7217         case Token.IDENTIFIER:
7218         case Token.AWAIT:
7219                 return "identifier";
7220
7221         case Token.EOF:
7222                 return "end-of-file";
7223
7224                 // All of these are internal.
7225         case Token.NONE:
7226         case Token.ERROR:
7227         case Token.FIRST_KEYWORD:
7228         case Token.EVAL_COMPILATION_UNIT_PARSER:
7229         case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER:
7230         case Token.EVAL_STATEMENT_PARSER:
7231         case Token.LAST_KEYWORD:
7232         case Token.GENERATE_COMPLETION:
7233         case Token.COMPLETE_COMPLETION:
7234                 return "<internal>";
7235
7236                 // A bit more robust.
7237         default:
7238                 return yyNames [token];
7239         }
7240 }
7241
7242 /* end end end */
7243 }