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