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