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