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