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