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