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