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