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