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