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