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