Merge pull request #347 from JamesB7/master
[mono.git] / mcs / mcs / cs-parser.jay
1 %{
2 //
3 // cs-parser.jay: The Parser for the C# compiler
4 //
5 // Authors: Miguel de Icaza (miguel@gnome.org)
6 //          Ravi Pratap     (ravi@ximian.com)
7 //          Marek Safar     (marek.safar@gmail.com)
8 //
9 // Dual Licensed under the terms of the GNU GPL and the MIT X11 license
10 //
11 // (C) 2001 Ximian, Inc (http://www.ximian.com)
12 // (C) 2004-2011 Novell, Inc
13 // Copyright 2011-2012 Xamarin Inc.
14 //
15
16 using System.Text;
17 using System.IO;
18 using System;
19 using System.Collections.Generic;
20
21 namespace Mono.CSharp
22 {
23         /// <summary>
24         ///    The C# Parser
25         /// </summary>
26         public class CSharpParser
27         {
28                 [Flags]
29                 enum ParameterModifierType
30                 {
31                         Ref             = 1 << 1,
32                         Out             = 1 << 2,
33                         This    = 1 << 3,
34                         Params  = 1 << 4,
35                         Arglist = 1 << 5,
36                         DefaultValue = 1 << 6,
37                         
38                         All = Ref | Out | This | Params | Arglist | DefaultValue
39                 }
40                 
41                 static readonly object ModifierNone = 0;
42         
43                 NamespaceContainer current_namespace;
44                 TypeContainer current_container;
45                 TypeDefinition current_type;
46                 PropertyBase current_property;
47                 EventProperty current_event;
48                 EventField current_event_field;
49                 FieldBase current_field;
50         
51                 /// <summary>
52                 ///   Current block is used to add statements as we find
53                 ///   them.  
54                 /// </summary>
55                 Block      current_block;
56                 
57                 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                 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                 List<Parameter> parameters_bucket;
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         | opt_attributes IDENTIFIER error
2576           {
2577                 Error_SyntaxError (yyToken);
2578           
2579                 var lt = (Tokenizer.LocatedToken) $2;
2580                 var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
2581                 ((Enum) current_type).AddEnumMember (em);
2582
2583                 if (doc_support) {
2584                         em.DocComment = Lexer.consume_doc_comment ();
2585                         Lexer.doc_state = XmlCommentState.Allowed;
2586                 }
2587
2588                 $$ = em;
2589           }
2590         | attributes_without_members
2591         ;
2592
2593 delegate_declaration
2594         : opt_attributes
2595           opt_modifiers
2596           DELEGATE
2597           member_type type_declaration_name
2598           OPEN_PARENS
2599           {
2600                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue;
2601           }
2602           opt_formal_parameter_list CLOSE_PARENS
2603           {
2604                 valid_param_mod = 0;
2605
2606                 ParametersCompiled p = (ParametersCompiled) $8;
2607
2608                 Delegate del = new Delegate (current_container, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, p, (Attributes) $1);
2609
2610                 p.CheckParameters (del);
2611
2612                 current_container.AddTypeContainer (del);
2613
2614                 current_delegate = del;
2615                 lexer.ConstraintsParsing = true;
2616           }
2617           opt_type_parameter_constraints_clauses
2618           {
2619                 lexer.ConstraintsParsing = false;
2620           }
2621           SEMICOLON
2622           {
2623                 if (doc_support) {
2624                         current_delegate.DocComment = Lexer.consume_doc_comment ();
2625                         Lexer.doc_state = XmlCommentState.Allowed;
2626                 }
2627           
2628                 if ($11 != null)
2629                         current_delegate.SetConstraints ((List<Constraints>) $11);
2630                 lbag.AddMember (current_delegate, mod_locations, GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($13));
2631
2632                 $$ = current_delegate;
2633
2634                 current_delegate = null;
2635           }
2636         ;
2637
2638 opt_nullable
2639         : /* empty */
2640         | INTERR_NULLABLE
2641           {
2642                 if (lang_version < LanguageVersion.ISO_2)
2643                         FeatureIsNotAvailable (GetLocation ($1), "nullable types");
2644           
2645                 $$ = ComposedTypeSpecifier.CreateNullable (GetLocation ($1));
2646           }
2647         ;
2648
2649 namespace_or_type_expr
2650         : member_name
2651         | qualified_alias_member IDENTIFIER opt_type_argument_list
2652           {
2653                 var lt1 = (Tokenizer.LocatedToken) $1;
2654                 var lt2 = (Tokenizer.LocatedToken) $2;
2655                 
2656                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
2657                 lbag.AddLocation ($$, GetLocation ($2));
2658           }
2659         ;
2660
2661 member_name
2662         : simple_name_expr
2663         | namespace_or_type_expr DOT IDENTIFIER opt_type_argument_list
2664           {
2665                 var lt = (Tokenizer.LocatedToken) $3;
2666                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
2667                 lbag.AddLocation ($$, GetLocation ($2));
2668           }
2669         ;
2670
2671 simple_name_expr
2672         : IDENTIFIER opt_type_argument_list
2673           {
2674                 var lt = (Tokenizer.LocatedToken) $1;
2675                 $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);
2676           }
2677         ;
2678         
2679 //
2680 // Generics arguments  (any type, without attributes)
2681 //
2682 opt_type_argument_list
2683         : /* empty */
2684         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2685           {
2686                 if (lang_version < LanguageVersion.ISO_2)
2687                         FeatureIsNotAvailable (GetLocation ($1), "generics");     
2688           
2689                 $$ = $2;
2690           }
2691         | OP_GENERICS_LT error
2692           {
2693                 Error_TypeExpected (lexer.Location);
2694                 $$ = new TypeArguments ();
2695           }
2696         ;
2697
2698 type_arguments
2699         : type
2700           {
2701                 TypeArguments type_args = new TypeArguments ();
2702                 type_args.Add ((FullNamedExpression) $1);
2703                 $$ = type_args;
2704           }
2705         | type_arguments COMMA type
2706           {
2707                 TypeArguments type_args = (TypeArguments) $1;
2708                 type_args.Add ((FullNamedExpression) $3);
2709                 $$ = type_args;
2710           }       
2711         ;
2712
2713 //
2714 // Generics parameters (identifiers only, with attributes), used in type or method declarations
2715 //
2716 type_declaration_name
2717         : IDENTIFIER
2718           {
2719                 lexer.parsing_generic_declaration = true;
2720           }
2721           opt_type_parameter_list
2722           {
2723                 lexer.parsing_generic_declaration = false;
2724                 var lt = (Tokenizer.LocatedToken) $1;
2725                 $$ = new MemberName (lt.Value, (TypeParameters)$3, lt.Location);
2726           }
2727         ;
2728
2729 member_declaration_name
2730         : method_declaration_name
2731           {
2732                 MemberName mn = (MemberName)$1;
2733                 if (mn.TypeParameters != null)
2734                         syntax_error (mn.Location, string.Format ("Member `{0}' cannot declare type arguments",
2735                                 mn.GetSignatureForError ()));
2736           }
2737         ;
2738
2739 method_declaration_name
2740         : type_declaration_name
2741         | explicit_interface IDENTIFIER opt_type_parameter_list
2742           {
2743                 lexer.parsing_generic_declaration = false;        
2744                 var lt = (Tokenizer.LocatedToken) $2;
2745                 $$ = new MemberName (lt.Value, (TypeParameters) $3, (ATypeNameExpression) $1, lt.Location);
2746           }
2747         ;
2748         
2749 indexer_declaration_name
2750         : THIS
2751           {
2752                 lexer.parsing_generic_declaration = false;        
2753                 $$ = new MemberName (TypeDefinition.DefaultIndexerName, GetLocation ($1));
2754           }
2755         | explicit_interface THIS
2756           {
2757                 lexer.parsing_generic_declaration = false;
2758                 $$ = new MemberName (TypeDefinition.DefaultIndexerName, null, (ATypeNameExpression) $1, GetLocation ($2));
2759           }
2760         ;
2761
2762 explicit_interface
2763         : IDENTIFIER opt_type_argument_list DOT
2764           {
2765                 var lt = (Tokenizer.LocatedToken) $1;
2766                 $$ = new SimpleName (lt.Value, (TypeArguments) $2, lt.Location);
2767                 lbag.AddLocation ($$, GetLocation ($3));
2768           }
2769         | qualified_alias_member IDENTIFIER opt_type_argument_list DOT
2770           {
2771                 var lt1 = (Tokenizer.LocatedToken) $1;
2772                 var lt2 = (Tokenizer.LocatedToken) $2;
2773
2774                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
2775                 lbag.AddLocation ($$, GetLocation ($4));
2776           }
2777         | explicit_interface IDENTIFIER opt_type_argument_list DOT
2778           {
2779                 var lt = (Tokenizer.LocatedToken) $2;
2780                 $$ = new MemberAccess ((ATypeNameExpression) $1, lt.Value, (TypeArguments) $3, lt.Location);
2781                 lbag.AddLocation ($$, GetLocation ($4));
2782           }
2783         ;
2784         
2785 opt_type_parameter_list
2786         : /* empty */
2787         | OP_GENERICS_LT_DECL type_parameters OP_GENERICS_GT
2788           {
2789                 if (lang_version < LanguageVersion.ISO_2)
2790                         FeatureIsNotAvailable (GetLocation ($1), "generics");
2791           
2792                 $$ = $2;
2793                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
2794           }
2795         ;
2796
2797 type_parameters
2798         : type_parameter
2799           {
2800                 var tparams = new TypeParameters ();
2801                 tparams.Add ((TypeParameter)$1);
2802                 $$ = tparams;
2803           }
2804         | type_parameters COMMA type_parameter
2805           {
2806                 var tparams = (TypeParameters) $1;
2807                 tparams.Add ((TypeParameter)$3);
2808                 $$ = tparams;
2809                 lbag.AddLocation ($3, GetLocation ($3));
2810           }       
2811         ;
2812
2813 type_parameter
2814         : opt_attributes opt_type_parameter_variance IDENTIFIER
2815           {
2816                 var lt = (Tokenizer.LocatedToken)$3;
2817                 $$ = new TypeParameter (new MemberName (lt.Value, lt.Location), (Attributes)$1, (Variance) $2);
2818           }
2819         | error
2820           {
2821                 if (GetTokenName (yyToken) == "type")
2822                         report.Error (81, GetLocation ($1), "Type parameter declaration must be an identifier not a type");
2823                 else
2824                         Error_SyntaxError (yyToken);
2825                         
2826                 $$ = new TypeParameter (MemberName.Null, null, Variance.None);
2827           }
2828         ;
2829
2830 //
2831 // All types where void is allowed
2832 //
2833 type_and_void
2834         : type_expression_or_array
2835         | VOID
2836           {
2837                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
2838           }
2839         ;
2840         
2841 member_type
2842         : type_and_void
2843           {
2844                 lexer.parsing_generic_declaration = true;
2845           }
2846         ;
2847         
2848 //
2849 // A type which does not allow `void' to be used
2850 //
2851 type
2852         : type_expression_or_array
2853         | VOID
2854           {
2855                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
2856                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
2857           }     
2858         ;
2859         
2860 simple_type
2861         : type_expression
2862         | VOID
2863           {
2864                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
2865                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
2866           }     
2867         ;
2868         
2869 parameter_type
2870         : type_expression_or_array
2871         | VOID
2872           {
2873                 report.Error (1536, GetLocation ($1), "Invalid parameter type `void'");
2874                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
2875           }     
2876         ;
2877
2878 type_expression_or_array
2879         : type_expression
2880         | type_expression rank_specifiers
2881           {
2882                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
2883           }
2884         ;
2885         
2886 type_expression
2887         : namespace_or_type_expr opt_nullable
2888           {
2889                 if ($2 != null) {
2890                         $$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
2891                 } else {
2892                         var sn = $1 as SimpleName;
2893                         if (sn != null && sn.Name == "var")
2894                                 $$ = new VarExpr (sn.Location);
2895                         else
2896                                 $$ = $1;
2897                 }
2898           }
2899         | namespace_or_type_expr pointer_stars
2900           {
2901                 $$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
2902           }
2903         | builtin_types opt_nullable
2904           {
2905                 if ($2 != null)
2906                         $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
2907           }
2908         | builtin_types pointer_stars
2909           {
2910                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
2911           }
2912         | VOID pointer_stars
2913           {
2914                 $$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
2915           }
2916         ;
2917
2918 type_list
2919         : base_type_name
2920           {
2921                 var types = new List<FullNamedExpression> (2);
2922                 types.Add ((FullNamedExpression) $1);
2923                 $$ = types;
2924           }
2925         | type_list COMMA base_type_name
2926           {
2927                 var types = (List<FullNamedExpression>) $1;
2928                 types.Add ((FullNamedExpression) $3);
2929                 $$ = types;
2930           }
2931         ;
2932
2933 base_type_name
2934         : type
2935           {
2936                 if ($1 is ComposedCast) {
2937                         report.Error (1521, GetLocation ($1), "Invalid base type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
2938                 }
2939                 $$ = $1;
2940           }
2941         ;
2942         
2943 /*
2944  * replaces all the productions for isolating the various
2945  * simple types, but we need this to reuse it easily in variable_type
2946  */
2947 builtin_types
2948         : OBJECT        { $$ = new TypeExpression (compiler.BuiltinTypes.Object, GetLocation ($1)); }
2949         | STRING        { $$ = new TypeExpression (compiler.BuiltinTypes.String, GetLocation ($1)); }
2950         | BOOL          { $$ = new TypeExpression (compiler.BuiltinTypes.Bool, GetLocation ($1)); }
2951         | DECIMAL       { $$ = new TypeExpression (compiler.BuiltinTypes.Decimal, GetLocation ($1)); }
2952         | FLOAT         { $$ = new TypeExpression (compiler.BuiltinTypes.Float, GetLocation ($1)); }
2953         | DOUBLE        { $$ = new TypeExpression (compiler.BuiltinTypes.Double, GetLocation ($1)); }
2954         | integral_type
2955         ;
2956
2957 integral_type
2958         : SBYTE         { $$ = new TypeExpression (compiler.BuiltinTypes.SByte, GetLocation ($1)); }
2959         | BYTE          { $$ = new TypeExpression (compiler.BuiltinTypes.Byte, GetLocation ($1)); }
2960         | SHORT         { $$ = new TypeExpression (compiler.BuiltinTypes.Short, GetLocation ($1)); }
2961         | USHORT        { $$ = new TypeExpression (compiler.BuiltinTypes.UShort, GetLocation ($1)); }
2962         | INT           { $$ = new TypeExpression (compiler.BuiltinTypes.Int, GetLocation ($1)); }
2963         | UINT          { $$ = new TypeExpression (compiler.BuiltinTypes.UInt, GetLocation ($1)); }
2964         | LONG          { $$ = new TypeExpression (compiler.BuiltinTypes.Long, GetLocation ($1)); }
2965         | ULONG         { $$ = new TypeExpression (compiler.BuiltinTypes.ULong, GetLocation ($1)); }
2966         | CHAR          { $$ = new TypeExpression (compiler.BuiltinTypes.Char, GetLocation ($1)); }
2967         ;
2968
2969 //
2970 // Expressions, section 7.5
2971 //
2972
2973
2974 primary_expression
2975         : primary_expression_or_type
2976         | literal
2977         | array_creation_expression
2978         | parenthesized_expression
2979         | default_value_expression
2980         | invocation_expression
2981         | element_access
2982         | this_access
2983         | base_access
2984         | post_increment_expression
2985         | post_decrement_expression
2986         | object_or_delegate_creation_expression
2987         | anonymous_type_expression
2988         | typeof_expression
2989         | sizeof_expression
2990         | checked_expression
2991         | unchecked_expression
2992         | pointer_member_access
2993         | anonymous_method_expression
2994         | undocumented_expressions
2995         ;
2996
2997 primary_expression_or_type
2998         : IDENTIFIER opt_type_argument_list
2999           {
3000                 var lt = (Tokenizer.LocatedToken) $1;
3001                 $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);   
3002           }
3003         | IDENTIFIER GENERATE_COMPLETION {
3004                 var lt = (Tokenizer.LocatedToken) $1;
3005                $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location);
3006           }
3007         | member_access
3008         ;
3009
3010 literal
3011         : boolean_literal
3012         | LITERAL
3013         | NULL                  { $$ = new NullLiteral (GetLocation ($1)); }
3014         ;
3015
3016 boolean_literal
3017         : TRUE                  { $$ = new BoolLiteral (compiler.BuiltinTypes, true, GetLocation ($1)); }
3018         | FALSE                 { $$ = new BoolLiteral (compiler.BuiltinTypes, false, GetLocation ($1)); }
3019         ;
3020
3021
3022 //
3023 // Here is the trick, tokenizer may think that parens is a special but
3024 // parser is interested in open parens only, so we merge them.
3025 // Consider: if (a)foo ();
3026 //
3027 open_parens_any
3028         : OPEN_PARENS
3029         | OPEN_PARENS_CAST
3030         ;
3031
3032 // 
3033 // Use this production to accept closing parenthesis or 
3034 // performing completion
3035 //
3036 close_parens
3037         : CLOSE_PARENS
3038         | COMPLETE_COMPLETION
3039         ;
3040
3041
3042 parenthesized_expression
3043         : OPEN_PARENS expression CLOSE_PARENS
3044           {
3045                 $$ = new ParenthesizedExpression ((Expression) $2);
3046                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
3047           }
3048         | OPEN_PARENS expression COMPLETE_COMPLETION
3049           {
3050                 $$ = new ParenthesizedExpression ((Expression) $2);
3051           }
3052         ;
3053         
3054 member_access
3055         : primary_expression DOT IDENTIFIER opt_type_argument_list
3056           {
3057                 var lt = (Tokenizer.LocatedToken) $3;
3058                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3059                 lbag.AddLocation ($$, GetLocation ($2));
3060           }
3061         | builtin_types DOT IDENTIFIER opt_type_argument_list
3062           {
3063                 var lt = (Tokenizer.LocatedToken) $3;
3064                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3065                 lbag.AddLocation ($$, GetLocation ($2));
3066           }
3067         | BASE DOT IDENTIFIER opt_type_argument_list
3068           {
3069                 var lt = (Tokenizer.LocatedToken) $3;
3070                 $$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location);
3071                 lbag.AddLocation ($$, GetLocation ($2));
3072           }
3073         | qualified_alias_member IDENTIFIER opt_type_argument_list
3074           {
3075                 var lt1 = (Tokenizer.LocatedToken) $1;
3076                 var lt2 = (Tokenizer.LocatedToken) $2;
3077
3078                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
3079                 lbag.AddLocation ($$, GetLocation ($2));
3080           }
3081         | primary_expression DOT GENERATE_COMPLETION {
3082                 $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3));
3083           }
3084         | primary_expression DOT IDENTIFIER GENERATE_COMPLETION {
3085                 var lt = (Tokenizer.LocatedToken) $3;
3086                 $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
3087           }
3088         | builtin_types DOT GENERATE_COMPLETION
3089           {
3090                 $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location);
3091           }
3092         | builtin_types DOT IDENTIFIER GENERATE_COMPLETION {
3093                 var lt = (Tokenizer.LocatedToken) $3;
3094                 $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
3095           }
3096         ;
3097
3098 invocation_expression
3099         : primary_expression open_parens_any opt_argument_list close_parens
3100           {
3101                 $$ = new Invocation ((Expression) $1, (Arguments) $3);
3102                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3103           }
3104         | primary_expression open_parens_any argument_list error
3105           {
3106                 Error_SyntaxError (yyToken);
3107
3108                 $$ = new Invocation ((Expression) $1, (Arguments) $3);
3109                 lbag.AddLocation ($$, GetLocation ($2));
3110           }
3111         
3112         ;
3113
3114 opt_object_or_collection_initializer
3115         : /* empty */           { $$ = null; }
3116         | object_or_collection_initializer
3117         ;
3118
3119 object_or_collection_initializer
3120         : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion
3121           {
3122                 if ($2 == null) {
3123                         $$ = CollectionOrObjectInitializers.Empty;
3124                         // TODO: lbag
3125                 } else {
3126                         $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
3127                         lbag.AddLocation ($$, GetLocation ($3));
3128                 }
3129           }
3130         | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE
3131           {
3132                 $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
3133                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4));
3134           }
3135         ;
3136
3137 opt_member_initializer_list
3138         : /* empty */           { $$ = null; }
3139         | member_initializer_list
3140         {
3141                 $$ = $1;
3142         }
3143         ;
3144
3145 member_initializer_list
3146         : member_initializer
3147           {
3148                 var a = new List<Expression> ();
3149                 a.Add ((Expression) $1);
3150                 $$ = a;
3151           }
3152         | member_initializer_list COMMA member_initializer
3153           {
3154                 var a = (List<Expression>)$1;
3155                 a.Add ((Expression) $3);
3156                 $$ = a;
3157           }
3158         | member_initializer_list error {
3159                 Error_SyntaxError (yyToken);
3160                 $$ = $1;
3161           }
3162         ;
3163
3164 member_initializer
3165         : IDENTIFIER ASSIGN initializer_value
3166           {
3167                 var lt = (Tokenizer.LocatedToken) $1;
3168                 $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
3169                 lbag.AddLocation ($$, GetLocation ($2));
3170           }
3171         | GENERATE_COMPLETION 
3172           {
3173                 $$ = new CompletionElementInitializer (null, GetLocation ($1));
3174           }
3175         | non_assignment_expression opt_COMPLETE_COMPLETION  {
3176                 CompletionSimpleName csn = $1 as CompletionSimpleName;
3177                 if (csn == null)
3178                         $$ = new CollectionElementInitializer ((Expression)$1);
3179                 else
3180                         $$ = new CompletionElementInitializer (csn.Prefix, csn.Location);
3181           }
3182         | OPEN_BRACE expression_list CLOSE_BRACE
3183           {
3184                 if ($2 == null)
3185                         $$ = null;
3186                 else
3187                         $$ = new CollectionElementInitializer ((List<Expression>)$2, GetLocation ($1));
3188           }
3189         | OPEN_BRACE CLOSE_BRACE
3190           {
3191                 report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
3192                 $$ = null;
3193           }       
3194         ;
3195
3196 initializer_value
3197         : expression
3198         | object_or_collection_initializer
3199         ;
3200
3201 opt_argument_list
3202         : /* empty */           { $$ = null; }
3203         | argument_list
3204         ;
3205
3206 argument_list
3207         : argument_or_named_argument
3208           { 
3209                 Arguments list = new Arguments (4);
3210                 list.Add ((Argument) $1);
3211                 $$ = list;
3212           }
3213         | argument_list COMMA argument
3214           {
3215                 Arguments list = (Arguments) $1;
3216                 if (list [list.Count - 1] is NamedArgument)
3217                         Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]);
3218                 
3219                 list.Add ((Argument) $3);
3220                 $$ = list;
3221           }
3222         | argument_list COMMA named_argument
3223           {
3224                 Arguments list = (Arguments) $1;
3225                 NamedArgument a = (NamedArgument) $3;
3226                 for (int i = 0; i < list.Count; ++i) {
3227                         NamedArgument na = list [i] as NamedArgument;
3228                         if (na != null && na.Name == a.Name)
3229                                 report.Error (1740, na.Location, "Named argument `{0}' specified multiple times",
3230                                         na.Name);
3231                 }
3232                 
3233                 list.Add (a);
3234                 $$ = list;
3235           }
3236         | argument_list COMMA error
3237           {
3238                 lexer.putback (')'); // TODO: Wrong but what can I do
3239                 Error_SyntaxError (yyToken);
3240                 $$ = $1;
3241           }
3242         | COMMA error
3243           {
3244                 report.Error (839, GetLocation ($1), "An argument is missing");
3245                 $$ = null;
3246           }
3247         ;
3248
3249 argument
3250         : expression
3251           {
3252                 $$ = new Argument ((Expression) $1);
3253           }
3254         | non_simple_argument
3255         ;
3256
3257 argument_or_named_argument
3258         : argument
3259         | named_argument
3260         ;
3261
3262 non_simple_argument
3263         : REF variable_reference 
3264           { 
3265                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3266                 lbag.AddLocation ($$, GetLocation ($1));
3267           }
3268         | OUT variable_reference 
3269           { 
3270                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
3271                 lbag.AddLocation ($$, GetLocation ($1));
3272           }
3273         | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
3274           {
3275                 $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1)));
3276                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3277           }
3278         | ARGLIST OPEN_PARENS CLOSE_PARENS
3279           {
3280                 $$ = new Argument (new Arglist (GetLocation ($1)));
3281                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
3282           }       
3283         ;
3284
3285 variable_reference
3286         : expression
3287         ;
3288
3289 element_access
3290         : primary_expression OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET  
3291           {
3292                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
3293                 lbag.AddLocation ($$, GetLocation ($4));
3294           }
3295         | primary_expression OPEN_BRACKET_EXPR expression_list_arguments error
3296           {
3297                 Error_SyntaxError (yyToken);
3298                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
3299           }
3300         | primary_expression OPEN_BRACKET_EXPR error
3301           {
3302                 Error_SyntaxError (yyToken);
3303                 $$ = new ElementAccess ((Expression) $1, null, GetLocation ($2));
3304           }
3305         ;
3306
3307 expression_list
3308         : expression
3309           {
3310                 var list = new List<Expression> (4);
3311                 list.Add ((Expression) $1);
3312                 $$ = list;
3313           }
3314         | expression_list COMMA expression
3315           {
3316                 var list = (List<Expression>) $1;
3317                 list.Add ((Expression) $3);
3318                 $$ = list;
3319           }
3320         | expression_list error {
3321                 Error_SyntaxError (yyToken);
3322                 $$ = $1;
3323           }
3324         ;
3325         
3326 expression_list_arguments
3327         : expression_list_argument
3328           {
3329                 Arguments args = new Arguments (4);
3330                 args.Add ((Argument) $1);
3331                 $$ = args;
3332           }
3333         | expression_list_arguments COMMA expression_list_argument
3334           {
3335                 Arguments args = (Arguments) $1;
3336                 if (args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
3337                         Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
3338           
3339                 args.Add ((Argument) $3);
3340                 $$ = args;        
3341           }
3342         ;
3343         
3344 expression_list_argument
3345         : expression
3346           {
3347                 $$ = new Argument ((Expression) $1);
3348           }
3349         | named_argument
3350         ;
3351
3352 this_access
3353         : THIS
3354           {
3355                 $$ = new This (GetLocation ($1));
3356           }
3357         ;
3358
3359 base_access
3360         : BASE OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
3361           {
3362                 $$ = new ElementAccess (new BaseThis (GetLocation ($1)), (Arguments) $3, GetLocation ($2));
3363                 lbag.AddLocation ($$, GetLocation ($4));
3364           }
3365         | BASE OPEN_BRACKET error
3366           {
3367                 Error_SyntaxError (yyToken);
3368                 $$ = new ElementAccess (null, null, GetLocation ($2));
3369           }
3370         ;
3371
3372 post_increment_expression
3373         : primary_expression OP_INC
3374           {
3375                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1, GetLocation ($2));
3376           }
3377         ;
3378
3379 post_decrement_expression
3380         : primary_expression OP_DEC
3381           {
3382                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1, GetLocation ($2));
3383           }
3384         ;
3385         
3386 object_or_delegate_creation_expression
3387         : NEW new_expr_type open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer
3388           {
3389                 if ($6 != null) {
3390                         if (lang_version <= LanguageVersion.ISO_2)
3391                                 FeatureIsNotAvailable (GetLocation ($1), "object initializers");
3392                                 
3393                         $$ = new NewInitialize ((FullNamedExpression) $2, (Arguments) $4, (CollectionOrObjectInitializers) $6, GetLocation ($1));
3394                 } else {
3395                         $$ = new New ((FullNamedExpression) $2, (Arguments) $4, GetLocation ($1));
3396                 }
3397                 
3398                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3399           }
3400         | NEW new_expr_type object_or_collection_initializer
3401           {
3402                 if (lang_version <= LanguageVersion.ISO_2)
3403                         FeatureIsNotAvailable (GetLocation ($1), "collection initializers");
3404           
3405                 $$ = new NewInitialize ((FullNamedExpression) $2, null, (CollectionOrObjectInitializers) $3, GetLocation ($1));
3406           }
3407         ;
3408
3409 array_creation_expression
3410         : NEW new_expr_type OPEN_BRACKET_EXPR expression_list CLOSE_BRACKET
3411           opt_rank_specifier
3412           opt_array_initializer
3413           {
3414                 $$ = new ArrayCreation ((FullNamedExpression) $2, (List<Expression>) $4,
3415                                 new ComposedTypeSpecifier (((List<Expression>) $4).Count, GetLocation ($3)) {
3416                                         Next = (ComposedTypeSpecifier) $6
3417                                 }, (ArrayInitializer) $7, GetLocation ($1));
3418                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3419           }
3420         | NEW new_expr_type rank_specifiers opt_array_initializer
3421           {
3422                 if ($4 == null)
3423                         report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer");
3424
3425                 $$ = new ArrayCreation ((FullNamedExpression) $2, (ComposedTypeSpecifier) $3, (ArrayInitializer) $4, GetLocation ($1));
3426           }
3427         | NEW rank_specifier array_initializer
3428           {
3429                 if (lang_version <= LanguageVersion.ISO_2)
3430                         FeatureIsNotAvailable (GetLocation ($1), "implicitly typed arrays");
3431           
3432                 $$ = new ImplicitlyTypedArrayCreation ((ComposedTypeSpecifier) $2, (ArrayInitializer) $3, GetLocation ($1));
3433           }
3434         | NEW new_expr_type OPEN_BRACKET CLOSE_BRACKET OPEN_BRACKET_EXPR error CLOSE_BRACKET
3435           {
3436                 report.Error (178, GetLocation ($6), "Invalid rank specifier, expecting `,' or `]'");
3437                 $$ = new ArrayCreation ((FullNamedExpression) $2, null, GetLocation ($1));
3438           }
3439         | NEW new_expr_type error
3440           {
3441                 Error_SyntaxError (yyToken);
3442                 // It can be any of new expression, create the most common one
3443                 $$ = new New ((FullNamedExpression) $2, null, GetLocation ($1));
3444           }
3445         ;
3446
3447 new_expr_type
3448         : {
3449                 ++lexer.parsing_type;
3450           }
3451           simple_type
3452           {
3453                 --lexer.parsing_type;
3454                 $$ = $2;
3455           }
3456         ;
3457
3458 anonymous_type_expression
3459         : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
3460           {
3461                 if (lang_version <= LanguageVersion.ISO_2)
3462                         FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
3463
3464                 $$ = new NewAnonymousType ((List<AnonymousTypeParameter>) $3, current_container, GetLocation ($1));
3465                 
3466                 // TODO: lbag comma location
3467                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3468           }
3469         ;
3470
3471 anonymous_type_parameters_opt_comma
3472         : anonymous_type_parameters_opt
3473         | anonymous_type_parameters COMMA
3474         ;
3475
3476 anonymous_type_parameters_opt
3477         : { $$ = null; }
3478         | anonymous_type_parameters
3479         ;
3480
3481 anonymous_type_parameters
3482         : anonymous_type_parameter
3483           {
3484                 var a = new List<AnonymousTypeParameter> (4);
3485                 a.Add ((AnonymousTypeParameter) $1);
3486                 $$ = a;
3487           }
3488         | anonymous_type_parameters COMMA anonymous_type_parameter
3489           {
3490                 var a = (List<AnonymousTypeParameter>) $1;
3491                 a.Add ((AnonymousTypeParameter) $3);
3492                 $$ = a;
3493           }
3494         ;
3495
3496 anonymous_type_parameter
3497         : IDENTIFIER ASSIGN variable_initializer
3498           {
3499                 var lt = (Tokenizer.LocatedToken)$1;
3500                 $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
3501                 lbag.AddLocation ($$, GetLocation ($2));
3502           }
3503         | IDENTIFIER
3504           {
3505                 var lt = (Tokenizer.LocatedToken)$1;
3506                 $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
3507                         lt.Value, lt.Location);
3508           }
3509         | member_access
3510           {
3511                 MemberAccess ma = (MemberAccess) $1;
3512                 $$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
3513           }
3514         | error
3515           {
3516                 report.Error (746, lexer.Location,
3517                         "Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression");
3518                 $$ = null;
3519           }
3520         ;
3521
3522 opt_rank_specifier
3523         : /* empty */
3524         | rank_specifiers
3525         ;
3526
3527 rank_specifiers
3528         : rank_specifier
3529         | rank_specifier rank_specifiers
3530           {
3531                 ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
3532                 $$ = $1;
3533           }
3534         ;
3535
3536 rank_specifier
3537         : OPEN_BRACKET CLOSE_BRACKET
3538           {
3539                 $$ = ComposedTypeSpecifier.CreateArrayDimension (1, GetLocation ($1));
3540                 lbag.AddLocation ($$, GetLocation ($2));
3541           }
3542         | OPEN_BRACKET dim_separators CLOSE_BRACKET
3543           {
3544                 $$ = ComposedTypeSpecifier.CreateArrayDimension ((int)$2, GetLocation ($1));
3545                 lbag.AddLocation ($$, GetLocation ($3));
3546           }
3547         ;
3548
3549 dim_separators
3550         : COMMA
3551           {
3552                 $$ = 2;
3553           }
3554         | dim_separators COMMA
3555           {
3556                 $$ = ((int) $1) + 1;
3557           }
3558         ;
3559
3560 opt_array_initializer
3561         : /* empty */
3562           {
3563                 $$ = null;
3564           }
3565         | array_initializer
3566           {
3567                 $$ = $1;
3568           }
3569         ;
3570
3571 array_initializer
3572         : OPEN_BRACE CLOSE_BRACE
3573           {
3574                 var ai = new ArrayInitializer (0, GetLocation ($1));
3575                 ai.VariableDeclaration = current_variable;
3576                 lbag.AddLocation (ai, GetLocation ($2));
3577                 $$ = ai;
3578           }
3579         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
3580           {
3581                 var ai = new ArrayInitializer ((List<Expression>) $2, GetLocation ($1));
3582                 ai.VariableDeclaration = current_variable;
3583                 if ($3 != null) {
3584                         lbag.AddLocation (ai, GetLocation ($3), GetLocation ($4));
3585                 } else {
3586                         lbag.AddLocation (ai, GetLocation ($4));
3587                 }
3588                 $$ = ai;
3589           }
3590         ;
3591
3592 variable_initializer_list
3593         : variable_initializer
3594           {
3595                 var list = new List<Expression> (4);
3596                 list.Add ((Expression) $1);
3597                 $$ = list;
3598           }
3599         | variable_initializer_list COMMA variable_initializer
3600           {
3601                 var list = (List<Expression>) $1;
3602                 list.Add ((Expression) $3);
3603                 $$ = list;
3604           }
3605         ;
3606
3607 typeof_expression
3608         : TYPEOF
3609       {
3610                 lexer.TypeOfParsing = true;
3611           }
3612           open_parens_any typeof_type_expression CLOSE_PARENS
3613           {
3614                 lexer.TypeOfParsing = false;
3615                 $$ = new TypeOf ((FullNamedExpression) $4, GetLocation ($1));
3616                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
3617           }
3618         ;
3619         
3620 typeof_type_expression
3621         : type_and_void
3622         | unbound_type_name
3623         | error
3624          {
3625                 Error_TypeExpected (lexer.Location);
3626                 $$ = null;
3627          }
3628         ;
3629         
3630 unbound_type_name
3631         : identifier_inside_body generic_dimension
3632           {  
3633                 var lt = (Tokenizer.LocatedToken) $1;
3634
3635                 $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
3636           }
3637         | qualified_alias_member identifier_inside_body generic_dimension
3638           {
3639                 var lt1 = (Tokenizer.LocatedToken) $1;
3640                 var lt2 = (Tokenizer.LocatedToken) $2;
3641
3642                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
3643                 lbag.AddLocation ($$, GetLocation ($2));
3644           }
3645         | unbound_type_name DOT identifier_inside_body
3646           {
3647                 var lt = (Tokenizer.LocatedToken) $3;
3648                 
3649                 $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);         
3650           }
3651         | unbound_type_name DOT identifier_inside_body generic_dimension
3652           {
3653                 var lt = (Tokenizer.LocatedToken) $3;
3654                 
3655                 $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);               
3656           }
3657         | namespace_or_type_expr DOT identifier_inside_body generic_dimension
3658           {
3659                 var tne = (ATypeNameExpression) $1;
3660                 if (tne.HasTypeArguments)
3661                         Error_TypeExpected (GetLocation ($4));
3662
3663                 var lt = (Tokenizer.LocatedToken) $3;
3664                 $$ = new MemberAccess (tne, lt.Value, (int) $4, lt.Location);           
3665           }
3666         ;
3667
3668 generic_dimension
3669         : GENERIC_DIMENSION
3670           {
3671                 if (lang_version < LanguageVersion.ISO_2)
3672                         FeatureIsNotAvailable (GetLocation ($1), "generics");
3673
3674                 $$ = $1;
3675           }
3676         ;
3677         
3678 qualified_alias_member
3679         : IDENTIFIER DOUBLE_COLON
3680           {
3681                 var lt = (Tokenizer.LocatedToken) $1;
3682                 if (lang_version == LanguageVersion.ISO_1)
3683                         FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
3684
3685                 $$ = lt;                
3686           }
3687         ;
3688
3689 sizeof_expression
3690         : SIZEOF open_parens_any type CLOSE_PARENS
3691           { 
3692                 $$ = new SizeOf ((Expression) $3, GetLocation ($1));
3693                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3694           }
3695         ;
3696
3697 checked_expression
3698         : CHECKED open_parens_any expression CLOSE_PARENS
3699           {
3700                 $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
3701                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3702           }
3703         ;
3704
3705 unchecked_expression
3706         : UNCHECKED open_parens_any expression CLOSE_PARENS
3707           {
3708                 $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
3709                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3710           }
3711         ;
3712
3713 pointer_member_access
3714         : primary_expression OP_PTR IDENTIFIER opt_type_argument_list
3715           {
3716                 var lt = (Tokenizer.LocatedToken) $3;
3717                 $$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, (TypeArguments) $4, lt.Location);
3718           }
3719         ;
3720
3721 anonymous_method_expression
3722         : DELEGATE opt_anonymous_method_signature
3723           {
3724                 start_anonymous (false, (ParametersCompiled) $2, false, GetLocation ($1));
3725           }
3726           block
3727           {
3728                 $$ = end_anonymous ((ParametersBlock) $4);
3729           }
3730         | ASYNC DELEGATE opt_anonymous_method_signature
3731           {
3732                 start_anonymous (false, (ParametersCompiled) $3, true, GetLocation ($1));
3733           }
3734           block
3735           {
3736                 $$ = end_anonymous ((ParametersBlock) $5);
3737           }
3738         ;
3739
3740 opt_anonymous_method_signature
3741         : 
3742           {
3743                 $$ = ParametersCompiled.Undefined;
3744           } 
3745         | anonymous_method_signature
3746         ;
3747
3748 anonymous_method_signature
3749         : OPEN_PARENS
3750           {
3751                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
3752           }
3753           opt_formal_parameter_list CLOSE_PARENS
3754           {
3755                 valid_param_mod = 0;
3756                 $$ = $3;
3757           }
3758         ;
3759
3760 default_value_expression
3761         : DEFAULT open_parens_any type CLOSE_PARENS
3762           {
3763                 if (lang_version < LanguageVersion.ISO_2)
3764                         FeatureIsNotAvailable (GetLocation ($1), "default value expression");
3765
3766                 $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1));
3767                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3768           }
3769         ;
3770
3771 unary_expression
3772         : primary_expression
3773         | BANG prefixed_unary_expression
3774           {
3775                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1));
3776           }
3777         | TILDE prefixed_unary_expression
3778           {
3779                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
3780           }
3781         | OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
3782           {
3783                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3784                 lbag.AddLocation ($$, GetLocation ($3));
3785           }
3786         | AWAIT prefixed_unary_expression
3787           {
3788                 if (!async_block) {
3789                          if (current_anonymous_method is LambdaExpression) {
3790                                 report.Error (4034, GetLocation ($1),
3791                                         "The `await' operator can only be used when its containing lambda expression is marked with the `async' modifier");
3792                         } else if (current_anonymous_method is AnonymousMethodExpression) {
3793                                 report.Error (4035, GetLocation ($1),
3794                                         "The `await' operator can only be used when its containing anonymous method is marked with the `async' modifier");
3795                         } else {
3796                                 report.Error (4033, GetLocation ($1),
3797                                         "The `await' operator can only be used when its containing method is marked with the `async' modifier");
3798                         }
3799                 } else {
3800                         current_block.Explicit.RegisterAsyncAwait ();
3801                 }
3802                 
3803                 $$ = new Await ((Expression) $2, GetLocation ($1));
3804           }
3805         ;
3806
3807         //
3808         // The idea to split this out is from Rhys' grammar
3809         // to solve the problem with casts.
3810         //
3811 prefixed_unary_expression
3812         : unary_expression
3813         | PLUS prefixed_unary_expression
3814           { 
3815                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
3816           } 
3817         | MINUS prefixed_unary_expression 
3818           { 
3819                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
3820           }
3821         | OP_INC prefixed_unary_expression 
3822           {
3823                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1));
3824           }
3825         | OP_DEC prefixed_unary_expression 
3826           {
3827                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1));
3828           }
3829         | STAR prefixed_unary_expression
3830           {
3831                 $$ = new Indirection ((Expression) $2, GetLocation ($1));
3832           }
3833         | BITWISE_AND prefixed_unary_expression
3834           {
3835                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1));
3836           }
3837         ;
3838
3839 multiplicative_expression
3840         : prefixed_unary_expression
3841         | multiplicative_expression STAR prefixed_unary_expression
3842           {
3843                 $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
3844                 lbag.AddLocation ($$, GetLocation ($2));
3845           }
3846         | multiplicative_expression DIV prefixed_unary_expression
3847           {
3848                 $$ = new Binary (Binary.Operator.Division, (Expression) $1, (Expression) $3);
3849                 lbag.AddLocation ($$, GetLocation ($2));
3850           }
3851         | multiplicative_expression PERCENT prefixed_unary_expression 
3852           {
3853                 $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
3854                 lbag.AddLocation ($$, GetLocation ($2));
3855           }
3856         ;
3857
3858 additive_expression
3859         : multiplicative_expression
3860         | additive_expression PLUS multiplicative_expression 
3861           {
3862                 $$ = new Binary (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
3863                 lbag.AddLocation ($$, GetLocation ($2));
3864           }
3865         | additive_expression MINUS multiplicative_expression
3866           {
3867                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
3868                 lbag.AddLocation ($$, GetLocation ($2));
3869           }
3870         | additive_expression AS type
3871           {
3872                 $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
3873           }
3874         | additive_expression IS type
3875           {
3876                 $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
3877           }       
3878         ;
3879
3880 shift_expression
3881         : additive_expression
3882         | shift_expression OP_SHIFT_LEFT additive_expression
3883           {
3884                 $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
3885                 lbag.AddLocation ($$, GetLocation ($2));
3886           }
3887         | shift_expression OP_SHIFT_RIGHT additive_expression
3888           {
3889                 $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
3890                 lbag.AddLocation ($$, GetLocation ($2));
3891           }
3892         ; 
3893
3894 relational_expression
3895         : shift_expression
3896         | relational_expression OP_LT shift_expression
3897           {
3898                 $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, (Expression) $3);
3899                 lbag.AddLocation ($$, GetLocation ($2));
3900           }
3901         | relational_expression OP_GT shift_expression
3902           {
3903                 $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, (Expression) $3);
3904                 lbag.AddLocation ($$, GetLocation ($2));
3905           }
3906         | relational_expression OP_LE shift_expression
3907           {
3908                 $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, (Expression) $3);
3909                 lbag.AddLocation ($$, GetLocation ($2));
3910           }
3911         | relational_expression OP_GE shift_expression
3912           {
3913                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3);
3914                 lbag.AddLocation ($$, GetLocation ($2));
3915           }
3916         ;
3917
3918 equality_expression
3919         : relational_expression
3920         | equality_expression OP_EQ relational_expression
3921           {
3922                 $$ = new Binary (Binary.Operator.Equality, (Expression) $1, (Expression) $3);
3923                 lbag.AddLocation ($$, GetLocation ($2));
3924           }
3925         | equality_expression OP_NE relational_expression
3926           {
3927                 $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, (Expression) $3);
3928                 lbag.AddLocation ($$, GetLocation ($2));
3929           }
3930         ; 
3931
3932 and_expression
3933         : equality_expression
3934         | and_expression BITWISE_AND equality_expression
3935           {
3936                 $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
3937                 lbag.AddLocation ($$, GetLocation ($2));
3938           }
3939         ;
3940
3941 exclusive_or_expression
3942         : and_expression
3943         | exclusive_or_expression CARRET and_expression
3944           {
3945                 $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
3946                 lbag.AddLocation ($$, GetLocation ($2));
3947           }
3948         ;
3949
3950 inclusive_or_expression
3951         : exclusive_or_expression
3952         | inclusive_or_expression BITWISE_OR exclusive_or_expression
3953           {
3954                 $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
3955                 lbag.AddLocation ($$, GetLocation ($2));
3956           }
3957         ;
3958
3959 conditional_and_expression
3960         : inclusive_or_expression
3961         | conditional_and_expression OP_AND inclusive_or_expression
3962           {
3963                 $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3);
3964                 lbag.AddLocation ($$, GetLocation ($2));
3965           }
3966         ;
3967
3968 conditional_or_expression
3969         : conditional_and_expression
3970         | conditional_or_expression OP_OR conditional_and_expression
3971           {
3972                 $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3);
3973                 lbag.AddLocation ($$, GetLocation ($2));
3974           }
3975         ;
3976         
3977 null_coalescing_expression
3978         : conditional_or_expression
3979         | conditional_or_expression OP_COALESCING null_coalescing_expression
3980           {
3981                 if (lang_version < LanguageVersion.ISO_2)
3982                         FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
3983                         
3984                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3);
3985                 lbag.AddLocation ($$, GetLocation ($2));
3986           }
3987         ;
3988
3989 conditional_expression
3990         : null_coalescing_expression
3991         | null_coalescing_expression INTERR expression COLON expression_or_error
3992           {
3993                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
3994                 lbag.AddLocation ($$, GetLocation ($4));
3995           }
3996         | null_coalescing_expression INTERR expression error
3997           {
3998                 Error_SyntaxError (yyToken);
3999                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
4000           }
4001         ;
4002
4003 assignment_expression
4004         : prefixed_unary_expression ASSIGN expression
4005           {
4006                 $$ = new SimpleAssign ((Expression) $1, (Expression) $3);
4007                 lbag.AddLocation ($$, GetLocation ($2));
4008           }
4009         | prefixed_unary_expression OP_MULT_ASSIGN expression
4010           {
4011                 $$ = new CompoundAssign (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
4012                 lbag.AddLocation ($$, GetLocation ($2));
4013           }
4014         | prefixed_unary_expression OP_DIV_ASSIGN expression
4015           {
4016                 $$ = new CompoundAssign (Binary.Operator.Division, (Expression) $1, (Expression) $3);
4017                 lbag.AddLocation ($$, GetLocation ($2));
4018           }
4019         | prefixed_unary_expression OP_MOD_ASSIGN expression
4020           {
4021                 $$ = new CompoundAssign (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
4022                 lbag.AddLocation ($$, GetLocation ($2));
4023           }
4024         | prefixed_unary_expression OP_ADD_ASSIGN expression
4025           {
4026                 $$ = new CompoundAssign (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
4027                 lbag.AddLocation ($$, GetLocation ($2));
4028           }
4029         | prefixed_unary_expression OP_SUB_ASSIGN expression
4030           {
4031                 $$ = new CompoundAssign (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
4032                 lbag.AddLocation ($$, GetLocation ($2));
4033           }
4034         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
4035           {
4036                 $$ = new CompoundAssign (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
4037                 lbag.AddLocation ($$, GetLocation ($2));
4038           }
4039         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
4040           {
4041                 $$ = new CompoundAssign (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
4042                 lbag.AddLocation ($$, GetLocation ($2));
4043           }
4044         | prefixed_unary_expression OP_AND_ASSIGN expression
4045           {
4046                 $$ = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
4047                 lbag.AddLocation ($$, GetLocation ($2));
4048           }
4049         | prefixed_unary_expression OP_OR_ASSIGN expression
4050           {
4051                 $$ = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
4052                 lbag.AddLocation ($$, GetLocation ($2));
4053           }
4054         | prefixed_unary_expression OP_XOR_ASSIGN expression
4055           {
4056                 $$ = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
4057                 lbag.AddLocation ($$, GetLocation ($2));
4058           }
4059         ;
4060
4061 lambda_parameter_list
4062         : lambda_parameter
4063           {
4064                 var pars = new List<Parameter> (4);
4065                 pars.Add ((Parameter) $1);
4066
4067                 $$ = pars;
4068           }
4069         | lambda_parameter_list COMMA lambda_parameter
4070           {
4071                 var pars = (List<Parameter>) $1;
4072                 Parameter p = (Parameter)$3;
4073                 if (pars[0].GetType () != p.GetType ()) {
4074                         report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
4075                 }
4076                 
4077                 pars.Add (p);
4078                 $$ = pars;
4079           }
4080         ;
4081
4082 lambda_parameter
4083         : parameter_modifier parameter_type identifier_inside_body
4084           {
4085                 var lt = (Tokenizer.LocatedToken) $3;
4086
4087                 $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
4088           }
4089         | parameter_type identifier_inside_body
4090           {
4091                 var lt = (Tokenizer.LocatedToken) $2;
4092
4093                 $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
4094           }
4095         | IDENTIFIER
4096           {
4097                 var lt = (Tokenizer.LocatedToken) $1;
4098                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
4099           }
4100         ;
4101
4102 opt_lambda_parameter_list
4103         : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
4104         | lambda_parameter_list         { 
4105                 var pars_list = (List<Parameter>) $1;
4106                 $$ = new ParametersCompiled (pars_list.ToArray ());
4107           }
4108         ;
4109
4110 lambda_expression_body
4111         : lambda_expression_body_simple
4112         | block
4113         ;
4114         
4115 lambda_expression_body_simple
4116         : {
4117                 start_block (Location.Null);
4118           }
4119           expression_or_error   // Have to close block when error occurs
4120           {
4121                 Block b = end_block (Location.Null);
4122                 b.IsCompilerGenerated = true;
4123                 b.AddStatement (new ContextualReturn ((Expression) $2));
4124                 $$ = b;
4125           } 
4126         ;
4127         
4128 expression_or_error
4129         : expression
4130         | error
4131           {
4132                 Error_SyntaxError (yyToken);    
4133                 $$ = EmptyExpression.Null;
4134           }
4135         ;
4136
4137 lambda_expression
4138         : IDENTIFIER ARROW 
4139           {
4140                 var lt = (Tokenizer.LocatedToken) $1;   
4141                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4142                 start_anonymous (true, new ParametersCompiled (p), false, lt.Location);
4143           }
4144           lambda_expression_body
4145           {
4146                 $$ = end_anonymous ((ParametersBlock) $4);
4147                 lbag.AddLocation ($$, GetLocation ($2));
4148           }
4149         | ASYNC identifier_inside_body ARROW
4150           {
4151                 var lt = (Tokenizer.LocatedToken) $2;
4152                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4153                 start_anonymous (true, new ParametersCompiled (p), true, lt.Location);
4154           }
4155           lambda_expression_body
4156           {
4157                 $$ = end_anonymous ((ParametersBlock) $5);
4158                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
4159           }
4160         | OPEN_PARENS_LAMBDA
4161           {
4162                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
4163           }
4164           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4165           {
4166                 valid_param_mod = 0;
4167                 start_anonymous (true, (ParametersCompiled) $3, false, GetLocation ($1));
4168           }
4169           lambda_expression_body
4170           {
4171                 $$ = end_anonymous ((ParametersBlock) $7);
4172                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($4), GetLocation ($5));
4173           }
4174         | ASYNC OPEN_PARENS_LAMBDA
4175           {
4176                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;          
4177           }
4178           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4179           {
4180                 valid_param_mod = 0;
4181                 start_anonymous (true, (ParametersCompiled) $4, true, GetLocation ($1));
4182           }
4183           lambda_expression_body
4184           {
4185                 $$ = end_anonymous ((ParametersBlock) $8);
4186                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($5), GetLocation ($6));
4187           }
4188         ;
4189
4190 expression
4191         : assignment_expression 
4192         | non_assignment_expression
4193         ;
4194         
4195 non_assignment_expression
4196         : conditional_expression
4197         | lambda_expression
4198         | query_expression
4199         | ARGLIST
4200           {
4201                 $$ = new ArglistAccess (GetLocation ($1));
4202           }
4203         ;
4204         
4205 undocumented_expressions
4206         : REFVALUE OPEN_PARENS non_assignment_expression COMMA type CLOSE_PARENS
4207           {
4208                 $$ = new RefValueExpr ((Expression) $3, (FullNamedExpression) $5, GetLocation ($1));
4209                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
4210           }
4211         | REFTYPE open_parens_any expression CLOSE_PARENS
4212           {
4213                 $$ = new RefTypeExpr ((Expression) $3, GetLocation ($1));
4214                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
4215           }
4216         | MAKEREF open_parens_any expression CLOSE_PARENS
4217           {
4218                 $$ = new MakeRefExpr ((Expression) $3, GetLocation ($1));
4219                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));        
4220           }
4221         ;
4222
4223 constant_expression
4224         : expression
4225         ;
4226
4227 boolean_expression
4228         : expression
4229           {
4230                 $$ = new BooleanExpression ((Expression) $1);
4231           }
4232         ;
4233
4234 //
4235 // 10 classes
4236 //
4237 class_declaration
4238         : opt_attributes
4239           opt_modifiers
4240           opt_partial
4241           CLASS
4242           {
4243                 lexer.ConstraintsParsing = true;
4244           }
4245           type_declaration_name
4246           {
4247                 Class c = new Class (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1);
4248                 if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) {
4249                         FeatureIsNotAvailable (c.Location, "static classes");
4250                 }
4251                         
4252                 push_current_container (c, $3);
4253           }
4254           opt_class_base
4255           opt_type_parameter_constraints_clauses
4256           {
4257                 lexer.ConstraintsParsing = false;
4258
4259                 if ($9 != null)
4260                         current_container.SetConstraints ((List<Constraints>) $9);
4261                 lbag.AddMember (current_container, mod_locations, GetLocation ($4));
4262
4263                 if (doc_support) {
4264                         current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
4265                         Lexer.doc_state = XmlCommentState.Allowed;
4266                 }
4267                 
4268                 lexer.parsing_modifiers = true;
4269           }
4270           OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
4271           {
4272                 --lexer.parsing_declaration;
4273                 if (doc_support)
4274                         Lexer.doc_state = XmlCommentState.Allowed;
4275           }
4276           opt_semicolon 
4277           {
4278                 lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13), GetLocation ($15));
4279                 $$ = pop_current_class ();
4280           }
4281         ;       
4282
4283 opt_partial
4284         : /* empty */
4285           { $$ = null; }
4286         | PARTIAL
4287           { $$ = $1; } // location
4288         ;
4289
4290 opt_modifiers
4291         : /* empty */
4292           {
4293             mod_locations = null;
4294                 $$ = ModifierNone;
4295                 lexer.parsing_modifiers = false;
4296           }
4297         | modifiers
4298           {
4299                 lexer.parsing_modifiers = false;                
4300           }
4301         ;
4302
4303 modifiers
4304         : modifier
4305         | modifiers modifier
4306           { 
4307                 var m1 = (Modifiers) $1;
4308                 var m2 = (Modifiers) $2;
4309
4310                 if ((m1 & m2) != 0) {
4311                         report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length,
4312                                 "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2));
4313                 } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 &&
4314                         ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) {
4315                         report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length,
4316                                 "More than one protection modifier specified");
4317                 }
4318                 
4319                 $$ = m1 | m2;
4320           }
4321         ;
4322
4323 modifier
4324         : NEW
4325           {
4326                 $$ = Modifiers.NEW;
4327                 StoreModifierLocation ($$, GetLocation ($1));
4328                 
4329                 if (current_container.Kind == MemberKind.Namespace)
4330                         report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements");
4331           }
4332         | PUBLIC
4333           {
4334                 $$ = Modifiers.PUBLIC;
4335                 StoreModifierLocation ($$, GetLocation ($1));
4336           }
4337         | PROTECTED
4338           {
4339                 $$ = Modifiers.PROTECTED;
4340                 StoreModifierLocation ($$, GetLocation ($1));
4341           }
4342         | INTERNAL
4343           {
4344                 $$ = Modifiers.INTERNAL;
4345                 StoreModifierLocation ($$, GetLocation ($1));
4346           }
4347         | PRIVATE
4348           {
4349                 $$ = Modifiers.PRIVATE;
4350                 StoreModifierLocation ($$, GetLocation ($1));
4351           }
4352         | ABSTRACT
4353           {
4354                 $$ = Modifiers.ABSTRACT;
4355                 StoreModifierLocation ($$, GetLocation ($1));
4356           }
4357         | SEALED
4358           {
4359                 $$ = Modifiers.SEALED;
4360                 StoreModifierLocation ($$, GetLocation ($1));
4361           }
4362         | STATIC
4363           {
4364                 $$ = Modifiers.STATIC;
4365                 StoreModifierLocation ($$, GetLocation ($1));
4366           }
4367         | READONLY
4368           {
4369                 $$ = Modifiers.READONLY;
4370                 StoreModifierLocation ($$, GetLocation ($1));
4371           }
4372         | VIRTUAL
4373           {
4374                 $$ = Modifiers.VIRTUAL;
4375                 StoreModifierLocation ($$, GetLocation ($1));
4376           }
4377         | OVERRIDE
4378           {
4379                 $$ = Modifiers.OVERRIDE;
4380                 StoreModifierLocation ($$, GetLocation ($1));
4381           }
4382         | EXTERN
4383           {
4384                 $$ = Modifiers.EXTERN;
4385                 StoreModifierLocation ($$, GetLocation ($1));
4386           }
4387         | VOLATILE
4388           {
4389                 $$ = Modifiers.VOLATILE;
4390                 StoreModifierLocation ($$, GetLocation ($1));
4391           }
4392         | UNSAFE
4393           {
4394                 $$ = Modifiers.UNSAFE;
4395                 StoreModifierLocation ($$, GetLocation ($1));
4396                 if (!settings.Unsafe)
4397                         Error_UnsafeCodeNotAllowed (GetLocation ($1));
4398           }
4399         | ASYNC
4400           {
4401                 $$ = Modifiers.ASYNC;
4402                 StoreModifierLocation ($$, GetLocation ($1));
4403           }
4404         ;
4405         
4406 opt_class_base
4407         : /* empty */
4408         | COLON type_list
4409          {
4410                 current_type.AddBasesForPart ((List<FullNamedExpression>) $2);
4411          }
4412         | COLON type_list error
4413           {
4414                 Error_SyntaxError (yyToken);
4415
4416                 current_type.AddBasesForPart ((List<FullNamedExpression>) $2);
4417           }
4418         ;
4419
4420 opt_type_parameter_constraints_clauses
4421         : /* empty */
4422         | type_parameter_constraints_clauses 
4423           {
4424                 $$ = $1;
4425           }
4426         ;
4427
4428 type_parameter_constraints_clauses
4429         : type_parameter_constraints_clause
4430           {
4431                 var constraints = new List<Constraints> (1);
4432                 constraints.Add ((Constraints) $1);
4433                 $$ = constraints;
4434           }
4435         | type_parameter_constraints_clauses type_parameter_constraints_clause
4436           {
4437                 var constraints = (List<Constraints>) $1;
4438                 Constraints new_constraint = (Constraints)$2;
4439
4440                 foreach (Constraints c in constraints) {
4441                         if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) {
4442                                 report.Error (409, new_constraint.Location,
4443                                         "A constraint clause has already been specified for type parameter `{0}'",
4444                                         new_constraint.TypeParameter.Value);
4445                         }
4446                 }
4447
4448                 constraints.Add (new_constraint);
4449                 $$ = constraints;
4450           }
4451         ; 
4452
4453 type_parameter_constraints_clause
4454         : WHERE IDENTIFIER COLON type_parameter_constraints
4455           {
4456                 var lt = (Tokenizer.LocatedToken) $2;
4457                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List<FullNamedExpression>) $4, GetLocation ($1));
4458                 lbag.AddLocation ($$, GetLocation ($3));
4459           }
4460         | WHERE IDENTIFIER error
4461           {
4462                 Error_SyntaxError (yyToken);
4463           
4464                 var lt = (Tokenizer.LocatedToken) $2;
4465                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), null, GetLocation ($1));
4466           }
4467         ; 
4468
4469 type_parameter_constraints
4470         : type_parameter_constraint
4471           {
4472                 var constraints = new List<FullNamedExpression> (1);
4473                 constraints.Add ((FullNamedExpression) $1);
4474                 $$ = constraints;
4475           }
4476         | type_parameter_constraints COMMA type_parameter_constraint
4477           {
4478                 var constraints = (List<FullNamedExpression>) $1;
4479                 var prev = constraints [constraints.Count - 1] as SpecialContraintExpr;
4480                 if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) {                   
4481                         report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified");
4482                 }
4483                 
4484                 prev = $3 as SpecialContraintExpr;
4485                 if (prev != null) {
4486                         if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) {
4487                                 report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified");                 
4488                         } else {
4489                                 prev = constraints [0] as SpecialContraintExpr;
4490                                 if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) {                        
4491                                         report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint");
4492                                 }
4493                         }
4494                 }
4495
4496                 constraints.Add ((FullNamedExpression) $3);
4497                 $$ = constraints;
4498           }
4499         ;
4500
4501 type_parameter_constraint
4502         : type
4503           {
4504                 if ($1 is ComposedCast)
4505                         report.Error (706, GetLocation ($1), "Invalid constraint type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
4506           
4507                 $$ = $1;
4508           }
4509         | NEW OPEN_PARENS CLOSE_PARENS
4510           {
4511                 $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1));
4512                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
4513           }
4514         | CLASS
4515           {
4516                 $$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1));
4517           }
4518         | STRUCT
4519           {
4520                 $$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1));
4521           }
4522         ;
4523
4524 opt_type_parameter_variance
4525         : /* empty */
4526           {
4527                 $$ = Variance.None;
4528           }
4529         | type_parameter_variance
4530           {
4531                 if (lang_version <= LanguageVersion.V_3)
4532                         FeatureIsNotAvailable (lexer.Location, "generic type variance");
4533                 
4534                 $$ = $1;
4535           }
4536         ;
4537
4538 type_parameter_variance
4539         : OUT
4540           {
4541                 $$ = Variance.Covariant;
4542           }
4543         | IN
4544           {
4545                 $$ = Variance.Contravariant;
4546           }
4547         ;
4548
4549 //
4550 // Statements (8.2)
4551 //
4552
4553 //
4554 // A block is "contained" on the following places:
4555 //      method_body
4556 //      property_declaration as part of the accessor body (get/set)
4557 //      operator_declaration
4558 //      constructor_declaration
4559 //      destructor_declaration
4560 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
4561 //      
4562 block
4563         : OPEN_BRACE  
4564           {
4565                 ++lexer.parsing_block;
4566                 start_block (GetLocation ($1));
4567           } 
4568           opt_statement_list block_end
4569           {
4570                 $$ = $4;
4571           }
4572         ;
4573
4574 block_end 
4575         : CLOSE_BRACE 
4576           {
4577                 --lexer.parsing_block;
4578                 $$ = end_block (GetLocation ($1));
4579           }
4580         | COMPLETE_COMPLETION
4581           {
4582                 --lexer.parsing_block;
4583                 $$ = end_block (lexer.Location);
4584           }
4585         ;
4586
4587
4588 block_prepared
4589         : OPEN_BRACE
4590           {
4591                 ++lexer.parsing_block;
4592                 current_block.StartLocation = GetLocation ($1);
4593           }
4594           opt_statement_list CLOSE_BRACE 
4595           {
4596                 --lexer.parsing_block;
4597                 $$ = end_block (GetLocation ($4));
4598           }
4599         ;
4600
4601 opt_statement_list
4602         : /* empty */
4603         | statement_list 
4604         ;
4605
4606 statement_list
4607         : statement
4608         | statement_list statement
4609         ;
4610
4611 statement
4612         : block_variable_declaration
4613           {
4614                 current_block.AddStatement ((Statement) $1);
4615           }
4616         | valid_declaration_statement
4617           {
4618                 current_block.AddStatement ((Statement) $1);
4619           }
4620         | labeled_statement
4621         | error
4622           {
4623                 Error_SyntaxError (yyToken);
4624                 $$ = null;
4625           }
4626         ;
4627
4628 //
4629 // The interactive_statement and its derivatives are only 
4630 // used to provide a special version of `expression_statement'
4631 // that has a side effect of assigning the expression to
4632 // $retval
4633 //
4634 interactive_statement_list
4635         : interactive_statement
4636         | interactive_statement_list interactive_statement
4637         ;
4638
4639 interactive_statement
4640         : block_variable_declaration
4641           {
4642                 current_block.AddStatement ((Statement) $1);
4643           }
4644         | interactive_valid_declaration_statement
4645           {
4646                 current_block.AddStatement ((Statement) $1);
4647           }
4648         | labeled_statement
4649         ;
4650
4651 valid_declaration_statement
4652         : block
4653         | empty_statement
4654         | expression_statement
4655         | selection_statement
4656         | iteration_statement
4657         | jump_statement                  
4658         | try_statement
4659         | checked_statement
4660         | unchecked_statement
4661         | lock_statement
4662         | using_statement
4663         | unsafe_statement
4664         | fixed_statement
4665         ;
4666
4667 interactive_valid_declaration_statement
4668         : block
4669         | empty_statement
4670         | interactive_expression_statement
4671         | selection_statement
4672         | iteration_statement
4673         | jump_statement                  
4674         | try_statement
4675         | checked_statement
4676         | unchecked_statement
4677         | lock_statement
4678         | using_statement
4679         | unsafe_statement
4680         | fixed_statement
4681         ;
4682
4683 embedded_statement
4684         : valid_declaration_statement
4685         | block_variable_declaration
4686           {
4687                   report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4688                   $$ = null;
4689           }
4690         | labeled_statement
4691           {
4692                   report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4693                   $$ = null;
4694           }
4695         | error
4696           {
4697                 Error_SyntaxError (yyToken);
4698                 $$ = new EmptyStatement (GetLocation ($1));
4699           }
4700         ;
4701
4702 empty_statement
4703         : SEMICOLON
4704           {
4705                 // Uses lexer.Location because semicolon location is not kept in quick mode
4706                 $$ = new EmptyStatement (lexer.Location);
4707           }
4708         ;
4709
4710 labeled_statement
4711         : identifier_inside_body COLON 
4712           {
4713                 var lt = (Tokenizer.LocatedToken) $1;
4714                 LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location);
4715                 lbag.AddLocation (labeled, GetLocation ($2));
4716                 current_block.AddLabel (labeled);
4717                 current_block.AddStatement (labeled);
4718           }
4719           statement
4720         ;
4721
4722 variable_type
4723         : variable_type_simple
4724         | variable_type_simple rank_specifiers
4725           {
4726                 if ($1 is VarExpr)
4727                         $1 = new SimpleName ("var", ((VarExpr) $1).Location);
4728           
4729                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
4730           }
4731         ;
4732
4733 /* 
4734  * The following is from Rhys' grammar:
4735  * > Types in local variable declarations must be recognized as 
4736  * > expressions to prevent reduce/reduce errors in the grammar.
4737  * > The expressions are converted into types during semantic analysis.
4738  */
4739 variable_type_simple
4740         : primary_expression_or_type opt_nullable
4741           { 
4742                 // Ok, the above "primary_expression" is there to get rid of
4743                 // both reduce/reduce and shift/reduces in the grammar, it should
4744                 // really just be "type_name".  If you use type_name, a reduce/reduce
4745                 // creeps up.  If you use namespace_or_type_name (which is all we need
4746                 // really) two shift/reduces appear.
4747                 // 
4748
4749                 // So the super-trick is that primary_expression
4750                 // can only be either a SimpleName or a MemberAccess. 
4751                 // The MemberAccess case arises when you have a fully qualified type-name like :
4752                 // Foo.Bar.Blah i;
4753                 // SimpleName is when you have
4754                 // Blah i;
4755                 
4756                 Expression expr = (Expression) $1;
4757                 if ($2 == null) {
4758                         SimpleName sn = expr as SimpleName;
4759                         if (sn != null && sn.Name == "var")
4760                                 $$ = new VarExpr (sn.Location);
4761                         else
4762                                 $$ = $1;
4763                 } else if (expr is ATypeNameExpression) {
4764                         $$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2);
4765                 } else {
4766                         Error_ExpectingTypeName (expr);
4767                         $$ = null;
4768                 }
4769           }
4770         | primary_expression_or_type pointer_stars
4771           {
4772                 ATypeNameExpression expr = $1 as ATypeNameExpression;
4773
4774                 if (expr != null) {
4775                         $$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2);
4776                 } else {
4777                         Error_ExpectingTypeName ((Expression)$1);
4778                         $$ = expr;
4779                 }
4780           }
4781         | builtin_types opt_nullable
4782           {
4783                 if ($2 == null)
4784                         $$ = $1;
4785                 else
4786                         $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
4787           }
4788         | builtin_types pointer_stars
4789           {
4790                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
4791           }
4792         | VOID pointer_stars
4793           {
4794                 $$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
4795           }       
4796         | VOID
4797           {
4798                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
4799                 $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
4800           }
4801         ;
4802         
4803 pointer_stars
4804         : pointer_star
4805         | pointer_star pointer_stars
4806           {
4807                 ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
4808                 $$ = $1;
4809           }       
4810         ;
4811
4812 pointer_star
4813         : STAR
4814           {
4815                 $$ = ComposedTypeSpecifier.CreatePointer (GetLocation ($1));
4816           }
4817         ;
4818
4819 identifier_inside_body
4820         : IDENTIFIER
4821         | AWAIT
4822           {
4823                 if (async_block) {
4824                         report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression");
4825                         $$ = new Tokenizer.LocatedToken ("await", GetLocation ($1));
4826                 }
4827           }
4828         ;
4829
4830 block_variable_declaration
4831         : variable_type identifier_inside_body
4832           {
4833                 var lt = (Tokenizer.LocatedToken) $2;
4834                 var li = new LocalVariable (current_block, lt.Value, lt.Location);
4835                 current_block.AddLocalName (li);
4836                 current_variable = new BlockVariableDeclaration ((FullNamedExpression) $1, li);
4837           }
4838           opt_local_variable_initializer opt_variable_declarators SEMICOLON
4839           {
4840                 $$ = current_variable;
4841                 current_variable = null;
4842                 lbag.AddLocation ($$, GetLocation ($6));
4843           }
4844         | CONST variable_type identifier_inside_body
4845           {
4846                 var lt = (Tokenizer.LocatedToken) $3;
4847                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
4848                 current_block.AddLocalName (li);
4849                 current_variable = new BlockConstantDeclaration ((FullNamedExpression) $2, li);
4850           }
4851           const_variable_initializer opt_const_declarators SEMICOLON
4852           {
4853                 $$ = current_variable;
4854                 current_variable = null;
4855                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($7));
4856           }
4857         ;
4858
4859 opt_local_variable_initializer
4860         : /* empty */
4861         | ASSIGN block_variable_initializer
4862           {
4863                 current_variable.Initializer = (Expression) $2;
4864                 // TODO: lbag
4865           }
4866         | error
4867           {
4868                 if (yyToken == Token.OPEN_BRACKET_EXPR) {
4869                         report.Error (650, lexer.Location,
4870                                 "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");
4871                 } else {
4872                         Error_SyntaxError (yyToken);
4873                 }
4874           }
4875         ;
4876
4877 opt_variable_declarators
4878         : /* empty */
4879         | variable_declarators
4880         ;
4881         
4882 opt_using_or_fixed_variable_declarators
4883         : /* empty */
4884         | variable_declarators
4885           {
4886                 foreach (var d in current_variable.Declarators) {
4887                         if (d.Initializer == null)
4888                                 Error_MissingInitializer (d.Variable.Location);
4889                 }
4890           }
4891         ;       
4892         
4893 variable_declarators
4894         : variable_declarator
4895         | variable_declarators variable_declarator
4896         ;
4897         
4898 variable_declarator
4899         : COMMA identifier_inside_body
4900           {
4901                 var lt = (Tokenizer.LocatedToken) $2;     
4902                 var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
4903                 var d = new BlockVariableDeclaration.Declarator (li, null);
4904                 current_variable.AddDeclarator (d);
4905                 current_block.AddLocalName (li);
4906                 lbag.AddLocation (d, GetLocation ($1));
4907           }
4908         | COMMA identifier_inside_body ASSIGN block_variable_initializer
4909           {
4910                 var lt = (Tokenizer.LocatedToken) $2;     
4911                 var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
4912                 var d = new BlockVariableDeclaration.Declarator (li, (Expression) $4);
4913                 current_variable.AddDeclarator (d);
4914                 current_block.AddLocalName (li);
4915                 lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
4916           }
4917         ;
4918         
4919 const_variable_initializer
4920         : /* empty */
4921           {
4922                 report.Error (145, lexer.Location, "A const field requires a value to be provided");
4923           }
4924         | ASSIGN constant_initializer_expr 
4925           {
4926                 current_variable.Initializer = (Expression) $2;
4927           }
4928         ;
4929         
4930 opt_const_declarators
4931         : /* empty */
4932         | const_declarators
4933         ;
4934         
4935 const_declarators
4936         : const_declarator
4937         | const_declarators const_declarator
4938         ;
4939         
4940 const_declarator
4941         : COMMA identifier_inside_body ASSIGN constant_initializer_expr
4942           {
4943                 var lt = (Tokenizer.LocatedToken) $2;     
4944                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
4945                 var d = new BlockVariableDeclaration.Declarator (li, (Expression) $4);
4946                 current_variable.AddDeclarator (d);
4947                 current_block.AddLocalName (li);
4948                 lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
4949           }
4950         ;
4951         
4952 block_variable_initializer
4953         : variable_initializer
4954         | STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET
4955           {
4956                 $$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1));
4957                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
4958           }
4959         | STACKALLOC simple_type
4960           {
4961                 report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type");
4962                 $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1));          
4963           }
4964         ;
4965
4966 expression_statement
4967         : statement_expression SEMICOLON
4968           {
4969                 $$ = $1;
4970                 lbag.AddStatement ($$, GetLocation ($2));
4971           }
4972         | statement_expression COMPLETE_COMPLETION { $$ = $1; }
4973         | statement_expression CLOSE_BRACE
4974           {
4975                 $$ = $1;
4976                 report.Error (1002, GetLocation ($2), "; expected");
4977                 lexer.putback ('}');
4978           }
4979         ;
4980
4981 interactive_expression_statement
4982         : interactive_statement_expression SEMICOLON { $$ = $1; }
4983         | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; }
4984         ;
4985
4986         //
4987         // We have to do the wrapping here and not in the case above,
4988         // because statement_expression is used for example in for_statement
4989         //
4990 statement_expression
4991         : expression
4992           {
4993                 ExpressionStatement s = $1 as ExpressionStatement;
4994                 if (s == null) {
4995                         Expression.Error_InvalidExpressionStatement (report, GetLocation ($1));
4996                         $$ = new StatementErrorExpression ($1 as Expression);
4997                 } else {
4998                         $$ = new StatementExpression (s);
4999                 }
5000           }
5001         ;
5002
5003 interactive_statement_expression
5004         : expression
5005           {
5006                 Expression expr = (Expression) $1;
5007                 ExpressionStatement s;
5008
5009                 s = new OptionalAssign (new SimpleName ("$retval", lexer.Location), expr, lexer.Location);
5010                 $$ = new StatementExpression (s);
5011           }
5012         | error
5013           {
5014                 Error_SyntaxError (yyToken);
5015                 $$ = new EmptyStatement (GetLocation ($1));
5016           }
5017         ;
5018         
5019 selection_statement
5020         : if_statement
5021         | switch_statement
5022         ; 
5023
5024 if_statement
5025         : IF open_parens_any boolean_expression CLOSE_PARENS 
5026           embedded_statement
5027           { 
5028                 if ($5 is EmptyStatement)
5029                         Warning_EmptyStatement (GetLocation ($5));
5030                 
5031                 $$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
5032                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5033           }
5034         | IF open_parens_any boolean_expression CLOSE_PARENS
5035           embedded_statement ELSE embedded_statement
5036           {
5037                 $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1));
5038                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
5039                 
5040                 if ($5 is EmptyStatement)
5041                         Warning_EmptyStatement (GetLocation ($5));
5042                 if ($7 is EmptyStatement)
5043                         Warning_EmptyStatement (GetLocation ($7));
5044           }
5045         | IF open_parens_any boolean_expression error
5046           {
5047                 Error_SyntaxError (yyToken);
5048                 
5049                 $$ = new If ((BooleanExpression) $3, null, GetLocation ($1));
5050                 lbag.AddStatement ($$, GetLocation ($2));
5051           }
5052         ;
5053
5054 switch_statement
5055         : SWITCH open_parens_any expression CLOSE_PARENS OPEN_BRACE
5056           {
5057                 start_block (GetLocation ($5));
5058           }
5059           opt_switch_sections CLOSE_BRACE
5060           {
5061                 $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, (List<SwitchSection>) $7, GetLocation ($1));  
5062                 end_block (GetLocation ($8));
5063                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5064           }
5065         | SWITCH open_parens_any expression error
5066           {
5067                 Error_SyntaxError (yyToken);
5068           
5069                 $$ = new Switch ((Expression) $3, null, null, GetLocation ($1));        
5070                 lbag.AddStatement ($$, GetLocation ($2));
5071           }
5072         ;
5073
5074 opt_switch_sections
5075         : /* empty */           
5076       {
5077                 report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); 
5078                 $$ = new List<SwitchSection> ();
5079           }
5080         | switch_sections
5081         ;
5082
5083 switch_sections
5084         : switch_section 
5085           {
5086                 var sections = new List<SwitchSection> (4);
5087
5088                 sections.Add ((SwitchSection) $1);
5089                 $$ = sections;
5090           }
5091         | switch_sections switch_section
5092           {
5093                 var sections = (List<SwitchSection>) $1;
5094
5095                 sections.Add ((SwitchSection) $2);
5096                 $$ = sections;
5097           }
5098         | error
5099           {
5100                 Error_SyntaxError (yyToken);
5101                 $$ = new List<SwitchSection> ();
5102           } 
5103         ;
5104
5105 switch_section
5106         : switch_labels
5107           {
5108                 current_block = current_block.CreateSwitchBlock (lexer.Location);
5109           }
5110           statement_list 
5111           {
5112                 $$ = new SwitchSection ((List<SwitchLabel>) $1, current_block);
5113           }
5114         ;
5115
5116 switch_labels
5117         : switch_label 
5118           {
5119                 var labels = new List<SwitchLabel> (2);
5120
5121                 labels.Add ((SwitchLabel) $1);
5122                 $$ = labels;
5123           }
5124         | switch_labels switch_label 
5125           {
5126                 var labels = (List<SwitchLabel>) ($1);
5127                 labels.Add ((SwitchLabel) $2);
5128
5129                 $$ = labels;
5130           }
5131         ;
5132
5133 switch_label
5134         : CASE constant_expression COLON
5135          {
5136                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
5137                 lbag.AddLocation ($$, GetLocation ($3));
5138          }
5139         | CASE constant_expression error
5140           {
5141                 Error_SyntaxError (yyToken);
5142                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
5143           }
5144         | DEFAULT_COLON
5145           {
5146                 $$ = new SwitchLabel (null, GetLocation ($1));
5147           }
5148         ;
5149
5150 iteration_statement
5151         : while_statement
5152         | do_statement
5153         | for_statement
5154         | foreach_statement
5155         ;
5156
5157 while_statement
5158         : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement
5159           {
5160                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5161                         Warning_EmptyStatement (GetLocation ($5));
5162           
5163                 $$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
5164                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5165           }
5166         | WHILE open_parens_any boolean_expression error
5167           {
5168                 Error_SyntaxError (yyToken);
5169                 
5170                 $$ = new While ((BooleanExpression) $3, null, GetLocation ($1));
5171                 lbag.AddStatement ($$, GetLocation ($2));
5172           }
5173         ;
5174
5175 do_statement
5176         : DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
5177           {
5178                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
5179                 lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
5180           }
5181         | DO embedded_statement error
5182           {
5183                 Error_SyntaxError (yyToken);
5184                 $$ = new Do ((Statement) $2, null, GetLocation ($1), Location.Null);
5185           }
5186         | DO embedded_statement WHILE open_parens_any boolean_expression error
5187           {
5188                 Error_SyntaxError (yyToken);
5189           
5190                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
5191                 lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4));
5192           }
5193         ;
5194
5195 for_statement
5196         : FOR open_parens_any
5197           {
5198                 start_block (GetLocation ($2));
5199                 current_block.IsCompilerGenerated = true;
5200                 For f = new For (GetLocation ($1));
5201                 current_block.AddStatement (f);
5202                 $$ = f;
5203           }
5204           for_statement_cont
5205           {
5206                 $$ = $4;
5207           }
5208         ;
5209         
5210 // Has to use be extra rule to recover started block
5211 for_statement_cont
5212         : opt_for_initializer SEMICOLON
5213           {
5214                 ((For) $0).Initializer = (Statement) $1;
5215
5216                 // Pass the "For" object to the iterator_part4
5217                 oob_stack.Push ($0);
5218           }
5219           for_condition_and_iterator_part
5220           embedded_statement
5221           {
5222                 var locations = (Tuple<Location,Location>) $4;
5223                 oob_stack.Pop ();
5224                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5225                         Warning_EmptyStatement (GetLocation ($5));
5226           
5227                 For f = ((For) $0);
5228                 f.Statement = (Statement) $5;
5229                 lbag.AddStatement (f, current_block.StartLocation, GetLocation ($2), GetLocation (locations.Item1), GetLocation (locations.Item2));
5230
5231                 $$ = end_block (GetLocation ($2));
5232           }
5233         | error
5234           {
5235                 Error_SyntaxError (yyToken);
5236                 $$ = end_block (current_block.StartLocation);
5237           }
5238         ;
5239
5240 for_condition_and_iterator_part
5241         : opt_for_condition SEMICOLON
5242           {
5243                 For f = (For) oob_stack.Peek ();
5244                 f.Condition = (BooleanExpression) $1;
5245           }
5246           for_iterator_part {
5247                 $$ = new Tuple<Location,Location> (GetLocation ($2), (Location) $4);
5248           }
5249
5250         // Handle errors in the case of opt_for_condition being followed by
5251         // a close parenthesis
5252         | opt_for_condition close_parens_close_brace {
5253                 report.Error (1525, GetLocation ($2), "Unexpected symbol `}'");
5254                 For f = (For) oob_stack.Peek ();
5255                 f.Condition = (BooleanExpression) $1;
5256                 $$ = new Tuple<Location,Location> (GetLocation ($2), GetLocation ($2));
5257           }
5258         ;
5259
5260 for_iterator_part
5261         : opt_for_iterator CLOSE_PARENS {
5262                 For f = (For) oob_stack.Peek ();
5263                 f.Iterator = (Statement) $1;
5264                 $$ = GetLocation ($2);
5265           }
5266         | opt_for_iterator CLOSE_BRACE {
5267                 report.Error (1525, GetLocation ($2), "Unexpected symbol expected ')'");
5268                 For f = (For) oob_stack.Peek ();
5269                 f.Iterator = (Statement) $1;
5270                 $$ = GetLocation ($2);
5271           }
5272         ; 
5273
5274 close_parens_close_brace 
5275         : CLOSE_PARENS
5276         | CLOSE_BRACE { lexer.putback ('}'); }
5277         ;
5278
5279 opt_for_initializer
5280         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
5281         | for_initializer       
5282         ;
5283
5284 for_initializer
5285         : variable_type identifier_inside_body
5286           {
5287                 var lt = (Tokenizer.LocatedToken) $2;
5288                 var li = new LocalVariable (current_block, lt.Value, lt.Location);
5289                 current_block.AddLocalName (li);
5290                 current_variable = new BlockVariableDeclaration ((FullNamedExpression) $1, li);
5291           }
5292           opt_local_variable_initializer opt_variable_declarators
5293           {
5294                 $$ = current_variable;
5295                 current_variable = null;
5296           }
5297         | statement_expression_list
5298         ;
5299
5300 opt_for_condition
5301         : /* empty */           { $$ = null; }
5302         | boolean_expression
5303         ;
5304
5305 opt_for_iterator
5306         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
5307         | for_iterator
5308         ;
5309
5310 for_iterator
5311         : statement_expression_list
5312         ;
5313
5314 statement_expression_list
5315         : statement_expression
5316         | statement_expression_list COMMA statement_expression
5317           {
5318                 var sl = $1 as StatementList;
5319                 if (sl == null) {
5320                         sl = new StatementList ((Statement) $1, (Statement) $3);
5321                         lbag.AddStatement (sl, GetLocation ($2));
5322                 } else {
5323                         sl.Add ((Statement) $3);
5324                         lbag.AppendTo (sl, GetLocation ($2));
5325                 }
5326                         
5327                 $$ = sl;
5328           }
5329         ;
5330
5331 foreach_statement
5332         : FOREACH open_parens_any type error
5333           {
5334                 report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement");
5335
5336                 start_block (GetLocation ($2));
5337                 current_block.IsCompilerGenerated = true;
5338                 
5339                 Foreach f = new Foreach ((Expression) $3, null, null, null, null, GetLocation ($1));
5340                 current_block.AddStatement (f);
5341                 
5342                 lbag.AddStatement (f, GetLocation ($2));
5343                 $$ = end_block (GetLocation ($4));
5344           }
5345         | FOREACH open_parens_any type identifier_inside_body error
5346           {
5347                 Error_SyntaxError (yyToken);
5348         
5349                 start_block (GetLocation ($2));
5350                 current_block.IsCompilerGenerated = true;
5351                 
5352                 var lt = (Tokenizer.LocatedToken) $4;
5353                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
5354                 current_block.AddLocalName (li);
5355                 
5356                 Foreach f = new Foreach ((Expression) $3, li, null, null, null, GetLocation ($1));
5357                 current_block.AddStatement (f);
5358                 
5359                 lbag.AddStatement (f, GetLocation ($2));
5360                 $$ = end_block (GetLocation ($5));
5361           }
5362         | FOREACH open_parens_any type identifier_inside_body IN expression CLOSE_PARENS 
5363           {
5364                 start_block (GetLocation ($2));
5365                 current_block.IsCompilerGenerated = true;
5366                 
5367                 var lt = (Tokenizer.LocatedToken) $4;
5368                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
5369                 current_block.AddLocalName (li);
5370                 $$ = li;
5371           } 
5372           embedded_statement
5373           {
5374                 if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5375                         Warning_EmptyStatement (GetLocation ($9));
5376                 
5377                 Foreach f = new Foreach ((Expression) $3, (LocalVariable) $8, (Expression) $6, (Statement) $9, current_block, GetLocation ($1));
5378                 lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
5379                 end_block (GetLocation ($7));
5380                 
5381                 $$ = f;
5382           }
5383         ;
5384
5385 jump_statement
5386         : break_statement
5387         | continue_statement
5388         | goto_statement
5389         | return_statement
5390         | throw_statement
5391         | yield_statement
5392         ;
5393
5394 break_statement
5395         : BREAK SEMICOLON
5396           {
5397                 $$ = new Break (GetLocation ($1));
5398                 lbag.AddStatement ($$, GetLocation ($2));
5399           }
5400         ;
5401
5402 continue_statement
5403         : CONTINUE SEMICOLON
5404           {
5405                 $$ = new Continue (GetLocation ($1));
5406                 lbag.AddStatement ($$, GetLocation ($2));
5407           }
5408         | CONTINUE error
5409           {
5410                 Error_SyntaxError (yyToken);
5411                 $$ = new Continue (GetLocation ($1));
5412           }
5413         ;
5414
5415 goto_statement
5416         : GOTO identifier_inside_body SEMICOLON 
5417           {
5418                 var lt = (Tokenizer.LocatedToken) $2;
5419                 $$ = new Goto (lt.Value, GetLocation ($1));
5420                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5421           }
5422         | GOTO CASE constant_expression SEMICOLON
5423           {
5424                 $$ = new GotoCase ((Expression) $3, GetLocation ($1));
5425                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5426           }
5427         | GOTO DEFAULT SEMICOLON 
5428           {
5429                 $$ = new GotoDefault (GetLocation ($1));
5430                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5431           }
5432         ; 
5433
5434 return_statement
5435         : RETURN opt_expression SEMICOLON
5436           {
5437                 $$ = new Return ((Expression) $2, GetLocation ($1));
5438                 lbag.AddStatement ($$, GetLocation ($3));
5439           }
5440         | RETURN expression error
5441           {
5442                 Error_SyntaxError (yyToken);
5443                 $$ = new Return ((Expression) $2, GetLocation ($1));
5444           }
5445         | RETURN error
5446           {
5447                 Error_SyntaxError (yyToken);
5448                 $$ = new Return (null, GetLocation ($1));
5449           }
5450         ;
5451
5452 throw_statement
5453         : THROW opt_expression SEMICOLON
5454           {
5455                 $$ = new Throw ((Expression) $2, GetLocation ($1));
5456                 lbag.AddStatement ($$, GetLocation ($3));
5457           }
5458         | THROW error
5459           {
5460                 Error_SyntaxError (yyToken);
5461                 $$ = new Throw (null, GetLocation ($1));
5462           }
5463         ;
5464
5465 yield_statement 
5466         : identifier_inside_body RETURN opt_expression SEMICOLON
5467           {
5468                 var lt = (Tokenizer.LocatedToken) $1;
5469                 string s = lt.Value;
5470                 if (s != "yield"){
5471                         report.Error (1003, lt.Location, "; expected");
5472                 } else if ($3 == null) {
5473                         report.Error (1627, GetLocation ($4), "Expression expected after yield return");
5474                 } else if (lang_version == LanguageVersion.ISO_1){
5475                         FeatureIsNotAvailable (lt.Location, "iterators");
5476                 }
5477                 
5478                 current_block.Explicit.RegisterIteratorYield ();
5479                 $$ = new Yield ((Expression) $3, lt.Location);
5480                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5481           }
5482         | identifier_inside_body RETURN expression error
5483           {
5484                 Error_SyntaxError (yyToken);
5485
5486                 var lt = (Tokenizer.LocatedToken) $1;
5487                 string s = lt.Value;
5488                 if (s != "yield"){
5489                         report.Error (1003, lt.Location, "; expected");
5490                 } else if ($3 == null) {
5491                         report.Error (1627, GetLocation ($4), "Expression expected after yield return");
5492                 } else if (lang_version == LanguageVersion.ISO_1){
5493                         FeatureIsNotAvailable (lt.Location, "iterators");
5494                 }
5495                 
5496                 current_block.Explicit.RegisterIteratorYield ();
5497                 $$ = new Yield ((Expression) $3, lt.Location);
5498                 lbag.AddStatement ($$, GetLocation ($2));
5499           }
5500         | identifier_inside_body BREAK SEMICOLON
5501           {
5502                 var lt = (Tokenizer.LocatedToken) $1;
5503                 string s = lt.Value;
5504                 if (s != "yield"){
5505                         report.Error (1003, lt.Location, "; expected");
5506                 } else if (lang_version == LanguageVersion.ISO_1){
5507                         FeatureIsNotAvailable (lt.Location, "iterators");
5508                 }
5509                 
5510                 current_block.Explicit.RegisterIteratorYield ();
5511                 $$ = new YieldBreak (lt.Location);
5512                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5513           }
5514         ;
5515
5516 opt_expression
5517         : /* empty */
5518         | expression
5519         ;
5520
5521 try_statement
5522         : TRY block catch_clauses
5523           {
5524                 $$ = new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), false);
5525           }
5526         | TRY block FINALLY block
5527           {
5528                 $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1));
5529                 lbag.AddStatement ($$, GetLocation ($3));
5530           }
5531         | TRY block catch_clauses FINALLY block
5532           {
5533                 $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, Location.Null, true), (Block) $5, GetLocation ($1));
5534                 lbag.AddStatement ($$, GetLocation ($4));
5535           }
5536         | TRY block error
5537           {
5538                 Error_SyntaxError (1524, yyToken);
5539                 $$ = new TryCatch ((Block) $2, null, GetLocation ($1), false);
5540           }
5541         ;
5542
5543 catch_clauses
5544         : catch_clause 
5545           {
5546                 var l = new List<Catch> (2);
5547
5548                 l.Add ((Catch) $1);
5549                 $$ = l;
5550           }
5551         | catch_clauses catch_clause
5552           {
5553                 var l = (List<Catch>) $1;
5554                 
5555                 Catch c = (Catch) $2;
5556                 if (l [l.Count - 1].IsGeneral) {
5557                         report.Error (1017, c.loc, "Try statement already has an empty catch block");
5558                 }
5559                 
5560                 l.Add (c);
5561                 $$ = l;
5562           }
5563         ;
5564
5565 opt_identifier
5566         : /* empty */
5567         | identifier_inside_body
5568         ;
5569
5570 catch_clause 
5571         : CATCH block
5572           {
5573                 $$ = new Catch ((Block) $2, GetLocation ($1));
5574           }
5575         | CATCH open_parens_any type opt_identifier CLOSE_PARENS
5576           {
5577                 start_block (GetLocation ($2));
5578                 var c = new Catch (current_block, GetLocation ($1));
5579                 c.TypeExpression = (FullNamedExpression) $3;
5580
5581                 if ($4 != null) {
5582                         var lt = (Tokenizer.LocatedToken) $4;
5583                         c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
5584                         current_block.AddLocalName (c.Variable);
5585                 }
5586                 
5587                 lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
5588                 $$ = c;
5589           }
5590           block_prepared
5591           {
5592                 $$ = $6;
5593           }
5594         | CATCH open_parens_any error
5595           {
5596                 if (yyToken == Token.CLOSE_PARENS) {
5597                         report.Error (1015, lexer.Location,
5598                                 "A type that derives from `System.Exception', `object', or `string' expected");
5599                 } else {
5600                         Error_SyntaxError (yyToken);
5601                 }
5602                 
5603                 $$ = new Catch (null, GetLocation ($1));
5604           }
5605         ;
5606
5607 checked_statement
5608         : CHECKED block
5609           {
5610                 $$ = new Checked ((Block) $2, GetLocation ($1));
5611           }
5612         ;
5613
5614 unchecked_statement
5615         : UNCHECKED block
5616           {
5617                 $$ = new Unchecked ((Block) $2, GetLocation ($1));
5618           }
5619         ;
5620
5621 unsafe_statement
5622         : UNSAFE
5623           {
5624                 if (!settings.Unsafe)
5625                         Error_UnsafeCodeNotAllowed (GetLocation ($1));
5626           } block {
5627                 $$ = new Unsafe ((Block) $3, GetLocation ($1));
5628           }
5629         ;
5630
5631 lock_statement
5632         : LOCK open_parens_any expression CLOSE_PARENS embedded_statement
5633           {
5634                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5635                         Warning_EmptyStatement (GetLocation ($5));
5636           
5637                 $$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1));
5638                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5639           }
5640         | LOCK open_parens_any expression error
5641           {
5642                 Error_SyntaxError (yyToken);
5643
5644                 $$ = new Lock ((Expression) $3, null, GetLocation ($1));
5645                 lbag.AddStatement ($$, GetLocation ($2));
5646           }
5647         ;
5648
5649 fixed_statement
5650         : FIXED open_parens_any variable_type identifier_inside_body
5651           {
5652             start_block (GetLocation ($2));
5653             
5654                 current_block.IsCompilerGenerated = true;
5655                 var lt = (Tokenizer.LocatedToken) $4;
5656                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location);
5657                 current_block.AddLocalName (li);
5658                 current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) $3, li);
5659           }
5660           using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators CLOSE_PARENS
5661           {
5662                 $$ = current_variable;
5663                 current_variable = null;
5664           }
5665           embedded_statement
5666           {
5667                 if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5668                         Warning_EmptyStatement (GetLocation ($10));
5669           
5670                 Fixed f = new Fixed ((Fixed.VariableDeclaration) $9, (Statement) $10, GetLocation ($1));
5671                 current_block.AddStatement (f);
5672                 $$ = end_block (GetLocation ($8));
5673           }
5674         ;
5675
5676 using_statement
5677         : USING open_parens_any variable_type identifier_inside_body
5678           {
5679             start_block (GetLocation ($2));
5680             
5681                 current_block.IsCompilerGenerated = true;
5682                 var lt = (Tokenizer.LocatedToken) $4;
5683                 var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location);
5684                 current_block.AddLocalName (li);
5685                 current_variable = new Using.VariableDeclaration ((FullNamedExpression) $3, li);
5686           }
5687           using_initialization CLOSE_PARENS
5688           {
5689                 $$ = current_variable;    
5690                 current_variable = null;
5691           }
5692           embedded_statement
5693           {
5694                 if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5695                         Warning_EmptyStatement (GetLocation ($9));
5696           
5697                 Using u = new Using ((Using.VariableDeclaration) $8, (Statement) $9, GetLocation ($1));
5698                 current_block.AddStatement (u);
5699                 $$ = end_block (GetLocation ($7));
5700           }
5701         | USING open_parens_any expression CLOSE_PARENS embedded_statement
5702           {
5703                 if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
5704                         Warning_EmptyStatement (GetLocation ($5));
5705           
5706                 $$ = new Using ((Expression) $3, (Statement) $5, GetLocation ($1));
5707                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5708           }
5709         | USING open_parens_any expression error
5710           {
5711                 Error_SyntaxError (yyToken);
5712                 
5713                 $$ = new Using ((Expression) $3, null, GetLocation ($1));
5714                 lbag.AddStatement ($$, GetLocation ($2));
5715           }
5716         ;
5717         
5718 using_initialization
5719         : using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators
5720         | error
5721           {
5722                 // It has to be here for the parent to safely restore artificial block
5723                 Error_SyntaxError (yyToken);
5724           }
5725         ;
5726         
5727 using_or_fixed_variable_initializer
5728         : /* empty */
5729           {
5730                 Error_MissingInitializer (lexer.Location);
5731           }
5732         | ASSIGN variable_initializer
5733           {
5734                 current_variable.Initializer = (Expression) $2;
5735                 $$ = current_variable;
5736           }
5737         ;
5738
5739
5740 // LINQ
5741
5742 query_expression
5743         : first_from_clause query_body 
5744           {
5745                 lexer.query_parsing = false;
5746                         
5747                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5748                         
5749                 from.Tail.Next = (Linq.AQueryClause)$2;
5750                 $$ = from;
5751                 
5752                 current_block.SetEndLocation (lexer.Location);
5753                 current_block = current_block.Parent;
5754           }
5755         | nested_from_clause query_body
5756           {
5757                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5758                         
5759                 from.Tail.Next = (Linq.AQueryClause)$2;
5760                 $$ = from;
5761                 
5762                 current_block.SetEndLocation (lexer.Location);
5763                 current_block = current_block.Parent;
5764           }     
5765
5766         // Bubble up COMPLETE_COMPLETION productions
5767         | first_from_clause COMPLETE_COMPLETION {
5768                 lexer.query_parsing = false;
5769                 $$ = $1;
5770
5771                 current_block.SetEndLocation (lexer.Location);
5772                 current_block = current_block.Parent;
5773           }
5774         | nested_from_clause COMPLETE_COMPLETION {
5775                 $$ = $1;
5776                 current_block.SetEndLocation (lexer.Location);
5777                 current_block = current_block.Parent;
5778           }
5779         ;
5780         
5781 first_from_clause
5782         : FROM_FIRST identifier_inside_body IN expression
5783           {
5784                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5785           
5786                 var lt = (Tokenizer.LocatedToken) $2;
5787                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
5788                 $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)));
5789           }
5790         | FROM_FIRST type identifier_inside_body IN expression
5791           {
5792                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5793           
5794                 var lt = (Tokenizer.LocatedToken) $3;
5795                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
5796                 $$ = new Linq.QueryExpression (
5797                         new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
5798                                 IdentifierType = (FullNamedExpression)$2
5799                         }
5800                 );
5801           }
5802         ;
5803
5804 nested_from_clause
5805         : FROM identifier_inside_body IN expression
5806           {
5807                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5808           
5809                 var lt = (Tokenizer.LocatedToken) $2;
5810                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
5811                 $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)));
5812           }
5813         | FROM type identifier_inside_body IN expression
5814           {
5815                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5816           
5817                 var lt = (Tokenizer.LocatedToken) $3;
5818                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
5819                 $$ = new Linq.QueryExpression (
5820                         new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
5821                                 IdentifierType = (FullNamedExpression)$2
5822                         }
5823                 );
5824           }
5825         ;
5826         
5827 from_clause
5828         : FROM identifier_inside_body IN
5829           {
5830                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5831           }
5832           expression_or_error
5833           {
5834                 var lt = (Tokenizer.LocatedToken) $2;
5835                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
5836                 $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$5, GetLocation ($1));
5837                 
5838                 current_block.SetEndLocation (lexer.Location);
5839                 current_block = current_block.Parent;
5840                 
5841                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5842           }       
5843         | FROM type identifier_inside_body IN
5844           {
5845                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5846           }
5847           expression_or_error
5848           {
5849                 var lt = (Tokenizer.LocatedToken) $3;
5850                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
5851
5852                 $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) {
5853                         IdentifierType = (FullNamedExpression)$2
5854                 };
5855                 
5856                 current_block.SetEndLocation (lexer.Location);
5857                 current_block = current_block.Parent;
5858                 
5859                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5860           }
5861         ;       
5862
5863 query_body
5864         : query_body_clauses select_or_group_clause opt_query_continuation 
5865           {
5866                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5867                 
5868                 if ($3 != null)
5869                         head.Next = (Linq.AQueryClause)$3;
5870                                 
5871                 if ($1 != null) {
5872                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5873                         clause.Tail.Next = head;
5874                         head = clause;
5875                 }
5876                 
5877                 $$ = head;
5878           }
5879         | select_or_group_clause opt_query_continuation
5880           {
5881                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5882
5883                 if ($1 != null) {
5884                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5885                         clause.Tail.Next = head;
5886                         head = clause;
5887                 }
5888                 
5889                 $$ = head;
5890           }
5891         | query_body_clauses COMPLETE_COMPLETION
5892         | query_body_clauses error
5893           {
5894                 report.Error (742, GetLocation ($2), "Unexpected symbol `{0}'. A query body must end with select or group clause", GetSymbolName (yyToken));
5895                 $$ = $1;
5896           }
5897         | error
5898           {
5899                 Error_SyntaxError (yyToken);
5900                 $$ = null;
5901           }
5902         ;
5903         
5904 select_or_group_clause
5905         : SELECT
5906           {
5907                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5908           }
5909           expression_or_error
5910           {
5911                 $$ = new Linq.Select ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
5912
5913                 current_block.SetEndLocation (lexer.Location);
5914                 current_block = current_block.Parent;
5915           }
5916         | GROUP
5917           {
5918                 if (linq_clause_blocks == null)
5919                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
5920                         
5921                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5922                 linq_clause_blocks.Push ((Linq.QueryBlock)current_block);
5923           }
5924           expression_or_error
5925           {
5926                 current_block.SetEndLocation (lexer.Location);
5927                 current_block = current_block.Parent;
5928           
5929                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5930           }
5931           BY expression_or_error
5932           {
5933                 $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1));
5934                 lbag.AddLocation ($$, GetLocation ($5));
5935                 
5936                 current_block.SetEndLocation (lexer.Location);
5937                 current_block = current_block.Parent;
5938           }
5939         ;
5940         
5941 query_body_clauses
5942         : query_body_clause
5943         | query_body_clauses query_body_clause
5944           {
5945                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
5946                 $$ = $1;
5947           }
5948         ;
5949         
5950 query_body_clause
5951         : from_clause
5952         | let_clause 
5953         | where_clause
5954         | join_clause
5955         | orderby_clause
5956         ;
5957         
5958 let_clause
5959         : LET identifier_inside_body ASSIGN 
5960           {
5961                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5962           }
5963           expression_or_error
5964           {
5965                 var lt = (Tokenizer.LocatedToken) $2;
5966                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
5967                 $$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1));
5968                 lbag.AddLocation ($$, GetLocation ($3));
5969                 
5970                 current_block.SetEndLocation (lexer.Location);
5971                 current_block = current_block.Parent;
5972                 
5973                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5974           }
5975         ;
5976
5977 where_clause
5978         : WHERE
5979           {
5980                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5981           }
5982           expression_or_error
5983           {
5984                 $$ = new Linq.Where ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
5985
5986                 current_block.SetEndLocation (lexer.Location);
5987                 current_block = current_block.Parent;
5988           }
5989         ;
5990         
5991 join_clause
5992         : JOIN identifier_inside_body IN
5993           {
5994                 if (linq_clause_blocks == null)
5995                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
5996                         
5997                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
5998                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
5999           }
6000           expression_or_error ON
6001           {
6002                 current_block.SetEndLocation (lexer.Location);
6003                 current_block = current_block.Parent;
6004
6005                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6006                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6007           }
6008           expression_or_error EQUALS
6009           {
6010                 current_block.AddStatement (new ContextualReturn ((Expression) $8));
6011                 current_block.SetEndLocation (lexer.Location);
6012                 current_block = current_block.Parent;
6013
6014                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6015           }
6016           expression_or_error opt_join_into
6017           {
6018                 current_block.AddStatement (new ContextualReturn ((Expression) $11));
6019                 current_block.SetEndLocation (lexer.Location);
6020           
6021                 var outer_selector = linq_clause_blocks.Pop ();
6022                 var block = linq_clause_blocks.Pop ();
6023
6024                 var lt = (Tokenizer.LocatedToken) $2;   
6025                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6026                 Linq.RangeVariable into;
6027                 
6028                 if ($12 == null) {
6029                         into = sn;
6030                         $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1));
6031                         lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9));
6032                 } else {
6033                         //
6034                         // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
6035                         //
6036                         var parent = block.Parent;
6037                         while (parent is Linq.QueryBlock) {
6038                                 parent = parent.Parent;
6039                         }
6040                         current_block.Parent = parent;
6041                         
6042                         ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6043                 
6044                         lt = (Tokenizer.LocatedToken) $12;
6045                         into = new Linq.RangeVariable (lt.Value, lt.Location);
6046
6047                         $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1));   
6048                         lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($12));
6049                 }
6050
6051                 current_block = block.Parent;
6052                 ((Linq.QueryBlock)current_block).AddRangeVariable (into);
6053           }
6054         | JOIN type identifier_inside_body IN
6055           {
6056                 if (linq_clause_blocks == null)
6057                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
6058                         
6059                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6060                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6061           }
6062           expression_or_error ON
6063           {
6064                 current_block.SetEndLocation (lexer.Location);
6065                 current_block = current_block.Parent;
6066
6067                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6068                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
6069           }
6070           expression_or_error EQUALS
6071           {
6072                 current_block.AddStatement (new ContextualReturn ((Expression) $9));
6073                 current_block.SetEndLocation (lexer.Location);
6074                 current_block = current_block.Parent;
6075
6076                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6077           }
6078           expression_or_error opt_join_into
6079           {
6080                 current_block.AddStatement (new ContextualReturn ((Expression) $12));
6081                 current_block.SetEndLocation (lexer.Location);
6082           
6083                 var outer_selector = linq_clause_blocks.Pop ();
6084                 var block = linq_clause_blocks.Pop ();
6085                 
6086                 var lt = (Tokenizer.LocatedToken) $3;
6087                 var sn = new Linq.RangeVariable (lt.Value, lt.Location);
6088                 Linq.RangeVariable into;
6089                 
6090                 if ($13 == null) {
6091                         into = sn;              
6092                         $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) {
6093                                 IdentifierType = (FullNamedExpression)$2
6094                         };
6095                 } else {
6096                         //
6097                         // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
6098                         //
6099                         var parent = block.Parent;
6100                         while (parent is Linq.QueryBlock) {
6101                                 parent = parent.Parent;
6102                         }
6103                         current_block.Parent = parent;
6104                 
6105                         ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
6106                 
6107                         lt = (Tokenizer.LocatedToken) $13;
6108                         into = new Linq.RangeVariable (lt.Value, lt.Location); // TODO:
6109                         
6110                         $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)) {
6111                                 IdentifierType = (FullNamedExpression)$2
6112                         };                      
6113                 }
6114                 
6115                 current_block = block.Parent;
6116                 ((Linq.QueryBlock)current_block).AddRangeVariable (into);               
6117           }
6118         ;
6119         
6120 opt_join_into
6121         : /* empty */
6122         | INTO identifier_inside_body
6123           {
6124                 $$ = $2;
6125           }
6126         ;
6127         
6128 orderby_clause
6129         : ORDERBY
6130           {
6131                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6132           }
6133           orderings
6134           {
6135                 current_block.SetEndLocation (lexer.Location);
6136                 current_block = current_block.Parent;
6137           
6138                 $$ = $3;
6139           }
6140         ;
6141         
6142 orderings
6143         : order_by
6144         | order_by COMMA
6145           {
6146                 current_block.SetEndLocation (lexer.Location);
6147                 current_block = current_block.Parent;
6148           
6149                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6150           }
6151           orderings_then_by
6152           {
6153                 ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4;
6154                 $$ = $1;
6155           }
6156         ;
6157         
6158 orderings_then_by
6159         : then_by
6160         | orderings_then_by COMMA
6161          {
6162                 current_block.SetEndLocation (lexer.Location);
6163                 current_block = current_block.Parent;
6164           
6165                 current_block = new Linq.QueryBlock ((Linq.QueryBlock) current_block, lexer.Location);   
6166          }
6167          then_by
6168          {
6169                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$4;
6170                 $$ = $1;
6171          }
6172         ;       
6173         
6174 order_by
6175         : expression
6176           {
6177                 $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
6178           }
6179         | expression ASCENDING
6180           {
6181                 $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
6182                 lbag.AddLocation ($$, GetLocation ($2));
6183           }
6184         | expression DESCENDING
6185           {
6186                 $$ = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)$1);      
6187                 lbag.AddLocation ($$, GetLocation ($2));
6188           }
6189         ;
6190
6191 then_by
6192         : expression
6193           {
6194                 $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
6195           }
6196         | expression ASCENDING
6197           {
6198                 $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
6199                 lbag.AddLocation ($$, GetLocation ($2));
6200           }
6201         | expression DESCENDING
6202           {
6203                 $$ = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)$1);       
6204                 lbag.AddLocation ($$, GetLocation ($2));
6205           }     
6206         ;
6207
6208
6209 opt_query_continuation
6210         : /* empty */
6211         | INTO identifier_inside_body
6212           {
6213                 // query continuation block is not linked with query block but with block
6214                 // before. This means each query can use same range variable names for
6215                 // different identifiers.
6216
6217                 current_block.SetEndLocation (GetLocation ($1));
6218                 current_block = current_block.Parent;
6219         
6220                 current_block = new Linq.QueryBlock (current_block, lexer.Location);
6221                 
6222                 if (linq_clause_blocks == null)
6223                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
6224                         
6225                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);              
6226           }
6227           query_body
6228           {
6229                 var current_block = linq_clause_blocks.Pop ();    
6230                 var lt = (Tokenizer.LocatedToken) $2;
6231                 var rv = new Linq.RangeVariable (lt.Value, lt.Location);
6232                 $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation ($1)) {
6233                         next = (Linq.AQueryClause)$4
6234                 };
6235           }
6236         ;
6237         
6238 //
6239 // Support for using the compiler as an interactive parser
6240 //
6241 // The INTERACTIVE_PARSER token is first sent to parse our
6242 // productions;  If the result is a Statement, the parsing
6243 // is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
6244 // to setup the blocks in advance.
6245 //
6246 // This setup is here so that in the future we can add 
6247 // support for other constructs (type parsing, namespaces, etc)
6248 // that do not require a block to be setup in advance
6249 //
6250
6251 interactive_parsing
6252         : EVAL_STATEMENT_PARSER EOF 
6253         | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives opt_COMPLETE_COMPLETION
6254         | EVAL_STATEMENT_PARSER
6255          { 
6256                 current_container = current_type = new Class (current_container, new MemberName ("<InteractiveExpressionClass>"), Modifiers.PUBLIC, null);
6257
6258                 // (ref object retval)
6259                 Parameter [] mpar = new Parameter [1];
6260                 mpar [0] = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null);
6261
6262                 ParametersCompiled pars = new ParametersCompiled (mpar);
6263                 var mods = Modifiers.PUBLIC | Modifiers.STATIC;
6264                 if (settings.Unsafe)
6265                         mods |= Modifiers.UNSAFE;
6266
6267                 current_local_parameters = pars;
6268                 Method method = new Method (
6269                         current_type,
6270                         new TypeExpression (compiler.BuiltinTypes.Void, Location.Null),
6271                         mods,
6272                         new MemberName ("Host"),
6273                         pars,
6274                         null /* attributes */);
6275                         
6276                 current_type.AddMember (method);                        
6277
6278                 oob_stack.Push (method);
6279                 ++lexer.parsing_block;
6280                 start_block (lexer.Location);
6281           }             
6282           interactive_statement_list opt_COMPLETE_COMPLETION
6283           {
6284                 --lexer.parsing_block;
6285                 Method method = (Method) oob_stack.Pop ();
6286
6287                 method.Block = (ToplevelBlock) end_block(lexer.Location);
6288
6289                 InteractiveResult = (Class) pop_current_class ();
6290                 current_local_parameters = null;
6291           } 
6292         | EVAL_COMPILATION_UNIT_PARSER interactive_compilation_unit
6293         ;
6294
6295 interactive_compilation_unit
6296         : opt_extern_alias_directives opt_using_directives
6297         | opt_extern_alias_directives opt_using_directives namespace_or_type_declarations
6298         ;
6299
6300 opt_COMPLETE_COMPLETION
6301         : /* nothing */
6302         | COMPLETE_COMPLETION
6303         ;
6304
6305 close_brace_or_complete_completion
6306         : CLOSE_BRACE
6307         | COMPLETE_COMPLETION
6308         ;
6309         
6310 //
6311 // XML documentation code references micro parser
6312 //
6313 documentation_parsing
6314         : DOC_SEE doc_cref
6315           {
6316                 module.DocumentationBuilder.ParsedName = (MemberName) $2;
6317           }
6318         ;
6319
6320 doc_cref
6321         : doc_type_declaration_name opt_doc_method_sig
6322           {
6323                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$2;
6324           }
6325         | builtin_types opt_doc_method_sig
6326           {
6327                 module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
6328                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$2;
6329                 $$ = null;
6330           }
6331         | builtin_types DOT IDENTIFIER opt_doc_method_sig
6332           {
6333                 module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
6334                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$4;
6335                 var lt = (Tokenizer.LocatedToken) $3;
6336                 $$ = new MemberName (lt.Value);
6337           }
6338         | doc_type_declaration_name DOT THIS
6339           {
6340                 $$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
6341           }
6342         | doc_type_declaration_name DOT THIS OPEN_BRACKET
6343           {
6344                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
6345           }
6346           opt_doc_parameters CLOSE_BRACKET
6347           {
6348                 module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$6;
6349                 $$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
6350           }
6351         | EXPLICIT OPERATOR type opt_doc_method_sig
6352           {
6353                 var p = (List<DocumentationParameter>)$4 ?? new List<DocumentationParameter> (1);
6354                 p.Add (new DocumentationParameter ((FullNamedExpression) $3));
6355                 module.DocumentationBuilder.ParsedParameters = p;
6356                 module.DocumentationBuilder.ParsedOperator = Operator.OpType.Explicit;
6357                 $$ = null;
6358           }
6359         | IMPLICIT OPERATOR type opt_doc_method_sig
6360           {
6361                 var p = (List<DocumentationParameter>)$4 ?? new List<DocumentationParameter> (1);
6362                 p.Add (new DocumentationParameter ((FullNamedExpression) $3));
6363                 module.DocumentationBuilder.ParsedParameters = p;
6364                 module.DocumentationBuilder.ParsedOperator = Operator.OpType.Implicit;
6365                 $$ = null;
6366           }       
6367         | OPERATOR overloadable_operator opt_doc_method_sig
6368           {
6369                 var p = (List<DocumentationParameter>)$3 ?? new List<DocumentationParameter> (1);
6370                 module.DocumentationBuilder.ParsedParameters = p;
6371                 module.DocumentationBuilder.ParsedOperator = (Operator.OpType) $2;
6372                 $$ = null;
6373           }
6374         ;
6375         
6376 doc_type_declaration_name
6377         : type_declaration_name
6378         | doc_type_declaration_name DOT type_declaration_name
6379           {
6380                 $$ = new MemberName (((MemberName) $1), (MemberName) $3);
6381           }
6382         ;
6383         
6384 opt_doc_method_sig
6385         : /* empty */
6386         | OPEN_PARENS
6387           {
6388                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
6389           }
6390           opt_doc_parameters CLOSE_PARENS
6391           {
6392                 $$ = $3;
6393           }
6394         ;
6395         
6396 opt_doc_parameters
6397         : /* empty */
6398           {
6399                 $$ = new List<DocumentationParameter> (0);
6400           }
6401         | doc_parameters
6402         ;
6403         
6404 doc_parameters
6405         : doc_parameter
6406           {
6407                 var parameters = new List<DocumentationParameter> ();
6408                 parameters.Add ((DocumentationParameter) $1);
6409                 $$ = parameters;
6410           }
6411         | doc_parameters COMMA doc_parameter
6412           {
6413                 var parameters = $1 as List<DocumentationParameter>;
6414                 parameters.Add ((DocumentationParameter) $3);
6415                 $$ = parameters;
6416           }
6417         ;
6418         
6419 doc_parameter
6420         : opt_parameter_modifier parameter_type
6421           {
6422                 if ($1 != null)
6423                         $$ = new DocumentationParameter ((Parameter.Modifier) $1, (FullNamedExpression) $2);
6424                 else
6425                         $$ = new DocumentationParameter ((FullNamedExpression) $2);
6426           }
6427         ;
6428         
6429 %%
6430
6431 // <summary>
6432 //  A class used to hold info about an operator declarator
6433 // </summary>
6434 class OperatorDeclaration {
6435         public readonly Operator.OpType optype;
6436         public readonly FullNamedExpression ret_type;
6437         public readonly Location location;
6438
6439         public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
6440         {
6441                 optype = op;
6442                 this.ret_type = ret_type;
6443                 this.location = location;
6444         }
6445 }
6446
6447 void Error_ExpectingTypeName (Expression expr)
6448 {
6449         if (expr is Invocation){
6450                 report.Error (1002, expr.Location, "Expecting `;'");
6451         } else {
6452                 Expression.Error_InvalidExpressionStatement (report, expr.Location);
6453         }
6454 }
6455
6456 void Error_ParameterModifierNotValid (string modifier, Location loc)
6457 {
6458         report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
6459                                       modifier);
6460 }
6461
6462 void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
6463 {
6464         report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
6465                 Parameter.GetModifierSignature (mod));
6466 }
6467
6468 void Error_TypeExpected (Location loc)
6469 {
6470         report.Error (1031, loc, "Type expected");
6471 }
6472
6473 void Error_UnsafeCodeNotAllowed (Location loc)
6474 {
6475         report.Error (227, loc, "Unsafe code requires the `unsafe' command line option to be specified");
6476 }
6477
6478 void Warning_EmptyStatement (Location loc)
6479 {
6480         report.Warning (642, 3, loc, "Possible mistaken empty statement");
6481 }
6482
6483 void Error_NamedArgumentExpected (NamedArgument a)
6484 {
6485         report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
6486 }
6487
6488 void Error_MissingInitializer (Location loc)
6489 {
6490         report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration");
6491 }
6492
6493 void push_current_container (TypeDefinition tc, object partial_token)
6494 {
6495         if (module.Evaluator != null){
6496                 tc.Definition.Modifiers = tc.ModFlags = (tc.ModFlags & ~Modifiers.AccessibilityMask) | Modifiers.PUBLIC;
6497                 if (undo == null)
6498                         undo = new Undo ();
6499
6500                 undo.AddTypeContainer (current_container, tc);
6501         }
6502         
6503         if (partial_token != null)
6504                 current_container.AddPartial (tc);
6505         else
6506                 current_container.AddTypeContainer (tc);
6507                 
6508         ++lexer.parsing_declaration;
6509         current_container = tc;
6510         current_type = tc;
6511 }
6512
6513 TypeContainer pop_current_class ()
6514 {
6515         var retval = current_container;
6516
6517         current_container = current_container.Parent;
6518         current_type = current_type.Parent as TypeDefinition;
6519
6520         return retval;
6521 }
6522
6523 [System.Diagnostics.Conditional ("FULL_AST")]
6524 void StoreModifierLocation (object token, Location loc)
6525 {
6526         if (lbag == null)
6527                 return;
6528
6529         if (mod_locations == null)
6530                 mod_locations = new List<Tuple<Modifiers, Location>> ();
6531
6532         mod_locations.Add (Tuple.Create ((Modifiers) token, loc));
6533 }
6534
6535 string CheckAttributeTarget (string a, Location l)
6536 {
6537         switch (a) {
6538         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
6539                         return a;
6540         }
6541
6542         report.Warning (658, 1, l,
6543                  "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
6544         return string.Empty;
6545 }
6546
6547 static bool IsUnaryOperator (Operator.OpType op)
6548 {
6549         switch (op) {
6550                 
6551         case Operator.OpType.LogicalNot: 
6552         case Operator.OpType.OnesComplement: 
6553         case Operator.OpType.Increment:
6554         case Operator.OpType.Decrement:
6555         case Operator.OpType.True: 
6556         case Operator.OpType.False: 
6557         case Operator.OpType.UnaryPlus: 
6558         case Operator.OpType.UnaryNegation:
6559                 return true;
6560         }
6561         return false;
6562 }
6563
6564 void syntax_error (Location l, string msg)
6565 {
6566         report.Error (1003, l, "Syntax error, " + msg);
6567 }
6568
6569 Tokenizer lexer;
6570
6571 public Tokenizer Lexer {
6572         get {
6573                 return lexer;
6574         }
6575 }                  
6576
6577 public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, ParserSession session)
6578         : this (reader, file, file.Compiler.Report, session)
6579 {
6580 }
6581
6582 public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report, ParserSession session)
6583 {
6584         this.file = file;
6585         current_container = current_namespace = file;
6586         
6587         this.module = file.Module;
6588         this.compiler = file.Compiler;
6589         this.settings = compiler.Settings;
6590         this.report = report;
6591         
6592         lang_version = settings.Version;
6593         yacc_verbose_flag = settings.VerboseParserFlag;
6594         doc_support = settings.DocumentationFile != null;
6595         lexer = new Tokenizer (reader, file, session);
6596         oob_stack = new Stack<object> ();
6597         lbag = session.LocationsBag;
6598         use_global_stacks = session.UseJayGlobalArrays;
6599         parameters_bucket = session.ParametersStack;
6600 }
6601
6602 public void parse ()
6603 {
6604         eof_token = Token.EOF;
6605         
6606         try {
6607                 if (yacc_verbose_flag > 1)
6608                         yyparse (lexer, new yydebug.yyDebugSimple ());
6609                 else
6610                         yyparse (lexer);
6611                         
6612                 Tokenizer tokenizer = lexer as Tokenizer;
6613                 tokenizer.cleanup ();           
6614         } catch (Exception e){
6615                 if (e is yyParser.yyUnexpectedEof) {
6616                         Error_SyntaxError (yyToken);
6617                         UnexpectedEOF = true;
6618                         return;
6619                 }
6620                         
6621                 if (e is yyParser.yyException) {
6622                         report.Error (-25, lexer.Location, "Parsing error");
6623                 } else {
6624                         // Used by compiler-tester to test internal errors
6625                         if (yacc_verbose_flag > 0 || e is FatalException)
6626                                 throw;
6627                 
6628                         report.Error (589, lexer.Location, "Internal compiler error during parsing" + e);
6629                 }
6630         }
6631 }
6632
6633 void CheckToken (int error, int yyToken, string msg, Location loc)
6634 {
6635         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
6636                 report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken));
6637         else
6638                 report.Error (error, loc, msg);
6639 }
6640
6641 string ConsumeStoredComment ()
6642 {
6643         string s = tmpComment;
6644         tmpComment = null;
6645         Lexer.doc_state = XmlCommentState.Allowed;
6646         return s;
6647 }
6648
6649 void FeatureIsNotAvailable (Location loc, string feature)
6650 {
6651         report.FeatureIsNotAvailable (compiler, loc, feature);
6652 }
6653
6654 Location GetLocation (object obj)
6655 {
6656         var lt = obj as Tokenizer.LocatedToken;
6657         if (lt != null)
6658                 return lt.Location;
6659                 
6660         var mn = obj as MemberName;
6661         if (mn != null)
6662                 return mn.Location;
6663                 
6664         var expr = obj as Expression;
6665         if (expr != null)
6666                 return expr.Location;
6667
6668         return lexer.Location;
6669 }
6670
6671 void start_block (Location loc)
6672 {
6673         if (current_block == null) {
6674                 current_block = new ToplevelBlock (compiler, current_local_parameters, loc);
6675                 parsing_anonymous_method = false;
6676         } else if (parsing_anonymous_method) {
6677                 current_block = new ParametersBlock (current_block, current_local_parameters, loc);
6678                 parsing_anonymous_method = false;
6679         } else {
6680                 current_block = new ExplicitBlock (current_block, loc, Location.Null);
6681         }
6682 }
6683
6684 Block
6685 end_block (Location loc)
6686 {
6687         Block retval = current_block.Explicit;
6688         retval.SetEndLocation (loc);
6689         current_block = retval.Parent;
6690         return retval;
6691 }
6692
6693 void start_anonymous (bool isLambda, ParametersCompiled parameters, bool isAsync, Location loc)
6694 {
6695         oob_stack.Push (current_anonymous_method);
6696         oob_stack.Push (current_local_parameters);
6697         oob_stack.Push (current_variable);
6698         oob_stack.Push (async_block);
6699
6700         current_local_parameters = parameters;
6701         if (isLambda) {
6702                 if (lang_version <= LanguageVersion.ISO_2)
6703                         FeatureIsNotAvailable (loc, "lambda expressions");
6704
6705                 current_anonymous_method = new LambdaExpression (loc);
6706         } else {
6707                 if (lang_version == LanguageVersion.ISO_1)
6708                         FeatureIsNotAvailable (loc, "anonymous methods");
6709                         
6710                 current_anonymous_method = new AnonymousMethodExpression (loc);
6711         }
6712
6713         async_block = isAsync;
6714         // Force the next block to be created as a ToplevelBlock
6715         parsing_anonymous_method = true;
6716 }
6717
6718 /*
6719  * Completes the anonymous method processing, if lambda_expr is null, this
6720  * means that we have a Statement instead of an Expression embedded 
6721  */
6722 AnonymousMethodExpression end_anonymous (ParametersBlock anon_block)
6723 {
6724         AnonymousMethodExpression retval;
6725
6726         if (async_block)
6727                 anon_block.IsAsync = true;
6728
6729         current_anonymous_method.Block = anon_block;
6730         retval = current_anonymous_method;
6731
6732         async_block = (bool) oob_stack.Pop ();
6733         current_variable = (BlockVariableDeclaration) oob_stack.Pop ();
6734         current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
6735         current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
6736
6737         return retval;
6738 }
6739
6740 void Error_SyntaxError (int token)
6741 {
6742         Error_SyntaxError (0, token);
6743 }
6744
6745 void Error_SyntaxError (int error_code, int token)
6746 {
6747         Error_SyntaxError (error_code, token, "Unexpected symbol");
6748 }
6749
6750 void Error_SyntaxError (int error_code, int token, string msg)
6751 {
6752         Lexer.CompleteOnEOF = false;
6753
6754         // An error message has been reported by tokenizer
6755         if (token == Token.ERROR)
6756                 return;
6757
6758         string symbol = GetSymbolName (token);
6759         string expecting = GetExpecting ();
6760         var loc = lexer.Location - symbol.Length;
6761         
6762         if (error_code == 0) {
6763                 if (expecting == "`identifier'") {
6764                         if (token > Token.FIRST_KEYWORD && token < Token.LAST_KEYWORD) {
6765                                 report.Error (1041, loc, "Identifier expected, `{0}' is a keyword", symbol);
6766                                 return;
6767                         }
6768                         
6769                         error_code = 1001;
6770                         expecting = "identifier";
6771                 } else if (expecting == "`)'") {
6772                         error_code = 1026;
6773                 } else {
6774                         error_code = 1525;
6775                 }
6776         }
6777         
6778         if (string.IsNullOrEmpty (expecting))
6779                 report.Error (error_code, loc, "{1} `{0}'", symbol, msg);
6780         else
6781                 report.Error (error_code, loc, "{2} `{0}', expecting {1}", symbol, expecting, msg);       
6782 }
6783
6784 string GetExpecting ()
6785 {
6786         int [] tokens = yyExpectingTokens (yyExpectingState);
6787         var names = new List<string> (tokens.Length);
6788         bool has_type = false;
6789         bool has_identifier = false;
6790         for (int i = 0; i < tokens.Length; i++){
6791                 int token = tokens [i];
6792                 has_identifier |= token == Token.IDENTIFIER;
6793                 
6794                 string name = GetTokenName (token);
6795                 if (name == "<internal>")
6796                         continue;
6797                         
6798                 has_type |= name == "type";
6799                 if (names.Contains (name))
6800                         continue;
6801                 
6802                 names.Add (name);
6803         }
6804
6805         //
6806         // Too many tokens to enumerate
6807         //
6808         if (names.Count > 8)
6809                 return null;
6810
6811         if (has_type && has_identifier)
6812                 names.Remove ("identifier");
6813
6814         if (names.Count == 1)
6815                 return "`" + GetTokenName (tokens [0]) + "'";
6816         
6817         StringBuilder sb = new StringBuilder ();
6818         names.Sort ();
6819         int count = names.Count;
6820         for (int i = 0; i < count; i++){
6821                 bool last = i + 1 == count;
6822                 if (last)
6823                         sb.Append ("or ");
6824                 sb.Append ('`');
6825                 sb.Append (names [i]);
6826                 sb.Append (last ? "'" : count < 3 ? "' " : "', ");
6827         }
6828         return sb.ToString ();
6829 }
6830
6831
6832 string GetSymbolName (int token)
6833 {
6834         switch (token){
6835         case Token.LITERAL:
6836                 return ((Constant)lexer.Value).GetValue ().ToString ();
6837         case Token.IDENTIFIER:
6838                 return ((Tokenizer.LocatedToken)lexer.Value).Value;
6839
6840         case Token.BOOL:
6841                 return "bool";
6842         case Token.BYTE:
6843                 return "byte";
6844         case Token.CHAR:
6845                 return "char";
6846         case Token.VOID:
6847                 return "void";
6848         case Token.DECIMAL:
6849                 return "decimal";
6850         case Token.DOUBLE:
6851                 return "double";
6852         case Token.FLOAT:
6853                 return "float";
6854         case Token.INT:
6855                 return "int";
6856         case Token.LONG:
6857                 return "long";
6858         case Token.SBYTE:
6859                 return "sbyte";
6860         case Token.SHORT:
6861                 return "short";
6862         case Token.STRING:
6863                 return "string";
6864         case Token.UINT:
6865                 return "uint";
6866         case Token.ULONG:
6867                 return "ulong";
6868         case Token.USHORT:
6869                 return "ushort";
6870         case Token.OBJECT:
6871                 return "object";
6872                 
6873         case Token.PLUS:
6874                 return "+";
6875         case Token.UMINUS:
6876         case Token.MINUS:
6877                 return "-";
6878         case Token.BANG:
6879                 return "!";
6880         case Token.BITWISE_AND:
6881                 return "&";
6882         case Token.BITWISE_OR:
6883                 return "|";
6884         case Token.STAR:
6885                 return "*";
6886         case Token.PERCENT:
6887                 return "%";
6888         case Token.DIV:
6889                 return "/";
6890         case Token.CARRET:
6891                 return "^";
6892         case Token.OP_INC:
6893                 return "++";
6894         case Token.OP_DEC:
6895                 return "--";
6896         case Token.OP_SHIFT_LEFT:
6897                 return "<<";
6898         case Token.OP_SHIFT_RIGHT:
6899                 return ">>";
6900         case Token.OP_LT:
6901                 return "<";
6902         case Token.OP_GT:
6903                 return ">";
6904         case Token.OP_LE:
6905                 return "<=";
6906         case Token.OP_GE:
6907                 return ">=";
6908         case Token.OP_EQ:
6909                 return "==";
6910         case Token.OP_NE:
6911                 return "!=";
6912         case Token.OP_AND:
6913                 return "&&";
6914         case Token.OP_OR:
6915                 return "||";
6916         case Token.OP_PTR:
6917                 return "->";
6918         case Token.OP_COALESCING:       
6919                 return "??";
6920         case Token.OP_MULT_ASSIGN:
6921                 return "*=";
6922         case Token.OP_DIV_ASSIGN:
6923                 return "/=";
6924         case Token.OP_MOD_ASSIGN:
6925                 return "%=";
6926         case Token.OP_ADD_ASSIGN:
6927                 return "+=";
6928         case Token.OP_SUB_ASSIGN:
6929                 return "-=";
6930         case Token.OP_SHIFT_LEFT_ASSIGN:
6931                 return "<<=";
6932         case Token.OP_SHIFT_RIGHT_ASSIGN:
6933                 return ">>=";
6934         case Token.OP_AND_ASSIGN:
6935                 return "&=";
6936         case Token.OP_XOR_ASSIGN:
6937                 return "^=";
6938         case Token.OP_OR_ASSIGN:
6939                 return "|=";
6940         }
6941
6942         return GetTokenName (token);
6943 }
6944
6945 static string GetTokenName (int token)
6946 {
6947         switch (token){
6948         case Token.ABSTRACT:
6949                 return "abstract";
6950         case Token.AS:
6951                 return "as";
6952         case Token.ADD:
6953                 return "add";
6954         case Token.ASYNC:
6955                 return "async";
6956         case Token.BASE:
6957                 return "base";
6958         case Token.BREAK:
6959                 return "break";
6960         case Token.CASE:
6961                 return "case";
6962         case Token.CATCH:
6963                 return "catch";
6964         case Token.CHECKED:
6965                 return "checked";
6966         case Token.CLASS:
6967                 return "class";
6968         case Token.CONST:
6969                 return "const";
6970         case Token.CONTINUE:
6971                 return "continue";
6972         case Token.DEFAULT:
6973                 return "default";
6974         case Token.DELEGATE:
6975                 return "delegate";
6976         case Token.DO:
6977                 return "do";
6978         case Token.ELSE:
6979                 return "else";
6980         case Token.ENUM:
6981                 return "enum";
6982         case Token.EVENT:
6983                 return "event";
6984         case Token.EXPLICIT:
6985                 return "explicit";
6986         case Token.EXTERN:
6987         case Token.EXTERN_ALIAS:
6988                 return "extern";
6989         case Token.FALSE:
6990                 return "false";
6991         case Token.FINALLY:
6992                 return "finally";
6993         case Token.FIXED:
6994                 return "fixed";
6995         case Token.FOR:
6996                 return "for";
6997         case Token.FOREACH:
6998                 return "foreach";
6999         case Token.GOTO:
7000                 return "goto";
7001         case Token.IF:
7002                 return "if";
7003         case Token.IMPLICIT:
7004                 return "implicit";
7005         case Token.IN:
7006                 return "in";
7007         case Token.INTERFACE:
7008                 return "interface";
7009         case Token.INTERNAL:
7010                 return "internal";
7011         case Token.IS:
7012                 return "is";
7013         case Token.LOCK:
7014                 return "lock";
7015         case Token.NAMESPACE:
7016                 return "namespace";
7017         case Token.NEW:
7018                 return "new";
7019         case Token.NULL:
7020                 return "null";
7021         case Token.OPERATOR:
7022                 return "operator";
7023         case Token.OUT:
7024                 return "out";
7025         case Token.OVERRIDE:
7026                 return "override";
7027         case Token.PARAMS:
7028                 return "params";
7029         case Token.PRIVATE:
7030                 return "private";
7031         case Token.PROTECTED:
7032                 return "protected";
7033         case Token.PUBLIC:
7034                 return "public";
7035         case Token.READONLY:
7036                 return "readonly";
7037         case Token.REF:
7038                 return "ref";
7039         case Token.RETURN:
7040                 return "return";
7041         case Token.REMOVE:
7042                 return "remove";
7043         case Token.SEALED:
7044                 return "sealed";
7045         case Token.SIZEOF:
7046                 return "sizeof";
7047         case Token.STACKALLOC:
7048                 return "stackalloc";
7049         case Token.STATIC:
7050                 return "static";
7051         case Token.STRUCT:
7052                 return "struct";
7053         case Token.SWITCH:
7054                 return "switch";
7055         case Token.THIS:
7056                 return "this";
7057         case Token.THROW:
7058                 return "throw";
7059         case Token.TRUE:
7060                 return "true";
7061         case Token.TRY:
7062                 return "try";
7063         case Token.TYPEOF:
7064                 return "typeof";
7065         case Token.UNCHECKED:
7066                 return "unchecked";
7067         case Token.UNSAFE:
7068                 return "unsafe";
7069         case Token.USING:
7070                 return "using";
7071         case Token.VIRTUAL:
7072                 return "virtual";
7073         case Token.VOLATILE:
7074                 return "volatile";
7075         case Token.WHERE:
7076                 return "where";
7077         case Token.WHILE:
7078                 return "while";
7079         case Token.ARGLIST:
7080                 return "__arglist";
7081         case Token.REFVALUE:
7082                 return "__refvalue";
7083         case Token.REFTYPE:
7084                 return "__reftype";
7085         case Token.MAKEREF:
7086                 return "__makeref";
7087         case Token.PARTIAL:
7088                 return "partial";
7089         case Token.ARROW:
7090                 return "=>";
7091         case Token.FROM:
7092         case Token.FROM_FIRST:
7093                 return "from";
7094         case Token.JOIN:
7095                 return "join";
7096         case Token.ON:
7097                 return "on";
7098         case Token.EQUALS:
7099                 return "equals";
7100         case Token.SELECT:
7101                 return "select";
7102         case Token.GROUP:
7103                 return "group";
7104         case Token.BY:
7105                 return "by";
7106         case Token.LET:
7107                 return "let";
7108         case Token.ORDERBY:
7109                 return "orderby";
7110         case Token.ASCENDING:
7111                 return "ascending";
7112         case Token.DESCENDING:
7113                 return "descending";
7114         case Token.INTO:
7115                 return "into";
7116         case Token.GET:
7117                 return "get";
7118         case Token.SET:
7119                 return "set";
7120         case Token.OPEN_BRACE:
7121                 return "{";
7122         case Token.CLOSE_BRACE:
7123                 return "}";
7124         case Token.OPEN_BRACKET:
7125         case Token.OPEN_BRACKET_EXPR:
7126                 return "[";
7127         case Token.CLOSE_BRACKET:
7128                 return "]";
7129         case Token.OPEN_PARENS_CAST:
7130         case Token.OPEN_PARENS_LAMBDA:
7131         case Token.OPEN_PARENS:
7132                 return "(";
7133         case Token.CLOSE_PARENS:
7134                 return ")";
7135         case Token.DOT:
7136                 return ".";
7137         case Token.COMMA:
7138                 return ",";
7139         case Token.DEFAULT_COLON:
7140                 return "default:";
7141         case Token.COLON:
7142                 return ":";
7143         case Token.SEMICOLON:
7144                 return ";";
7145         case Token.TILDE:
7146                 return "~";
7147                 
7148         case Token.PLUS:
7149         case Token.UMINUS:
7150         case Token.MINUS:
7151         case Token.BANG:
7152         case Token.OP_LT:
7153         case Token.OP_GT:
7154         case Token.BITWISE_AND:
7155         case Token.BITWISE_OR:
7156         case Token.STAR:
7157         case Token.PERCENT:
7158         case Token.DIV:
7159         case Token.CARRET:
7160         case Token.OP_INC:
7161         case Token.OP_DEC:
7162         case Token.OP_SHIFT_LEFT:
7163         case Token.OP_SHIFT_RIGHT:
7164         case Token.OP_LE:
7165         case Token.OP_GE:
7166         case Token.OP_EQ:
7167         case Token.OP_NE:
7168         case Token.OP_AND:
7169         case Token.OP_OR:
7170         case Token.OP_PTR:
7171         case Token.OP_COALESCING:       
7172         case Token.OP_MULT_ASSIGN:
7173         case Token.OP_DIV_ASSIGN:
7174         case Token.OP_MOD_ASSIGN:
7175         case Token.OP_ADD_ASSIGN:
7176         case Token.OP_SUB_ASSIGN:
7177         case Token.OP_SHIFT_LEFT_ASSIGN:
7178         case Token.OP_SHIFT_RIGHT_ASSIGN:
7179         case Token.OP_AND_ASSIGN:
7180         case Token.OP_XOR_ASSIGN:
7181         case Token.OP_OR_ASSIGN:
7182                 return "<operator>";
7183
7184         case Token.BOOL:
7185         case Token.BYTE:
7186         case Token.CHAR:
7187         case Token.VOID:
7188         case Token.DECIMAL:
7189         case Token.DOUBLE:
7190         case Token.FLOAT:
7191         case Token.INT:
7192         case Token.LONG:
7193         case Token.SBYTE:
7194         case Token.SHORT:
7195         case Token.STRING:
7196         case Token.UINT:
7197         case Token.ULONG:
7198         case Token.USHORT:
7199         case Token.OBJECT:
7200                 return "type";
7201         
7202         case Token.ASSIGN:
7203                 return "=";
7204         case Token.OP_GENERICS_LT:
7205         case Token.GENERIC_DIMENSION:
7206                 return "<";
7207         case Token.OP_GENERICS_GT:
7208                 return ">";
7209         case Token.INTERR:
7210         case Token.INTERR_NULLABLE:
7211                 return "?";
7212         case Token.DOUBLE_COLON:
7213                 return "::";
7214         case Token.LITERAL:
7215                 return "value";
7216         case Token.IDENTIFIER:
7217         case Token.AWAIT:
7218                 return "identifier";
7219
7220         case Token.EOF:
7221                 return "end-of-file";
7222
7223                 // All of these are internal.
7224         case Token.NONE:
7225         case Token.ERROR:
7226         case Token.FIRST_KEYWORD:
7227         case Token.EVAL_COMPILATION_UNIT_PARSER:
7228         case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER:
7229         case Token.EVAL_STATEMENT_PARSER:
7230         case Token.LAST_KEYWORD:
7231         case Token.GENERATE_COMPLETION:
7232         case Token.COMPLETE_COMPLETION:
7233                 return "<internal>";
7234
7235                 // A bit more robust.
7236         default:
7237                 return yyNames [token];
7238         }
7239 }
7240
7241 /* end end end */
7242 }