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