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