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