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