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