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