Ensure that we only reflect into monotouch if the type exists.
[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));
788                 else
789                         $$ = new Attribute (current_attr_target, expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname));
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 te = ((MemberName) $1).GetTypeExpression ();
3736                 if (te.HasTypeArguments)
3737                         Error_TypeExpected (GetLocation ($4));
3738
3739                 var lt = (Tokenizer.LocatedToken) $3;
3740                 $$ = new MemberAccess (te, lt.Value, (int) $4, lt.Location);            
3741           }
3742         ;
3743
3744 generic_dimension
3745         : GENERIC_DIMENSION
3746           {
3747                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
3748                         Report.FeatureIsNotSupported (GetLocation ($1), "generics");
3749                 else if (RootContext.Version < LanguageVersion.ISO_2)
3750                         Report.FeatureIsNotAvailable (GetLocation ($1), "generics");
3751
3752                 $$ = $1;
3753           }
3754         ;
3755         
3756 qualified_alias_member
3757         : IDENTIFIER DOUBLE_COLON
3758           {
3759                 var lt = (Tokenizer.LocatedToken) $1;
3760                 if (RootContext.Version == LanguageVersion.ISO_1)
3761                         Report.FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
3762
3763                 $$ = lt;                
3764           }
3765         ;
3766
3767 sizeof_expression
3768         : SIZEOF open_parens_any type CLOSE_PARENS
3769           { 
3770                 $$ = new SizeOf ((Expression) $3, GetLocation ($1));
3771                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3772           }
3773         ;
3774
3775 checked_expression
3776         : CHECKED open_parens_any expression CLOSE_PARENS
3777           {
3778                 $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
3779                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3780           }
3781         ;
3782
3783 unchecked_expression
3784         : UNCHECKED open_parens_any expression CLOSE_PARENS
3785           {
3786                 $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
3787                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3788           }
3789         ;
3790
3791 pointer_member_access 
3792         : primary_expression OP_PTR IDENTIFIER
3793           {
3794                 var lt = (Tokenizer.LocatedToken) $3;
3795                 $$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, lt.Location);
3796           }
3797         ;
3798
3799 anonymous_method_expression
3800         : DELEGATE opt_anonymous_method_signature
3801           {
3802                 start_anonymous (false, (ParametersCompiled) $2, GetLocation ($1));
3803           }
3804           block
3805           {
3806                 $$ = end_anonymous ((ToplevelBlock) $4);
3807         }
3808         ;
3809
3810 opt_anonymous_method_signature
3811         : 
3812           {
3813                 $$ = ParametersCompiled.Undefined;
3814           } 
3815         | anonymous_method_signature
3816         ;
3817
3818 anonymous_method_signature
3819         : OPEN_PARENS
3820           {
3821                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
3822           }
3823           opt_formal_parameter_list CLOSE_PARENS
3824           {
3825                 valid_param_mod = 0;
3826                 $$ = $3;
3827           }
3828         ;
3829
3830 default_value_expression
3831         : DEFAULT open_parens_any type CLOSE_PARENS
3832           {
3833                 if (RootContext.Version < LanguageVersion.ISO_2)
3834                         Report.FeatureIsNotAvailable (GetLocation ($1), "default value expression");
3835
3836                 $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1));
3837                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
3838           }
3839         ;
3840
3841 unary_expression
3842         : primary_expression
3843         | BANG prefixed_unary_expression
3844           {
3845                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1));
3846           }
3847         | TILDE prefixed_unary_expression
3848           {
3849                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
3850           }
3851         | cast_expression
3852         ;
3853
3854 cast_expression
3855         : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
3856           {
3857                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3858                 lbag.AddLocation ($$, GetLocation ($3));
3859           }
3860         | OPEN_PARENS builtin_types CLOSE_PARENS prefixed_unary_expression
3861           {
3862                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3863                 lbag.AddLocation ($$, GetLocation ($3));
3864           }
3865         ;
3866
3867         //
3868         // The idea to split this out is from Rhys' grammar
3869         // to solve the problem with casts.
3870         //
3871 prefixed_unary_expression
3872         : unary_expression
3873         | PLUS prefixed_unary_expression
3874           { 
3875                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
3876           } 
3877         | MINUS prefixed_unary_expression 
3878           { 
3879                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
3880           }
3881         | OP_INC prefixed_unary_expression 
3882           {
3883                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1));
3884           }
3885         | OP_DEC prefixed_unary_expression 
3886           {
3887                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1));
3888           }
3889         | STAR prefixed_unary_expression
3890           {
3891                 $$ = new Indirection ((Expression) $2, GetLocation ($1));
3892           }
3893         | BITWISE_AND prefixed_unary_expression
3894           {
3895                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1));
3896           }
3897         ;
3898
3899 multiplicative_expression
3900         : prefixed_unary_expression
3901         | multiplicative_expression STAR prefixed_unary_expression
3902           {
3903                 $$ = new Binary (Binary.Operator.Multiply, 
3904                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3905           }
3906         | multiplicative_expression DIV prefixed_unary_expression
3907           {
3908                 $$ = new Binary (Binary.Operator.Division, 
3909                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3910           }
3911         | multiplicative_expression PERCENT prefixed_unary_expression 
3912           {
3913                 $$ = new Binary (Binary.Operator.Modulus, 
3914                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3915           }
3916         ;
3917
3918 additive_expression
3919         : multiplicative_expression
3920         | additive_expression PLUS multiplicative_expression 
3921           {
3922                 $$ = new Binary (Binary.Operator.Addition, 
3923                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3924           }
3925         | additive_expression MINUS multiplicative_expression
3926           {
3927                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
3928           }
3929         | parenthesized_expression MINUS multiplicative_expression
3930           {
3931                 // Shift/Reduce conflict
3932                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
3933           }
3934         | additive_expression AS type
3935           {
3936                 $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
3937           }
3938         | additive_expression IS type
3939           {
3940                 $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
3941           }       
3942         ;
3943
3944 shift_expression
3945         : additive_expression
3946         | shift_expression OP_SHIFT_LEFT additive_expression
3947           {
3948                 $$ = new Binary (Binary.Operator.LeftShift, 
3949                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3950           }
3951         | shift_expression OP_SHIFT_RIGHT additive_expression
3952           {
3953                 $$ = new Binary (Binary.Operator.RightShift, 
3954                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3955           }
3956         ; 
3957
3958 relational_expression
3959         : shift_expression
3960         | relational_expression OP_LT shift_expression
3961           {
3962                 $$ = new Binary (Binary.Operator.LessThan, 
3963                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3964           }
3965         | relational_expression OP_GT shift_expression
3966           {
3967                 $$ = new Binary (Binary.Operator.GreaterThan, 
3968                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3969           }
3970         | relational_expression OP_LE shift_expression
3971           {
3972                 $$ = new Binary (Binary.Operator.LessThanOrEqual, 
3973                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3974           }
3975         | relational_expression OP_GE shift_expression
3976           {
3977                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
3978                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3979           }
3980         ;
3981
3982 equality_expression
3983         : relational_expression
3984         | equality_expression OP_EQ relational_expression
3985           {
3986                 $$ = new Binary (Binary.Operator.Equality, 
3987                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3988           }
3989         | equality_expression OP_NE relational_expression
3990           {
3991                 $$ = new Binary (Binary.Operator.Inequality, 
3992                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3993           }
3994         ; 
3995
3996 and_expression
3997         : equality_expression
3998         | and_expression BITWISE_AND equality_expression
3999           {
4000                 $$ = new Binary (Binary.Operator.BitwiseAnd, 
4001                                  (Expression) $1, (Expression) $3, GetLocation ($2));
4002           }
4003         ;
4004
4005 exclusive_or_expression
4006         : and_expression
4007         | exclusive_or_expression CARRET and_expression
4008           {
4009                 $$ = new Binary (Binary.Operator.ExclusiveOr, 
4010                                  (Expression) $1, (Expression) $3, GetLocation ($2));
4011           }
4012         ;
4013
4014 inclusive_or_expression
4015         : exclusive_or_expression
4016         | inclusive_or_expression BITWISE_OR exclusive_or_expression
4017           {
4018                 $$ = new Binary (Binary.Operator.BitwiseOr, 
4019                                  (Expression) $1, (Expression) $3, GetLocation ($2));
4020           }
4021         ;
4022
4023 conditional_and_expression
4024         : inclusive_or_expression
4025         | conditional_and_expression OP_AND inclusive_or_expression
4026           {
4027                 $$ = new Binary (Binary.Operator.LogicalAnd, 
4028                                  (Expression) $1, (Expression) $3, GetLocation ($2));
4029           }
4030         ;
4031
4032 conditional_or_expression
4033         : conditional_and_expression
4034         | conditional_or_expression OP_OR conditional_and_expression
4035           {
4036                 $$ = new Binary (Binary.Operator.LogicalOr, 
4037                                  (Expression) $1, (Expression) $3, GetLocation ($2));
4038           }
4039         ;
4040         
4041 null_coalescing_expression
4042         : conditional_or_expression
4043         | conditional_or_expression OP_COALESCING null_coalescing_expression
4044           {
4045                 if (RootContext.Version < LanguageVersion.ISO_2)
4046                         Report.FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
4047                         
4048                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, GetLocation ($2));
4049           }
4050         ;
4051
4052 conditional_expression
4053         : null_coalescing_expression
4054         | null_coalescing_expression INTERR expression COLON expression 
4055           {
4056                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
4057                 lbag.AddLocation ($$, GetLocation ($4));
4058           }
4059         ;
4060
4061 assignment_expression
4062         : prefixed_unary_expression ASSIGN expression
4063           {
4064                 $$ = new SimpleAssign ((Expression) $1, (Expression) $3, GetLocation ($2));
4065           }
4066         | prefixed_unary_expression OP_MULT_ASSIGN expression
4067           {
4068                 $$ = new CompoundAssign (
4069                         Binary.Operator.Multiply, (Expression) $1, (Expression) $3, GetLocation ($2));
4070           }
4071         | prefixed_unary_expression OP_DIV_ASSIGN expression
4072           {
4073                 $$ = new CompoundAssign (
4074                         Binary.Operator.Division, (Expression) $1, (Expression) $3, GetLocation ($2));
4075           }
4076         | prefixed_unary_expression OP_MOD_ASSIGN expression
4077           {
4078                 $$ = new CompoundAssign (
4079                         Binary.Operator.Modulus, (Expression) $1, (Expression) $3, GetLocation ($2));
4080           }
4081         | prefixed_unary_expression OP_ADD_ASSIGN expression
4082           {
4083                 $$ = new CompoundAssign (
4084                         Binary.Operator.Addition, (Expression) $1, (Expression) $3, GetLocation ($2));
4085           }
4086         | prefixed_unary_expression OP_SUB_ASSIGN expression
4087           {
4088                 $$ = new CompoundAssign (
4089                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
4090           }
4091         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
4092           {
4093                 $$ = new CompoundAssign (
4094                         Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, GetLocation ($2));
4095           }
4096         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
4097           {
4098                 $$ = new CompoundAssign (
4099                         Binary.Operator.RightShift, (Expression) $1, (Expression) $3, GetLocation ($2));
4100           }
4101         | prefixed_unary_expression OP_AND_ASSIGN expression
4102           {
4103                 $$ = new CompoundAssign (
4104                         Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, GetLocation ($2));
4105           }
4106         | prefixed_unary_expression OP_OR_ASSIGN expression
4107           {
4108                 $$ = new CompoundAssign (
4109                         Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, GetLocation ($2));
4110           }
4111         | prefixed_unary_expression OP_XOR_ASSIGN expression
4112           {
4113                 $$ = new CompoundAssign (
4114                         Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, GetLocation ($2));
4115           }
4116         ;
4117
4118 lambda_parameter_list
4119         : lambda_parameter
4120           {
4121                 var pars = new List<Parameter> (4);
4122                 pars.Add ((Parameter) $1);
4123
4124                 $$ = pars;
4125           }
4126         | lambda_parameter_list COMMA lambda_parameter
4127           {
4128                 var pars = (List<Parameter>) $1;
4129                 Parameter p = (Parameter)$3;
4130                 if (pars[0].GetType () != p.GetType ()) {
4131                         Report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
4132                 }
4133                 
4134                 pars.Add (p);
4135                 $$ = pars;
4136           }
4137         ;
4138
4139 lambda_parameter
4140         : parameter_modifier parameter_type IDENTIFIER
4141           {
4142                 var lt = (Tokenizer.LocatedToken) $3;
4143
4144                 $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
4145           }
4146         | parameter_type IDENTIFIER
4147           {
4148                 var lt = (Tokenizer.LocatedToken) $2;
4149
4150                 $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
4151           }
4152         | IDENTIFIER
4153           {
4154                 var lt = (Tokenizer.LocatedToken) $1;
4155                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
4156           }
4157         ;
4158
4159 opt_lambda_parameter_list
4160         : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
4161         | lambda_parameter_list         { 
4162                 var pars_list = (List<Parameter>) $1;
4163                 $$ = new ParametersCompiled (compiler, pars_list.ToArray ());
4164           }
4165         ;
4166
4167 lambda_expression_body
4168         : {
4169                 start_block (lexer.Location);
4170           }
4171           expression 
4172           {
4173                 Block b = end_block (lexer.Location);
4174                 b.AddStatement (new ContextualReturn ((Expression) $2));
4175                 $$ = b;
4176           } 
4177         | block { 
4178                 $$ = $1; 
4179           } 
4180         ;
4181
4182 lambda_expression
4183         : IDENTIFIER ARROW 
4184           {
4185                 var lt = (Tokenizer.LocatedToken) $1;
4186                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4187                 start_anonymous (true, new ParametersCompiled (compiler, p), GetLocation ($1));
4188           }
4189           lambda_expression_body
4190           {
4191                 $$ = end_anonymous ((ToplevelBlock) $4);
4192                 lbag.AddLocation ($$, GetLocation ($2));
4193           }
4194         | OPEN_PARENS_LAMBDA
4195           {
4196                 if (RootContext.Version <= LanguageVersion.ISO_2)
4197                         Report.FeatureIsNotAvailable (GetLocation ($1), "lambda expressions");
4198           
4199                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
4200           }
4201           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4202           {
4203                 valid_param_mod = 0;
4204                 start_anonymous (true, (ParametersCompiled) $3, GetLocation ($1));
4205           }
4206           lambda_expression_body 
4207           {
4208                 $$ = end_anonymous ((ToplevelBlock) $7);
4209                 lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4));
4210           }
4211         ;
4212
4213 expression
4214         : assignment_expression 
4215         | non_assignment_expression 
4216         ;
4217         
4218 non_assignment_expression
4219         : conditional_expression
4220         | lambda_expression
4221         | query_expression 
4222         ;
4223
4224 constant_expression
4225         : expression
4226         ;
4227
4228 boolean_expression
4229         : expression
4230           {
4231                 $$ = new BooleanExpression ((Expression) $1);
4232           }
4233         ;
4234
4235 //
4236 // 10 classes
4237 //
4238 class_declaration
4239         : opt_attributes
4240           opt_modifiers
4241           opt_partial
4242           CLASS
4243           {
4244                 lexer.ConstraintsParsing = true;
4245           }
4246           type_declaration_name
4247           {
4248                 MemberName name = MakeName ((MemberName) $6);
4249                 push_current_class (new Class (current_namespace, current_class, name, (Modifiers) $2, (Attributes) $1), $3);
4250           }
4251           opt_class_base
4252           opt_type_parameter_constraints_clauses
4253           {
4254                 lexer.ConstraintsParsing = false;
4255
4256                 current_class.SetParameterInfo ((List<Constraints>) $9);
4257                 lbag.AddMember (current_class, mod_locations, GetLocation ($4));
4258
4259                 if (RootContext.Documentation != null) {
4260                         current_container.DocComment = Lexer.consume_doc_comment ();
4261                         Lexer.doc_state = XmlCommentState.Allowed;
4262                 }
4263           }
4264           OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
4265           {
4266                 --lexer.parsing_declaration;
4267                 if (RootContext.Documentation != null)
4268                         Lexer.doc_state = XmlCommentState.Allowed;
4269           }
4270           opt_semicolon 
4271           {
4272                 lbag.AppendToMember (current_class, GetLocation ($11), GetLocation ($13), GetLocation ($15));
4273                 $$ = pop_current_class ();
4274           }
4275         ;       
4276
4277 opt_partial
4278         : /* empty */
4279           { $$ = null; }
4280         | PARTIAL
4281           { $$ = $1; } // location
4282         ;
4283
4284 opt_modifiers
4285         : /* empty */
4286           {
4287             mod_locations = null;
4288                 $$ = ModifierNone;
4289           }
4290         | modifiers
4291         ;
4292
4293 modifiers
4294         : modifier
4295         | modifiers modifier
4296           { 
4297                 var m1 = (Modifiers) $1;
4298                 var m2 = (Modifiers) $2;
4299
4300                 if ((m1 & m2) != 0) {
4301                         Report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length,
4302                                 "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2));
4303                 } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 &&
4304                         ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) {
4305                         Report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length,
4306                                 "More than one protection modifier specified");
4307                 }
4308                 
4309                 $$ = m1 | m2;
4310           }
4311         ;
4312
4313 modifier
4314         : NEW
4315           {
4316                 $$ = Modifiers.NEW;
4317                 StoreModifierLocation ($$, GetLocation ($1));
4318                 
4319                 if (current_container == RootContext.ToplevelTypes)
4320                         Report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements");
4321           }
4322         | PUBLIC
4323           {
4324                 $$ = Modifiers.PUBLIC;
4325                 StoreModifierLocation ($$, GetLocation ($1));
4326           }
4327         | PROTECTED
4328           {
4329                 $$ = Modifiers.PROTECTED;
4330                 StoreModifierLocation ($$, GetLocation ($1));
4331           }
4332         | INTERNAL
4333           {
4334                 $$ = Modifiers.INTERNAL;
4335                 StoreModifierLocation ($$, GetLocation ($1));
4336           }
4337         | PRIVATE
4338           {
4339                 $$ = Modifiers.PRIVATE;
4340                 StoreModifierLocation ($$, GetLocation ($1));
4341           }
4342         | ABSTRACT
4343           {
4344                 $$ = Modifiers.ABSTRACT;
4345                 StoreModifierLocation ($$, GetLocation ($1));
4346           }
4347         | SEALED
4348           {
4349                 $$ = Modifiers.SEALED;
4350                 StoreModifierLocation ($$, GetLocation ($1));
4351           }
4352         | STATIC
4353           {
4354                 $$ = Modifiers.STATIC;
4355                 StoreModifierLocation ($$, GetLocation ($1));
4356           }
4357         | READONLY
4358           {
4359                 $$ = Modifiers.READONLY;
4360                 StoreModifierLocation ($$, GetLocation ($1));
4361           }
4362         | VIRTUAL
4363           {
4364                 $$ = Modifiers.VIRTUAL;
4365                 StoreModifierLocation ($$, GetLocation ($1));
4366           }
4367         | OVERRIDE
4368           {
4369                 $$ = Modifiers.OVERRIDE;
4370                 StoreModifierLocation ($$, GetLocation ($1));
4371           }
4372         | EXTERN
4373           {
4374                 $$ = Modifiers.EXTERN;
4375                 StoreModifierLocation ($$, GetLocation ($1));
4376           }
4377         | VOLATILE
4378           {
4379                 $$ = Modifiers.VOLATILE;
4380                 StoreModifierLocation ($$, GetLocation ($1));
4381           }
4382         | UNSAFE
4383           {
4384                 $$ = Modifiers.UNSAFE;
4385                 StoreModifierLocation ($$, GetLocation ($1));
4386                 if (!RootContext.Unsafe)
4387                         Error_UnsafeCodeNotAllowed (GetLocation ($1));
4388           }
4389         ;
4390
4391 opt_class_base
4392         : /* empty */
4393         | COLON type_list
4394          {
4395                 current_container.AddBasesForPart (current_class, (List<FullNamedExpression>) $2);
4396          }
4397         ;
4398
4399 opt_type_parameter_constraints_clauses
4400         : /* empty */           { $$ = null; }
4401         | type_parameter_constraints_clauses 
4402           {
4403                 $$ = $1;
4404           }
4405         ;
4406
4407 type_parameter_constraints_clauses
4408         : type_parameter_constraints_clause
4409           {
4410                 var constraints = new List<Constraints> (1);
4411                 constraints.Add ((Constraints) $1);
4412                 $$ = constraints;
4413           }
4414         | type_parameter_constraints_clauses type_parameter_constraints_clause
4415           {
4416                 var constraints = (List<Constraints>) $1;
4417                 Constraints new_constraint = (Constraints)$2;
4418
4419                 foreach (Constraints c in constraints) {
4420                         if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) {
4421                                 Report.Error (409, new_constraint.Location,
4422                                         "A constraint clause has already been specified for type parameter `{0}'",
4423                                         new_constraint.TypeParameter.Value);
4424                         }
4425                 }
4426
4427                 constraints.Add (new_constraint);
4428                 $$ = constraints;
4429           }
4430         ; 
4431
4432 type_parameter_constraints_clause
4433         : WHERE IDENTIFIER COLON type_parameter_constraints
4434           {
4435                 var lt = (Tokenizer.LocatedToken) $2;
4436                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List<FullNamedExpression>) $4, GetLocation ($1));
4437           }
4438         ; 
4439
4440 type_parameter_constraints
4441         : type_parameter_constraint
4442           {
4443                 var constraints = new List<FullNamedExpression> (1);
4444                 constraints.Add ((FullNamedExpression) $1);
4445                 $$ = constraints;
4446           }
4447         | type_parameter_constraints COMMA type_parameter_constraint
4448           {
4449                 var constraints = (List<FullNamedExpression>) $1;
4450                 var prev = constraints [constraints.Count - 1] as SpecialContraintExpr;
4451                 if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) {                   
4452                         Report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified");
4453                 }
4454                 
4455                 prev = $3 as SpecialContraintExpr;
4456                 if (prev != null) {
4457                         if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) {
4458                                 Report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified");                 
4459                         } else {
4460                                 prev = constraints [0] as SpecialContraintExpr;
4461                                 if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) {                        
4462                                         Report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint");
4463                                 }
4464                         }
4465                 }
4466
4467                 constraints.Add ((FullNamedExpression) $3);
4468                 $$ = constraints;
4469           }
4470         ;
4471
4472 type_parameter_constraint
4473         : type
4474           {
4475                 if ($1 is ComposedCast)
4476                         Report.Error (706, GetLocation ($1), "Invalid constraint type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
4477           
4478                 $$ = $1;
4479           }
4480         | NEW OPEN_PARENS CLOSE_PARENS
4481           {
4482                 $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1));
4483                 lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
4484           }
4485         | CLASS
4486           {
4487                 $$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1));
4488           }
4489         | STRUCT
4490           {
4491                 $$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1));
4492           }
4493         ;
4494
4495 opt_type_parameter_variance
4496         : /* empty */
4497           {
4498                 $$ = Variance.None;
4499           }
4500         | type_parameter_variance
4501           {
4502                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
4503                         Report.FeatureIsNotSupported (lexer.Location, "generic type variance");
4504                 else if (RootContext.Version <= LanguageVersion.V_3)
4505                         Report.FeatureIsNotAvailable (lexer.Location, "generic type variance");
4506
4507                 $$ = $1;
4508           }
4509         ;
4510
4511 type_parameter_variance
4512         : OUT
4513           {
4514                 $$ = Variance.Covariant;
4515           }
4516         | IN
4517           {
4518                 $$ = Variance.Contravariant;
4519           }
4520         ;
4521
4522 //
4523 // Statements (8.2)
4524 //
4525
4526 //
4527 // A block is "contained" on the following places:
4528 //      method_body
4529 //      property_declaration as part of the accessor body (get/set)
4530 //      operator_declaration
4531 //      constructor_declaration
4532 //      destructor_declaration
4533 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
4534 //      
4535 block
4536         : OPEN_BRACE  
4537           {
4538                 ++lexer.parsing_block;
4539                 start_block (GetLocation ($1));
4540           } 
4541           opt_statement_list block_end
4542           {
4543                 $$ = $4;
4544           }
4545         ;
4546
4547 block_end 
4548         : CLOSE_BRACE 
4549           {
4550                 --lexer.parsing_block;
4551                 $$ = end_block (GetLocation ($1));
4552           }
4553         | COMPLETE_COMPLETION
4554           {
4555                 --lexer.parsing_block;
4556                 $$ = end_block (lexer.Location);
4557           }
4558         ;
4559
4560
4561 block_prepared
4562         : OPEN_BRACE
4563           {
4564                 ++lexer.parsing_block;
4565                 current_block.StartLocation = GetLocation ($1);
4566           }
4567           opt_statement_list CLOSE_BRACE 
4568           {
4569                 --lexer.parsing_block;
4570                 $$ = end_block (GetLocation ($4));
4571           }
4572         ;
4573
4574 opt_statement_list
4575         : /* empty */
4576         | statement_list 
4577         ;
4578
4579 statement_list
4580         : statement
4581         | statement_list statement
4582         ;
4583
4584 statement
4585         : declaration_statement
4586           {
4587                 if ($1 != null && (Block) $1 != current_block){
4588                         current_block.AddStatement ((Statement) $1);
4589                         current_block = (Block) $1;
4590                 }
4591           }
4592         | valid_declaration_statement
4593           {
4594                 current_block.AddStatement ((Statement) $1);
4595           }
4596         | labeled_statement
4597         ;
4598
4599 //
4600 // The interactive_statement and its derivatives are only 
4601 // used to provide a special version of `expression_statement'
4602 // that has a side effect of assigning the expression to
4603 // $retval
4604 //
4605 interactive_statement_list
4606         : interactive_statement
4607         | interactive_statement_list interactive_statement
4608         ;
4609
4610 interactive_statement
4611         : declaration_statement
4612           {
4613                 if ($1 != null && (Block) $1 != current_block){
4614                         current_block.AddStatement ((Statement) $1);
4615                         current_block = (Block) $1;
4616                 }
4617           }
4618         | interactive_valid_declaration_statement
4619           {
4620                 current_block.AddStatement ((Statement) $1);
4621           }
4622         | labeled_statement
4623         ;
4624
4625 valid_declaration_statement
4626         : block
4627         | empty_statement
4628         | expression_statement
4629         | selection_statement
4630         | iteration_statement
4631         | jump_statement                  
4632         | try_statement
4633         | checked_statement
4634         | unchecked_statement
4635         | lock_statement
4636         | using_statement
4637         | unsafe_statement
4638         | fixed_statement
4639         ;
4640
4641 interactive_valid_declaration_statement
4642         : block
4643         | empty_statement
4644         | interactive_expression_statement
4645         | selection_statement
4646         | iteration_statement
4647         | jump_statement                  
4648         | try_statement
4649         | checked_statement
4650         | unchecked_statement
4651         | lock_statement
4652         | using_statement
4653         | unsafe_statement
4654         | fixed_statement
4655         ;
4656
4657 embedded_statement
4658         : valid_declaration_statement
4659         | declaration_statement
4660           {
4661                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4662                   $$ = null;
4663           }
4664         | labeled_statement
4665           {
4666                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4667                   $$ = null;
4668           }
4669         ;
4670
4671 empty_statement
4672         : SEMICOLON
4673           {
4674                 $$ = new EmptyStatement (GetLocation ($1));
4675           }
4676         ;
4677
4678 labeled_statement
4679         : IDENTIFIER COLON 
4680           {
4681                 var lt = (Tokenizer.LocatedToken) $1;
4682                 LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location);
4683
4684                 if (current_block.AddLabel (labeled))
4685                         current_block.AddStatement (labeled);
4686           }
4687           statement
4688         ;
4689
4690 declaration_statement
4691         : local_variable_declaration SEMICOLON
4692           {
4693                 if ($1 != null){
4694                         var de = (Tuple<FullNamedExpression, List<object>>) $1;
4695                         $$ = declare_local_variables (de.Item1, de.Item2, de.Item1.Location);
4696                 }
4697           }
4698
4699         | local_constant_declaration SEMICOLON
4700           {
4701                 if ($1 != null){
4702                         var de = (Tuple<FullNamedExpression, List<object>>) $1;
4703
4704                         $$ = declare_local_constants (de.Item1, de.Item2);
4705                 }
4706           }
4707         ;
4708
4709 /* 
4710  * The following is from Rhys' grammar:
4711  * > Types in local variable declarations must be recognized as 
4712  * > expressions to prevent reduce/reduce errors in the grammar.
4713  * > The expressions are converted into types during semantic analysis.
4714  */
4715 variable_type
4716         : primary_expression_no_array_creation opt_rank_specifier_or_nullable
4717           { 
4718                 // Ok, the above "primary_expression" is there to get rid of
4719                 // both reduce/reduce and shift/reduces in the grammar, it should
4720                 // really just be "type_name".  If you use type_name, a reduce/reduce
4721                 // creeps up.  If you use namespace_or_type_name (which is all we need
4722                 // really) two shift/reduces appear.
4723                 // 
4724
4725                 // So the super-trick is that primary_expression
4726                 // can only be either a SimpleName or a MemberAccess. 
4727                 // The MemberAccess case arises when you have a fully qualified type-name like :
4728                 // Foo.Bar.Blah i;
4729                 // SimpleName is when you have
4730                 // Blah i;
4731                 
4732                 Expression expr = (Expression) $1;
4733                 if ($2 == null) {
4734                         SimpleName sn = expr as SimpleName;
4735                         if (sn != null && sn.Name == "var")
4736                                 $$ = new VarExpr (sn.Location);
4737                         else
4738                                 $$ = $1;
4739                 } else if (expr is ATypeNameExpression) {
4740                         $$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2);
4741                 } else {
4742                         Error_ExpectingTypeName (expr);
4743                         $$ = null;
4744                 }
4745           }
4746         | builtin_types opt_rank_specifier_or_nullable
4747           {
4748                 if ($2 == null)
4749                         $$ = $1;
4750                 else
4751                         $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
4752           }
4753         | VOID opt_rank_specifier
4754           {
4755                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report);
4756                 $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1));
4757           }
4758         ;
4759
4760 local_variable_pointer_type
4761         : primary_expression_no_array_creation STAR
4762           {
4763                 ATypeNameExpression expr = $1 as ATypeNameExpression;
4764
4765                 if (expr != null) {
4766                         $$ = new ComposedCast (expr, ComposedTypeSpecifier.CreatePointer (GetLocation ($2)));
4767                 } else {
4768                         Error_ExpectingTypeName ((Expression)$1);
4769                         $$ = expr;
4770                 }
4771           }
4772         | builtin_types STAR
4773           {
4774                 $$ = new ComposedCast ((FullNamedExpression) $1, ComposedTypeSpecifier.CreatePointer (GetLocation ($2)));
4775           }
4776         | VOID STAR
4777           {
4778                 $$ = new ComposedCast (new TypeExpression (TypeManager.void_type, GetLocation ($1)), ComposedTypeSpecifier.CreatePointer (GetLocation ($2)));
4779           }
4780         | local_variable_pointer_type STAR
4781           {
4782                 $$ = new ComposedCast ((FullNamedExpression) $1, ComposedTypeSpecifier.CreatePointer (GetLocation ($2)));
4783           }
4784         ;
4785
4786 local_variable_type
4787         : variable_type
4788         | local_variable_pointer_type opt_rank_specifier
4789           {
4790                 if ($1 != null){
4791                         if ($2 == null)
4792                                 $$ = $1;
4793                         else
4794                                 $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
4795                 } else {
4796                         $$ = null;
4797                 }
4798           }
4799         ;
4800
4801 local_variable_declaration
4802         : local_variable_type local_variable_declarators
4803           {
4804                 if ($1 != null) {
4805                         VarExpr ve = $1 as VarExpr;
4806                         if (ve != null) {
4807                                 if (!((VariableDeclaration) ((List<object>)$2) [0]).HasInitializer)
4808                                         ve.VariableInitializersCount = 0;
4809                                 else
4810                                         ve.VariableInitializersCount = ((List<object>)$2).Count;
4811                         }
4812                                 
4813                         $$ = new Tuple<FullNamedExpression, List<object>> ((FullNamedExpression) $1, (List<object>) $2);
4814                 } else
4815                         $$ = null;
4816           }
4817         ;
4818
4819 local_constant_declaration
4820         : CONST variable_type local_constant_declarators
4821           {
4822                 if ($2 != null)
4823                         $$ = new Tuple<FullNamedExpression, List<object>> ((FullNamedExpression) $2, (List<object>) $3);
4824                 else
4825                         $$ = null;
4826           }
4827         ;
4828         
4829 local_constant_declarators
4830         : local_constant_declarator 
4831           {
4832                 variables_bucket.Clear ();
4833                 if ($1 != null)
4834                         variables_bucket.Add ($1);
4835                 $$ = variables_bucket;
4836           }
4837         | local_constant_declarators COMMA local_constant_declarator
4838           {
4839                 if ($3 != null) {
4840                         var constants = (List<object>) $1;
4841                         constants.Add ($3);
4842                 }
4843           }
4844         ;
4845
4846 local_constant_declarator
4847         : IDENTIFIER ASSIGN constant_initializer_expr
4848           {
4849                 $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, (Expression) $3);
4850           }
4851         | IDENTIFIER error
4852           {
4853                 Report.Error (145, GetLocation ($1), "A const field requires a value to be provided");
4854                 $$ = null;
4855           }
4856         ;
4857
4858 expression_statement
4859         : statement_expression SEMICOLON
4860           {
4861                 $$ = $1;
4862                 lbag.AddStatement ($$, GetLocation ($2));
4863           }
4864         | statement_expression COMPLETE_COMPLETION { $$ = $1; }
4865         ;
4866
4867 interactive_expression_statement
4868         : interactive_statement_expression SEMICOLON { $$ = $1; }
4869         | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; }
4870         ;
4871
4872         //
4873         // We have to do the wrapping here and not in the case above,
4874         // because statement_expression is used for example in for_statement
4875         //
4876 statement_expression
4877         : expression
4878           {
4879                 ExpressionStatement s = $1 as ExpressionStatement;
4880                 if (s == null) {
4881                         Expression.Error_InvalidExpressionStatement (Report, GetLocation ($1));
4882                         s = EmptyExpressionStatement.Instance;
4883                 }
4884
4885                 $$ = new StatementExpression (s);
4886           }
4887         | error
4888           {
4889                 Error_SyntaxError (yyToken);
4890                 $$ = null;
4891           }
4892         ;
4893
4894 interactive_statement_expression
4895         : expression
4896           {
4897                 Expression expr = (Expression) $1;
4898                 ExpressionStatement s;
4899
4900                 s = new OptionalAssign (new SimpleName ("$retval", lexer.Location), expr, lexer.Location);
4901                 $$ = new StatementExpression (s);
4902           }
4903         | error
4904           {
4905                 Error_SyntaxError (yyToken);
4906                 $$ = new EmptyStatement (GetLocation ($1));
4907           }
4908         ;
4909         
4910 selection_statement
4911         : if_statement
4912         | switch_statement
4913         ; 
4914
4915 if_statement
4916         : IF open_parens_any boolean_expression CLOSE_PARENS 
4917           embedded_statement
4918           { 
4919                 if ($5 is EmptyStatement)
4920                         Report.Warning (642, 3, GetLocation ($5), "Possible mistaken empty statement");
4921                 
4922                 $$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
4923                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
4924           }
4925         | IF open_parens_any boolean_expression CLOSE_PARENS
4926           embedded_statement ELSE embedded_statement
4927           {
4928                 $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1));
4929                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
4930                 
4931                 if ($5 is EmptyStatement)
4932                         Report.Warning (642, 3, GetLocation ($5), "Possible mistaken empty statement");
4933                 if ($7 is EmptyStatement)
4934                         Report.Warning (642, 3, GetLocation ($7), "Possible mistaken empty statement");
4935           }
4936         ;
4937
4938 switch_statement
4939         : SWITCH open_parens_any
4940           { 
4941                 if (switch_stack == null)
4942                         switch_stack = new Stack<Block> (2);
4943                 switch_stack.Push (current_block);
4944           }
4945           expression CLOSE_PARENS 
4946           OPEN_BRACE opt_switch_sections CLOSE_BRACE
4947           {
4948                 $$ = new Switch ((Expression) $4, (List<SwitchSection>) $7, GetLocation ($1));
4949                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($5), GetLocation ($6), GetLocation ($8));
4950                 
4951                 current_block = (Block) switch_stack.Pop ();
4952           }
4953         ;
4954
4955 opt_switch_sections
4956         : /* empty */           
4957       {
4958                 Report.Warning (1522, 1, lexer.Location, "Empty switch block"); 
4959                 $$ = new List<SwitchSection> ();
4960           }
4961         | switch_sections
4962         ;
4963
4964 switch_sections
4965         : switch_section 
4966           {
4967                 var sections = new List<SwitchSection> (4);
4968
4969                 sections.Add ((SwitchSection) $1);
4970                 $$ = sections;
4971           }
4972         | switch_sections switch_section
4973           {
4974                 var sections = (List<SwitchSection>) $1;
4975
4976                 sections.Add ((SwitchSection) $2);
4977                 $$ = sections;
4978           }
4979         ;
4980
4981 switch_section
4982         : switch_labels
4983           {
4984                 current_block = current_block.CreateSwitchBlock (lexer.Location);
4985           }
4986           statement_list 
4987           {
4988                 $$ = new SwitchSection ((List<SwitchLabel>) $1, current_block.Explicit);
4989           }
4990         ;
4991
4992 switch_labels
4993         : switch_label 
4994           {
4995                 var labels = new List<SwitchLabel> (4);
4996
4997                 labels.Add ((SwitchLabel) $1);
4998                 $$ = labels;
4999           }
5000         | switch_labels switch_label 
5001           {
5002                 var labels = (List<SwitchLabel>) ($1);
5003                 labels.Add ((SwitchLabel) $2);
5004
5005                 $$ = labels;
5006           }
5007         ;
5008
5009 switch_label
5010         : CASE constant_expression COLON
5011          {
5012                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
5013                 lbag.AddLocation ($$, GetLocation ($3));
5014          }
5015         | DEFAULT_COLON
5016           {
5017                 $$ = new SwitchLabel (null, GetLocation ($1));
5018           }
5019         ;
5020
5021 iteration_statement
5022         : while_statement
5023         | do_statement
5024         | for_statement
5025         | foreach_statement
5026         ;
5027
5028 while_statement
5029         : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement
5030           {
5031                 $$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
5032                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5033           }
5034         ;
5035
5036 do_statement
5037         : DO embedded_statement 
5038           WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
5039           {
5040                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1));
5041                 lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
5042           }
5043         ;
5044
5045 for_statement
5046         : FOR open_parens_any opt_for_initializer SEMICOLON
5047           {
5048                 Location l = lexer.Location;
5049                 start_block (l);  
5050                 Block assign_block = current_block;
5051
5052                 if ($3 is Tuple<FullNamedExpression, List<object>>){
5053                         var de = (Tuple<FullNamedExpression, List<object>>) $3;
5054                         
5055                         var type = de.Item1;
5056
5057                         foreach (VariableDeclaration decl in de.Item2){
5058
5059                                 LocalInfo vi;
5060
5061                                 vi = current_block.AddVariable (type, decl.identifier, decl.Location);
5062                                 if (vi == null)
5063                                         continue;
5064
5065                                 Expression expr = decl.GetInitializer (type);
5066                                         
5067                                 LocalVariableReference var;
5068                                 var = new LocalVariableReference (assign_block, decl.identifier, l);
5069
5070                                 if (expr != null) {
5071                                         Assign a = new SimpleAssign (var, expr, decl.Location);
5072                                         
5073                                         assign_block.AddStatement (new StatementExpression (a));
5074                                 }
5075                         }
5076                         
5077                         // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal.
5078                         // This can be referred to as $5 below.
5079                         $$ = null;
5080                 } else {
5081                         $$ = $3;
5082                 }
5083           } 
5084           opt_for_condition SEMICOLON
5085           opt_for_iterator CLOSE_PARENS 
5086           embedded_statement
5087           {
5088                 For f = new For ((Statement) $5, (BooleanExpression) $6, (Statement) $8, (Statement) $10, GetLocation ($1));
5089                 current_block.AddStatement (f);
5090                 
5091                 lbag.AddStatement (f, GetLocation ($2), GetLocation ($4), GetLocation ($7), GetLocation ($9));
5092
5093                 $$ = end_block (lexer.Location);
5094           }
5095         ;
5096
5097 opt_for_initializer
5098         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
5099         | for_initializer       
5100         ;
5101
5102 for_initializer
5103         : local_variable_declaration
5104         | statement_expression_list
5105         ;
5106
5107 opt_for_condition
5108         : /* empty */           { $$ = null; }
5109         | boolean_expression
5110         ;
5111
5112 opt_for_iterator
5113         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
5114         | for_iterator
5115         ;
5116
5117 for_iterator
5118         : statement_expression_list
5119         ;
5120
5121 statement_expression_list
5122         : statement_expression
5123         | statement_expression_list COMMA statement_expression
5124           {
5125                 var sl = $1 as StatementList;
5126                 if (sl == null)
5127                         sl = new StatementList ((Statement) $1, (Statement) $3);
5128                 else
5129                         sl.Add ((Statement) $3);
5130                         
5131                 lbag.AddStatement (sl, GetLocation ($2));
5132                 $$ = sl;
5133           }
5134         ;
5135
5136 foreach_statement
5137         : FOREACH open_parens_any type IN expression CLOSE_PARENS
5138           {
5139                 Report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement");
5140                 $$ = null;
5141           }
5142         | FOREACH open_parens_any type IDENTIFIER IN
5143           expression CLOSE_PARENS 
5144           {
5145                 start_block (lexer.Location);
5146                 Block foreach_block = current_block;
5147
5148                 var lt = (Tokenizer.LocatedToken) $4;
5149                 Location l = lt.Location;
5150                 LocalInfo vi = foreach_block.AddVariable ((Expression) $3, lt.Value, l);
5151                 if (vi != null) {
5152                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach);
5153
5154                         // Get a writable reference to this read-only variable.
5155                         //
5156                         // Note that the $$ here refers to the value of _this_ code block,
5157                         // not the value of the LHS non-terminal.  This can be referred to as $8 below.
5158                         $$ = new LocalVariableReference (foreach_block, lt.Value, l, vi, false);
5159                 } else {
5160                         $$ = null;
5161                 }
5162           } 
5163           embedded_statement 
5164           {
5165                 if ($8 != null) {
5166                         Foreach f = new Foreach ((Expression) $3, (LocalVariableReference) $8, (Expression) $6, (Statement) $9, GetLocation ($1));
5167                         lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
5168                         
5169                         current_block.AddStatement (f);
5170                 }
5171
5172                 $$ = end_block (lexer.Location);
5173           }
5174         ;
5175
5176 jump_statement
5177         : break_statement
5178         | continue_statement
5179         | goto_statement
5180         | return_statement
5181         | throw_statement
5182         | yield_statement
5183         ;
5184
5185 break_statement
5186         : BREAK SEMICOLON
5187           {
5188                 $$ = new Break (GetLocation ($1));
5189                 lbag.AddStatement ($$, GetLocation ($2));
5190           }
5191         ;
5192
5193 continue_statement
5194         : CONTINUE SEMICOLON
5195           {
5196                 $$ = new Continue (GetLocation ($1));
5197                 lbag.AddStatement ($$, GetLocation ($2));
5198           }
5199         ;
5200
5201 goto_statement
5202         : GOTO IDENTIFIER SEMICOLON 
5203           {
5204                 var lt = (Tokenizer.LocatedToken) $2;
5205                 $$ = new Goto (lt.Value, lt.Location);
5206                 lbag.AddStatement ($$, GetLocation ($1), GetLocation ($3));
5207           }
5208         | GOTO CASE constant_expression SEMICOLON
5209           {
5210                 $$ = new GotoCase ((Expression) $3, GetLocation ($1));
5211                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5212           }
5213         | GOTO DEFAULT SEMICOLON 
5214           {
5215                 $$ = new GotoDefault (GetLocation ($1));
5216                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5217           }
5218         ; 
5219
5220 return_statement
5221         : RETURN opt_expression SEMICOLON
5222           {
5223                 $$ = new Return ((Expression) $2, GetLocation ($1));
5224                 lbag.AddStatement ($$, GetLocation ($3));
5225           }
5226         ;
5227
5228 throw_statement
5229         : THROW opt_expression SEMICOLON
5230           {
5231                 $$ = new Throw ((Expression) $2, GetLocation ($1));
5232                 lbag.AddStatement ($$, GetLocation ($3));
5233           }
5234         ;
5235
5236 yield_statement 
5237         : IDENTIFIER RETURN opt_expression SEMICOLON
5238           {
5239                 var lt = (Tokenizer.LocatedToken) $1;
5240                 string s = lt.Value;
5241                 if (s != "yield"){
5242                         Report.Error (1003, lt.Location, "; expected");
5243                 } else if ($3 == null) {
5244                         Report.Error (1627, GetLocation ($4), "Expression expected after yield return");
5245                 } else if (RootContext.Version == LanguageVersion.ISO_1){
5246                         Report.FeatureIsNotAvailable (lt.Location, "iterators");
5247                 }
5248                 
5249                 current_block.Toplevel.IsIterator = true;
5250                 $$ = new Yield ((Expression) $3, lt.Location);
5251                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5252           }
5253         | IDENTIFIER BREAK SEMICOLON
5254           {
5255                 var lt = (Tokenizer.LocatedToken) $1;
5256                 string s = lt.Value;
5257                 if (s != "yield"){
5258                         Report.Error (1003, lt.Location, "; expected");
5259                 } else if (RootContext.Version == LanguageVersion.ISO_1){
5260                         Report.FeatureIsNotAvailable (lt.Location, "iterators");
5261                 }
5262                 
5263                 current_block.Toplevel.IsIterator = true;
5264                 $$ = new YieldBreak (lt.Location);
5265                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
5266           }
5267         ;
5268
5269 opt_expression
5270         : /* empty */
5271         | expression
5272         ;
5273
5274 try_statement
5275         : TRY block catch_clauses
5276           {
5277                 $$ = new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), false);
5278           }
5279         | TRY block FINALLY block
5280           {
5281                 $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1));
5282                 lbag.AddStatement ($$, GetLocation ($3));
5283           }
5284         | TRY block catch_clauses FINALLY block
5285           {
5286                 $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), true), (Block) $5, GetLocation ($1));
5287                 lbag.AddStatement ($$, GetLocation ($4));
5288           }
5289         | TRY block error 
5290           {
5291                 Report.Error (1524, GetLocation ($1), "Expected catch or finally");
5292                 $$ = null;
5293           }
5294         ;
5295
5296 catch_clauses
5297         : catch_clause 
5298           {
5299                 var l = new List<Catch> (2);
5300
5301                 l.Add ((Catch) $1);
5302                 $$ = l;
5303           }
5304         | catch_clauses catch_clause
5305           {
5306                 var l = (List<Catch>) $1;
5307                 
5308                 Catch c = (Catch) $2;
5309                 if (l [0].IsGeneral) {
5310                         Report.Error (1017, c.loc, "Try statement already has an empty catch block");
5311                 } else {
5312                         if (c.IsGeneral)
5313                                 l.Insert (0, c);
5314                         else
5315                                 l.Add (c);
5316                 }
5317                 
5318                 $$ = l;
5319           }
5320         ;
5321
5322 opt_identifier
5323         : /* empty */   { $$ = null; }
5324         | IDENTIFIER
5325         ;
5326
5327 catch_clause 
5328         : CATCH opt_catch_args 
5329           {
5330                 if ($2 != null) {
5331                         var cc = (Tuple<FullNamedExpression, Tokenizer.LocatedToken>) $2;
5332                         var lt = cc.Item2;
5333
5334                         if (lt != null){
5335                                 List<object> one = new List<object> (1);
5336
5337                                 one.Add (new VariableDeclaration (lt, null));
5338
5339                                 start_block (lexer.Location);
5340                                 current_block = declare_local_variables (cc.Item1, one, lt.Location);
5341                         }
5342                 }
5343           } block {
5344                 Expression type = null;
5345                 string id = null;
5346                 Block var_block = null;
5347
5348                 if ($2 != null){
5349                         var cc = (Tuple<FullNamedExpression, Tokenizer.LocatedToken>) $2;
5350                         type = cc.Item1;
5351                         var lt = cc.Item2;
5352
5353                         if (lt != null){
5354                                 id = lt.Value;
5355                                 var_block = end_block (lexer.Location);
5356                         }
5357                 }
5358
5359                 $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc);
5360                 lbag.AddLocation ($$, GetLocation ($1));
5361                 lbag.AppendTo ($$, lbag.GetLocations ($2));
5362           }
5363         ;
5364
5365 opt_catch_args
5366         : /* empty */ { $$ = null; }
5367         | catch_args
5368         ;         
5369
5370 catch_args 
5371         : open_parens_any type opt_identifier CLOSE_PARENS 
5372           {
5373                 $$ = new Tuple<FullNamedExpression, Tokenizer.LocatedToken> ((FullNamedExpression)$2, (Tokenizer.LocatedToken) $3);
5374                 lbag.AddLocation ($$, GetLocation ($1), GetLocation ($4));
5375           }
5376         | open_parens_any CLOSE_PARENS 
5377           {
5378                 Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected");
5379                 $$ = null;
5380           }
5381         ;
5382
5383 checked_statement
5384         : CHECKED block
5385           {
5386                 $$ = new Checked ((Block) $2, GetLocation ($1));
5387           }
5388         ;
5389
5390 unchecked_statement
5391         : UNCHECKED block
5392           {
5393                 $$ = new Unchecked ((Block) $2, GetLocation ($1));
5394           }
5395         ;
5396
5397 unsafe_statement
5398         : UNSAFE
5399           {
5400                 if (!RootContext.Unsafe)
5401                         Error_UnsafeCodeNotAllowed (GetLocation ($1));
5402           } block {
5403                 $$ = new Unsafe ((Block) $3, GetLocation ($1));
5404           }
5405         ;
5406
5407 fixed_statement
5408         : FIXED open_parens_any 
5409           type_and_void fixed_pointer_declarators 
5410           CLOSE_PARENS
5411           {
5412                 start_block (lexer.Location);
5413           }
5414           embedded_statement 
5415           {
5416                 Expression type = (Expression) $3;
5417                 var list = (List<KeyValuePair<Tokenizer.LocatedToken, Expression>>) $4;
5418                 Fixed f = new Fixed (type,
5419                         list.ConvertAll (i => {
5420                                 var v = new KeyValuePair<LocalInfo, Expression> (current_block.AddVariable (type, i.Key.Value, i.Key.Location), i.Value);
5421                                 if (v.Key != null) {
5422                                         v.Key.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
5423                                         v.Key.Pinned = true;
5424                                 }
5425                                 return v;
5426                         }), (Statement) $7, GetLocation ($1));
5427
5428                 lbag.AddStatement (f, GetLocation ($2), GetLocation ($5));
5429
5430                 current_block.AddStatement (f);
5431
5432                 $$ = end_block (lexer.Location);
5433           }
5434         ;
5435
5436 fixed_pointer_declarators
5437         : fixed_pointer_declarator      { 
5438                 var declarators = new List<KeyValuePair<Tokenizer.LocatedToken, Expression>> (2);
5439                 if ($1 != null)
5440                         declarators.Add ((KeyValuePair<Tokenizer.LocatedToken, Expression>)$1);
5441                 $$ = declarators;
5442           }
5443         | fixed_pointer_declarators COMMA fixed_pointer_declarator
5444           {
5445                 var declarators = (List<KeyValuePair<Tokenizer.LocatedToken, Expression>>) $1;
5446                 if ($3 != null)
5447                         declarators.Add ((KeyValuePair<Tokenizer.LocatedToken, Expression>)$3);
5448                 $$ = declarators;
5449           }
5450         ;
5451
5452 fixed_pointer_declarator
5453         : IDENTIFIER ASSIGN expression
5454           {
5455                 var lt = (Tokenizer.LocatedToken) $1;
5456                 $$ = new KeyValuePair<Tokenizer.LocatedToken, Expression> (lt, (Expression) $3);
5457           }
5458         | IDENTIFIER
5459           {
5460                 Report.Error (210, ((Tokenizer.LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration");
5461                 $$ = null;
5462           }
5463         ;
5464
5465 lock_statement
5466         : LOCK open_parens_any expression CLOSE_PARENS embedded_statement
5467           {
5468                 $$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1));
5469                 lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
5470           }
5471         ;
5472
5473 using_statement
5474         : USING open_parens_any local_variable_declaration CLOSE_PARENS
5475           {
5476                 start_block (lexer.Location);
5477                 Block assign_block = current_block;
5478
5479                 var de = (Tuple<FullNamedExpression, List<object>>) $3;
5480                 Location l = GetLocation ($1);
5481
5482                 var vars = new Stack<Tuple<LocalVariableReference, Expression>> ();
5483
5484                 lbag.AddStatement (assign_block, GetLocation ($1), GetLocation ($2), GetLocation ($4));
5485
5486                 foreach (VariableDeclaration decl in de.Item2) {
5487                         LocalInfo vi = current_block.AddVariable (de.Item1, decl.identifier, decl.Location);
5488                         if (vi == null)
5489                                 continue;
5490                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
5491
5492                         Expression expr = decl.GetInitializer (de.Item1);
5493                         if (expr == null) {
5494                                 Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
5495                                 continue;
5496                         }
5497                         LocalVariableReference var;
5498
5499                         // Get a writable reference to this read-only variable.
5500                         var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
5501
5502                         // This is so that it is not a warning on using variables
5503                         vi.Used = true;
5504
5505                         vars.Push (new Tuple<LocalVariableReference, Expression> (var, expr));
5506
5507                         // Assign a = new SimpleAssign (var, expr, decl.Location);
5508                         // assign_block.AddStatement (new StatementExpression (a));
5509                 }
5510
5511                 // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
5512                 // It can be referred to as $5 below.
5513                 $$ = vars;
5514           }
5515           embedded_statement
5516           {
5517                 Statement stmt = (Statement) $6;
5518                 var vars = (Stack<Tuple<LocalVariableReference, Expression>>) $5;
5519                 Location l = GetLocation ($1);
5520
5521                 while (vars.Count > 0) {
5522                           var de = vars.Pop ();
5523                           stmt = new Using (de.Item1, de.Item2, stmt, l);
5524                 }
5525                 current_block.AddStatement (stmt);
5526                 $$ = end_block (lexer.Location);
5527           }
5528         | USING open_parens_any expression CLOSE_PARENS
5529           {
5530                 start_block (lexer.Location);
5531           }
5532           embedded_statement
5533           {
5534                 UsingTemporary usingTemporary = new UsingTemporary ((Expression) $3, (Statement) $6, GetLocation ($1));
5535                 lbag.AddStatement (usingTemporary, GetLocation ($2), GetLocation ($4));
5536                 current_block.AddStatement (usingTemporary);
5537                 $$ = end_block (lexer.Location);
5538           }
5539         ; 
5540
5541
5542 // LINQ
5543
5544 query_expression
5545         : first_from_clause query_body 
5546           {
5547                 lexer.query_parsing = false;
5548                         
5549                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5550                         
5551                 from.Tail.Next = (Linq.AQueryClause)$2;
5552                 $$ = from;
5553                 
5554                 current_block.SetEndLocation (lexer.Location);
5555                 current_block = current_block.Parent;
5556           }
5557         | nested_from_clause query_body
5558           {
5559                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5560                         
5561                 from.Tail.Next = (Linq.AQueryClause)$2;
5562                 $$ = from;
5563                 
5564                 current_block.SetEndLocation (lexer.Location);
5565                 current_block = current_block.Parent;
5566           }     
5567
5568         // Bubble up COMPLETE_COMPLETION productions
5569         | first_from_clause COMPLETE_COMPLETION {
5570                 lexer.query_parsing = false;
5571                 $$ = $1;
5572
5573                 current_block.SetEndLocation (lexer.Location);
5574                 current_block = current_block.Parent;
5575           }
5576         | nested_from_clause COMPLETE_COMPLETION {
5577                 $$ = $1;
5578                 current_block.SetEndLocation (lexer.Location);
5579                 current_block = current_block.Parent;
5580           }
5581         ;
5582         
5583 first_from_clause
5584         : FROM_FIRST IDENTIFIER IN expression
5585           {
5586                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5587           
5588                 var lt = (Tokenizer.LocatedToken) $2;     
5589                 $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)));
5590           }
5591         | FROM_FIRST type IDENTIFIER IN expression
5592           {
5593                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5594           
5595                 var lt = (Tokenizer.LocatedToken) $3;
5596                 $$ = new Linq.QueryExpression (
5597                         new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) {
5598                                 IdentifierType = (FullNamedExpression)$2
5599                         }
5600                 );
5601           }
5602         ;
5603
5604 nested_from_clause
5605         : FROM IDENTIFIER IN expression
5606           {
5607                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5608           
5609                 var lt = (Tokenizer.LocatedToken) $2;     
5610                 $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)));
5611           }
5612         | FROM type IDENTIFIER IN expression
5613           {
5614                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5615           
5616                 var lt = (Tokenizer.LocatedToken) $3;
5617                 $$ = new Linq.QueryExpression (
5618                         new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) {
5619                                 IdentifierType = (FullNamedExpression)$2
5620                         }
5621                 );
5622           }
5623         ;
5624         
5625 from_clause
5626         : FROM IDENTIFIER IN
5627           {
5628                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5629           }
5630           expression
5631           {
5632                 var lt = (Tokenizer.LocatedToken) $2;
5633                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5634                 $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$5, GetLocation ($1));
5635                 
5636                 current_block.SetEndLocation (lexer.Location);
5637                 current_block = current_block.Parent;
5638                 
5639                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5640           }       
5641         | FROM type IDENTIFIER IN
5642           {
5643                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5644           }
5645           expression
5646           {
5647                 var lt = (Tokenizer.LocatedToken) $3;
5648                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5649
5650                 $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) {
5651                         IdentifierType = (FullNamedExpression)$2
5652                 };
5653                 
5654                 current_block.SetEndLocation (lexer.Location);
5655                 current_block = current_block.Parent;
5656                 
5657                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5658           }
5659         ;       
5660
5661 query_body
5662         : opt_query_body_clauses select_or_group_clause opt_query_continuation 
5663           {
5664                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5665                 
5666                 if ($3 != null)
5667                         head.Next = (Linq.AQueryClause)$3;
5668                                 
5669                 if ($1 != null) {
5670                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5671                         clause.Tail.Next = head;
5672                         head = clause;
5673                 }
5674                 
5675                 $$ = head;
5676           }
5677         | opt_query_body_clauses COMPLETE_COMPLETION
5678         ;
5679         
5680 select_or_group_clause
5681         : SELECT
5682           {
5683                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5684           }
5685           expression
5686           {
5687                 $$ = new Linq.Select ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
5688
5689                 current_block.SetEndLocation (lexer.Location);
5690                 current_block = current_block.Parent;
5691           }
5692         | GROUP
5693           {
5694                 if (linq_clause_blocks == null)
5695                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
5696                         
5697                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5698                 linq_clause_blocks.Push ((Linq.QueryBlock)current_block);
5699           }
5700           expression
5701           {
5702                 current_block.SetEndLocation (lexer.Location);
5703                 current_block = current_block.Parent;
5704           
5705                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5706           }
5707           BY expression
5708           {
5709                 $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1));
5710                 
5711                 current_block.SetEndLocation (lexer.Location);
5712                 current_block = current_block.Parent;
5713           }
5714         ;
5715         
5716 opt_query_body_clauses
5717         : /* empty */
5718         | query_body_clauses
5719         ;
5720         
5721 query_body_clauses
5722         : query_body_clause
5723         | query_body_clauses query_body_clause
5724           {
5725                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
5726                 $$ = $1;
5727           }
5728         ;
5729         
5730 query_body_clause
5731         : from_clause
5732         | let_clause 
5733         | where_clause
5734         | join_clause
5735         | orderby_clause
5736         ;
5737         
5738 let_clause
5739         : LET IDENTIFIER ASSIGN 
5740           {
5741                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5742           }
5743           expression
5744           {
5745                 var lt = (Tokenizer.LocatedToken) $2;
5746                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5747                 $$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1));
5748                 
5749                 current_block.SetEndLocation (lexer.Location);
5750                 current_block = current_block.Parent;
5751                 
5752                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
5753           }
5754         ;
5755
5756 where_clause
5757         : WHERE
5758           {
5759                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5760           }
5761           boolean_expression
5762           {
5763                 $$ = new Linq.Where ((Linq.QueryBlock)current_block, (BooleanExpression)$3, GetLocation ($1));
5764
5765                 current_block.SetEndLocation (lexer.Location);
5766                 current_block = current_block.Parent;
5767           }
5768         ;
5769         
5770 join_clause
5771         : JOIN IDENTIFIER IN
5772           {
5773                 if (linq_clause_blocks == null)
5774                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
5775                         
5776                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5777                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
5778           }
5779           expression ON
5780           {
5781                 current_block.SetEndLocation (lexer.Location);
5782                 current_block = current_block.Parent;
5783
5784                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5785                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
5786           }
5787           expression EQUALS
5788           {
5789                 current_block.AddStatement (new ContextualReturn ((Expression) $8));
5790                 current_block.SetEndLocation (lexer.Location);
5791                 current_block = current_block.Parent;
5792
5793                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5794           }
5795           expression opt_join_into
5796           {
5797                 var lt = (Tokenizer.LocatedToken) $2;
5798                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5799                 SimpleMemberName sn2 = null;
5800                 
5801                 var outer_selector = linq_clause_blocks.Pop ();
5802                 var block = linq_clause_blocks.Pop ();
5803
5804                 if ($12 == null) {
5805                         $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1));
5806                 } else {
5807                         var lt2 = (Tokenizer.LocatedToken) $12;
5808                         sn2 = new SimpleMemberName (lt2.Value, lt2.Location);
5809                         $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block,
5810                                 sn2, GetLocation ($1));
5811                 }
5812
5813                 current_block.AddStatement (new ContextualReturn ((Expression) $11));
5814                 current_block.SetEndLocation (lexer.Location);
5815                 current_block = current_block.Parent;
5816                         
5817                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn2 ?? sn);
5818           }
5819         | JOIN type IDENTIFIER IN
5820           {
5821                 if (linq_clause_blocks == null)
5822                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
5823                         
5824                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5825                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
5826           }
5827           expression ON
5828           {
5829                 current_block.SetEndLocation (lexer.Location);
5830                 current_block = current_block.Parent;
5831
5832                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5833                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
5834           }
5835           expression EQUALS
5836           {
5837                 current_block.AddStatement (new ContextualReturn ((Expression) $9));
5838                 current_block.SetEndLocation (lexer.Location);
5839                 current_block = current_block.Parent;
5840
5841                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5842           }
5843           expression opt_join_into
5844           {
5845                 var lt = (Tokenizer.LocatedToken) $3;
5846                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5847                 SimpleMemberName sn2 = null;
5848                 var outer_selector = linq_clause_blocks.Pop ();
5849                 var block = linq_clause_blocks.Pop ();
5850                 
5851                 if ($13 == null) {
5852                         $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) {
5853                                 IdentifierType = (FullNamedExpression)$2
5854                         };
5855                 } else {
5856                         var lt2 = (Tokenizer.LocatedToken) $13;
5857                         sn2 = new SimpleMemberName (lt2.Value, lt2.Location);
5858                         $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, sn2, GetLocation ($1)) {
5859                                 IdentifierType = (FullNamedExpression)$2
5860                         };                      
5861                 }
5862                 
5863                 current_block.AddStatement (new ContextualReturn ((Expression) $12));
5864                 current_block.SetEndLocation (lexer.Location);
5865                 current_block = current_block.Parent;
5866                         
5867                 ((Linq.QueryBlock)current_block).AddRangeVariable (sn2 ?? sn);
5868           }
5869         ;
5870         
5871 opt_join_into
5872         : /* empty */
5873         | INTO IDENTIFIER
5874           {
5875                 $$ = $2;
5876           }
5877         ;
5878         
5879 orderby_clause
5880         : ORDERBY
5881           {
5882                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5883           }
5884           orderings
5885           {
5886                 current_block.SetEndLocation (lexer.Location);
5887                 current_block = current_block.Parent;
5888           
5889                 $$ = $3;
5890           }
5891         ;
5892         
5893 orderings
5894         : order_by
5895         | order_by COMMA
5896           {
5897                 current_block.SetEndLocation (lexer.Location);
5898                 current_block = current_block.Parent;
5899           
5900                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5901           }
5902           orderings_then_by
5903           {
5904                 ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4;
5905                 $$ = $1;
5906           }
5907         ;
5908         
5909 orderings_then_by
5910         : then_by
5911         | orderings_then_by COMMA
5912          {
5913                 current_block.SetEndLocation (lexer.Location);
5914                 current_block = current_block.Parent;
5915           
5916                 current_block = new Linq.QueryBlock (compiler, (Linq.QueryBlock) current_block, lexer.Location);         
5917          }
5918          then_by
5919          {
5920                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$4;
5921                 $$ = $1;
5922          }
5923         ;       
5924         
5925 order_by
5926         : expression
5927           {
5928                 $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
5929           }
5930         | expression ASCENDING
5931           {
5932                 $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
5933           }
5934         | expression DESCENDING
5935           {
5936                 $$ = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)$1);      
5937           }
5938         ;
5939
5940 then_by
5941         : expression
5942           {
5943                 $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
5944           }
5945         | expression ASCENDING
5946           {
5947                 $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
5948           }
5949         | expression DESCENDING
5950           {
5951                 $$ = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)$1);       
5952           }     
5953         ;
5954
5955
5956 opt_query_continuation
5957         : /* empty */
5958         | INTO IDENTIFIER
5959           {
5960                 // query continuation block is not linked with query block but with block
5961                 // before. This means each query can use same range variable names for
5962                 // different identifiers.
5963
5964                 current_block.SetEndLocation (GetLocation ($1));
5965                 current_block = current_block.Parent;
5966         
5967                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5968                 
5969                 if (linq_clause_blocks == null)
5970                         linq_clause_blocks = new Stack<Linq.QueryBlock> ();
5971                         
5972                 linq_clause_blocks.Push ((Linq.QueryBlock) current_block);              
5973           }
5974           query_body
5975           {
5976                 var current_block = linq_clause_blocks.Pop ();    
5977                 var lt = (Tokenizer.LocatedToken) $2;
5978                 $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) {
5979                         next = (Linq.AQueryClause)$4
5980                 };
5981           }
5982         ;
5983         
5984 //
5985 // Support for using the compiler as an interactive parser
5986 //
5987 // The INTERACTIVE_PARSER token is first sent to parse our
5988 // productions;  If the result is a Statement, the parsing
5989 // is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
5990 // to setup the blocks in advance.
5991 //
5992 // This setup is here so that in the future we can add 
5993 // support for other constructs (type parsing, namespaces, etc)
5994 // that do not require a block to be setup in advance
5995 //
5996
5997 interactive_parsing
5998         : EVAL_STATEMENT_PARSER EOF 
5999         | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives 
6000         | EVAL_STATEMENT_PARSER { 
6001                 Evaluator.LoadAliases (current_namespace);
6002
6003                 push_current_class (new Class (current_namespace, current_class, new MemberName ("Class" + class_count++),
6004                         Modifiers.PUBLIC, null), null);
6005
6006                 var baseclass_list = new List<FullNamedExpression> ();
6007                 baseclass_list.Add (new TypeExpression (Evaluator.InteractiveBaseClass, lexer.Location));
6008                 current_container.AddBasesForPart (current_class, baseclass_list);
6009
6010                 // (ref object retval)
6011                 Parameter [] mpar = new Parameter [1];
6012                 mpar [0] = new Parameter (new TypeExpression (TypeManager.object_type, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null);
6013
6014                 ParametersCompiled pars = new ParametersCompiled (compiler, mpar);
6015                 current_local_parameters = pars;
6016                 Method method = new Method (
6017                         current_class,
6018                         null, // generic
6019                         new TypeExpression (TypeManager.void_type, Location.Null),
6020                         Modifiers.PUBLIC | Modifiers.STATIC,
6021                         new MemberName ("Host"),
6022                         pars,
6023                         null /* attributes */);
6024
6025                 oob_stack.Push (method);
6026                 ++lexer.parsing_block;
6027                 start_block (lexer.Location);
6028           }             
6029           interactive_statement_list opt_COMPLETE_COMPLETION
6030           {
6031                 --lexer.parsing_block;
6032                 Method method = (Method) oob_stack.Pop ();
6033
6034                 method.Block = (ToplevelBlock) end_block(lexer.Location);
6035                 current_container.AddMethod (method);
6036
6037                 --lexer.parsing_declaration;
6038                 InteractiveResult = pop_current_class ();
6039                 current_local_parameters = null;
6040           } 
6041         | EVAL_COMPILATION_UNIT_PARSER {
6042                 Evaluator.LoadAliases (current_namespace);
6043           }
6044           interactive_compilation_unit
6045         ;
6046
6047 interactive_compilation_unit
6048         : outer_declarations 
6049         | outer_declarations global_attributes 
6050         | global_attributes 
6051         | /* nothing */
6052         ;
6053
6054 opt_COMPLETE_COMPLETION
6055         : /* nothing */
6056         | COMPLETE_COMPLETION
6057         ;
6058
6059 close_brace_or_complete_completion
6060         : CLOSE_BRACE
6061         | COMPLETE_COMPLETION
6062         ;
6063 %%
6064
6065 // <summary>
6066 //   A class used to pass around variable declarations and constants
6067 // </summary>
6068 class VariableDeclaration {
6069         public string identifier;
6070         Expression initializer;
6071         public Location Location;
6072
6073         public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer)
6074         {
6075                 this.identifier = lt.Value;
6076                 this.initializer = initializer;
6077                 this.Location = lt.Location;
6078         }
6079
6080         public Expression GetInitializer (FullNamedExpression type)
6081         {
6082                 if (initializer is ArrayInitializer)
6083                         return new ArrayCreation (type, (ArrayInitializer)initializer);
6084
6085                 return initializer;
6086         }
6087
6088         public bool HasInitializer {
6089                 get { return initializer != null; }
6090         }
6091 }
6092
6093
6094 // <summary>
6095 //  A class used to hold info about an operator declarator
6096 // </summary>
6097 struct OperatorDeclaration {
6098         public readonly Operator.OpType optype;
6099         public readonly FullNamedExpression ret_type;
6100         public readonly Location location;
6101
6102         public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
6103         {
6104                 optype = op;
6105                 this.ret_type = ret_type;
6106                 this.location = location;
6107         }
6108 }
6109
6110 void Error_ExpectingTypeName (Expression expr)
6111 {
6112         if (expr is Invocation){
6113                 Report.Error (1002, expr.Location, "Expecting `;'");
6114         } else {
6115                 Expression.Error_InvalidExpressionStatement (Report, expr.Location);
6116         }
6117 }
6118
6119 void Error_ParameterModifierNotValid (string modifier, Location loc)
6120 {
6121         Report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
6122                                       modifier);
6123 }
6124
6125 void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
6126 {
6127         Report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
6128                 Parameter.GetModifierSignature (mod));
6129 }
6130
6131 void Error_TypeExpected (Location loc)
6132 {
6133         Report.Error (1031, loc, "Type expected");
6134 }
6135
6136 void Error_UnsafeCodeNotAllowed (Location loc)
6137 {
6138         Report.Error (227, loc, "Unsafe code requires the `unsafe' command line option to be specified");
6139 }
6140
6141 void Error_NamedArgumentExpected (NamedArgument a)
6142 {
6143         Report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
6144 }
6145
6146 void push_current_class (TypeContainer tc, object partial_token)
6147 {
6148         if (RootContext.EvalMode){
6149                 tc.ModFlags = (tc.ModFlags & ~(Modifiers.PRIVATE|Modifiers.INTERNAL)) | Modifiers.PUBLIC;
6150                 undo.AddTypeContainer (current_container, tc);
6151         }
6152
6153         if (partial_token != null)
6154                 current_container = current_container.AddPartial (tc);
6155         else
6156                 current_container = current_container.AddTypeContainer (tc);
6157
6158         ++lexer.parsing_declaration;
6159         current_class = tc;
6160 }
6161
6162 DeclSpace pop_current_class ()
6163 {
6164         DeclSpace retval = current_class;
6165
6166         current_class = current_class.Parent;
6167         current_container = current_class.PartialContainer;
6168
6169         return retval;
6170 }
6171
6172 // <summary>
6173 //   Given the @class_name name, it creates a fully qualified name
6174 //   based on the containing declaration space
6175 // </summary>
6176 MemberName
6177 MakeName (MemberName class_name)
6178 {
6179         Namespace ns = current_namespace.NS;
6180
6181         if (current_container == RootContext.ToplevelTypes) {
6182                 if (ns.Name.Length != 0)
6183                         return new MemberName (ns.MemberName, class_name);
6184                 else
6185                         return class_name;
6186         } else {
6187                 return new MemberName (current_container.MemberName, class_name);
6188         }
6189 }
6190
6191 [System.Diagnostics.Conditional ("FULL_AST")]
6192 void StoreModifierLocation (object token, Location loc)
6193 {
6194         if (lbag == null)
6195                 return;
6196
6197         if (mod_locations == null)
6198                 mod_locations = new List<Tuple<Modifiers, Location>> ();
6199
6200         mod_locations.Add (Tuple.Create ((Modifiers) token, loc));
6201 }
6202
6203 Block declare_local_variables (FullNamedExpression type, List<object> variable_declarators, Location loc)
6204 {
6205         Block implicit_block;
6206
6207         //
6208         // If we are doing interactive editing, we want variable declarations
6209         // that are in the top block to be added instead to the class as 
6210         // static variables
6211         //
6212         if (RootContext.StatementMode){
6213                 bool hoist = true;
6214
6215                 for (Block b = current_block; b != null; b = b.Parent){
6216                         if (b is ExplicitBlock && !(b is ToplevelBlock)){
6217                                 // There has been an explicit block, we cant add to the class
6218                                 hoist = false;
6219                                 break;
6220                         }
6221                 }               
6222                 if (hoist){
6223                         //
6224                         // We can use "current_block" since we know there are no explicit blocks
6225                         //
6226                         foreach (VariableDeclaration decl in variable_declarators){
6227                                 // We can not use the super-handy f.Initializer, because
6228                                 // multiple lines would force code to be executed out of sync
6229                                 var init = decl.GetInitializer (type);
6230                                 if (init != null){
6231                                         string id = "$" + decl.identifier;
6232                                         LocalInfo vi = current_block.AddVariable (type, id, decl.Location);                                     
6233
6234                                         // Avoid warning about this variable not being used.
6235                                         vi.Used = true;
6236
6237                                         LocalVariableReference var;
6238                                         var = new LocalVariableReferenceWithClassSideEffect (current_container, decl.identifier, current_block, id, vi, decl.Location);
6239                                         Assign assign = new SimpleAssign (var, init, decl.Location);
6240                                         current_block.AddStatement (new StatementExpression (assign));
6241                                         assign = new SimpleAssign (new SimpleName (decl.identifier, decl.Location), var);
6242                                         current_block.AddStatement (new StatementExpression (assign));
6243                                 } else {
6244                                         Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.PUBLIC | Modifiers.STATIC,
6245                                                 new MemberName (decl.identifier, loc), null);
6246                                         current_container.AddField (f);
6247
6248                                         // Register the field to be visible later as a global variable
6249                                         Evaluator.QueueField (f);
6250                                 }
6251                         }
6252
6253                         return current_block;
6254                 }
6255         }
6256
6257         //
6258         // We use the `Used' property to check whether statements
6259         // have been added to the current block.  If so, we need
6260         // to create another block to contain the new declaration
6261         // otherwise, as an optimization, we use the same block to
6262         // add the declaration.
6263         //
6264         // FIXME: A further optimization is to check if the statements
6265         // that were added were added as part of the initialization
6266         // below.  In which case, no other statements have been executed
6267         // and we might be able to reduce the number of blocks for
6268         // situations like this:
6269         //
6270         // int j = 1;  int k = j + 1;
6271         //
6272         if (current_block.Used)
6273                 implicit_block = new Block (current_block, loc, lexer.Location);
6274         else
6275                 implicit_block = current_block;
6276
6277         foreach (VariableDeclaration decl in variable_declarators){
6278
6279                 if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) {
6280                         if (decl.HasInitializer){
6281                                 Assign assign;
6282                                 
6283                                 var lvr = new LocalVariableReference (implicit_block, decl.identifier, loc);
6284
6285                                 assign = new SimpleAssign (lvr, decl.GetInitializer (type), decl.Location);
6286
6287                                 implicit_block.AddStatement (new StatementExpression (assign));
6288                         }
6289                 }
6290         }
6291         
6292         return implicit_block;
6293 }
6294
6295 Block declare_local_constants (FullNamedExpression type, List<object> declarators)
6296 {
6297         Block implicit_block;
6298
6299         if (current_block.Used)
6300                 implicit_block = new Block (current_block);
6301         else
6302                 implicit_block = current_block;
6303
6304         foreach (VariableDeclaration decl in declarators){
6305                 implicit_block.AddConstant (type, decl.identifier, decl.GetInitializer (type), decl.Location);
6306         }
6307         
6308         return implicit_block;
6309 }
6310
6311 string CheckAttributeTarget (string a, Location l)
6312 {
6313         switch (a) {
6314         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
6315                         return a;
6316         }
6317
6318         Report.Warning (658, 1, l,
6319                  "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
6320         return string.Empty;
6321 }
6322
6323 static bool IsUnaryOperator (Operator.OpType op)
6324 {
6325         switch (op) {
6326                 
6327         case Operator.OpType.LogicalNot: 
6328         case Operator.OpType.OnesComplement: 
6329         case Operator.OpType.Increment:
6330         case Operator.OpType.Decrement:
6331         case Operator.OpType.True: 
6332         case Operator.OpType.False: 
6333         case Operator.OpType.UnaryPlus: 
6334         case Operator.OpType.UnaryNegation:
6335                 return true;
6336         }
6337         return false;
6338 }
6339
6340 void syntax_error (Location l, string msg)
6341 {
6342         Report.Error (1003, l, "Syntax error, " + msg);
6343 }
6344
6345 Tokenizer lexer;
6346
6347 public Tokenizer Lexer {
6348         get {
6349                 return lexer;
6350         }
6351 }                  
6352
6353 static CSharpParser ()
6354 {
6355         oob_stack = new Stack<object> ();
6356 }
6357
6358 public CSharpParser (SeekableStreamReader reader, CompilationUnit file, CompilerContext ctx)
6359 {
6360         if (RootContext.EvalMode)
6361                 undo = new Undo ();
6362
6363         this.file = file;
6364         this.compiler = ctx;
6365         current_namespace = new NamespaceEntry (null, file, null);
6366         current_class = current_namespace.SlaveDeclSpace;
6367         current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
6368         oob_stack.Clear ();
6369         lexer = new Tokenizer (reader, file, ctx);
6370         
6371         use_global_stacks = true;
6372 }
6373
6374 public void parse ()
6375 {
6376         eof_token = Token.EOF;
6377         Tokenizer.LocatedToken.Initialize ();
6378         
6379         try {
6380                 if (yacc_verbose_flag > 1)
6381                         yyparse (lexer, new yydebug.yyDebugSimple ());
6382                 else
6383                         yyparse (lexer);
6384                         
6385                 Tokenizer tokenizer = lexer as Tokenizer;
6386                 tokenizer.cleanup ();           
6387         } catch (Exception e){
6388                 if (e is yyParser.yyUnexpectedEof)
6389                         UnexpectedEOF = true;
6390
6391                 if (e is yyParser.yyException)
6392                         Report.Error (-25, lexer.Location, "Parsing error");
6393                 else if (yacc_verbose_flag > 0)
6394                         throw;  // Used by compiler-tester to test internal errors
6395                 else 
6396                         Report.Error (589, lexer.Location, "Internal compiler error during parsing");
6397         }
6398
6399         if (RootContext.ToplevelTypes.NamespaceEntry != null)
6400                 throw new InternalErrorException ("who set it?");
6401 }
6402
6403 void CheckToken (int error, int yyToken, string msg, Location loc)
6404 {
6405         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
6406                 Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken));
6407         else
6408                 Report.Error (error, loc, msg);
6409 }
6410
6411 void CheckIdentifierToken (int yyToken, Location loc)
6412 {
6413         CheckToken (1041, yyToken, "Identifier expected", loc);
6414 }
6415
6416 string ConsumeStoredComment ()
6417 {
6418         string s = tmpComment;
6419         tmpComment = null;
6420         Lexer.doc_state = XmlCommentState.Allowed;
6421         return s;
6422 }
6423
6424 Location GetLocation (object obj)
6425 {
6426         if (obj is Tokenizer.LocatedToken)
6427                 return ((Tokenizer.LocatedToken) obj).Location;
6428         if (obj is MemberName)
6429                 return ((MemberName) obj).Location;
6430
6431         if (obj is Expression)
6432                 return ((Expression) obj).Location;
6433
6434         return lexer.Location;
6435 }
6436
6437 Report Report {
6438         get { return compiler.Report; }
6439 }
6440
6441 public LocationsBag LocationsBag {
6442         get {
6443                 return lbag;
6444         }
6445         set {
6446                 lbag = value;
6447         }
6448 }
6449
6450 void start_block (Location loc)
6451 {
6452         if (current_block == null || parsing_anonymous_method) {
6453                 current_block = new ToplevelBlock (compiler, current_block, current_local_parameters, loc);
6454                 parsing_anonymous_method = false;
6455         } else {
6456                 current_block = new ExplicitBlock (current_block, loc, Location.Null);
6457         }
6458 }
6459
6460 Block
6461 end_block (Location loc)
6462 {
6463         Block retval = current_block.Explicit;
6464         retval.SetEndLocation (loc);
6465         current_block = retval.Parent;
6466         return retval;
6467 }
6468
6469 void
6470 start_anonymous (bool lambda, ParametersCompiled parameters, Location loc)
6471 {
6472         if (RootContext.Version == LanguageVersion.ISO_1){
6473                 Report.FeatureIsNotAvailable (loc, "anonymous methods");
6474         }
6475
6476         oob_stack.Push (current_anonymous_method);
6477         oob_stack.Push (current_local_parameters);
6478
6479         current_local_parameters = parameters;
6480
6481         current_anonymous_method = lambda 
6482                 ? new LambdaExpression (loc) 
6483                 : new AnonymousMethodExpression (loc);
6484
6485         // Force the next block to be created as a ToplevelBlock
6486         parsing_anonymous_method = true;
6487 }
6488
6489 /*
6490  * Completes the anonymous method processing, if lambda_expr is null, this
6491  * means that we have a Statement instead of an Expression embedded 
6492  */
6493 AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block)
6494 {
6495         AnonymousMethodExpression retval;
6496
6497         current_anonymous_method.Block = anon_block;
6498         retval = current_anonymous_method;
6499
6500         current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
6501         current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
6502
6503         return retval;
6504 }
6505
6506 public NamespaceEntry CurrentNamespace {
6507        get { 
6508            return current_namespace;
6509        }
6510 }
6511
6512
6513 void Error_SyntaxError (int token)
6514 {
6515         Error_SyntaxError (0, token, "Unexpected symbol");
6516 }
6517
6518 void Error_SyntaxError (int error_code, int token, string msg)
6519 {
6520         string symbol = GetSymbolName (token);
6521         string expecting = GetExpecting ();
6522         
6523         if (error_code == 0) {
6524                 if (expecting == "`)'")
6525                         error_code = 1026;
6526                 else
6527                         error_code = 1525;
6528         }
6529         
6530         if (string.IsNullOrEmpty (expecting))
6531                 Report.Error (error_code, lexer.Location, "{1} `{0}'", symbol, msg);
6532         else
6533                 Report.Error (error_code, lexer.Location, "{2} `{0}', expecting {1}", symbol, expecting, msg);    
6534 }
6535
6536 string GetExpecting ()
6537 {
6538         int [] tokens = yyExpectingTokens (yyExpectingState);
6539         var names = new List<string> (tokens.Length);
6540         bool has_type = false;
6541         bool has_identifier = false;
6542         for (int i = 0; i < tokens.Length; i++){
6543                 int token = tokens [i];
6544                 has_identifier |= token == Token.IDENTIFIER;
6545                 
6546                 string name = GetTokenName (token);
6547                 if (name == "<internal>")
6548                         continue;
6549                         
6550                 has_type |= name == "type";
6551                 if (names.Contains (name))
6552                         continue;
6553                 
6554                 names.Add (name);
6555         }
6556
6557         //
6558         // Too many tokens to enumerate
6559         //
6560         if (names.Count > 8)
6561                 return null;
6562
6563         if (has_type && has_identifier)
6564                 names.Remove ("identifier");
6565
6566         if (names.Count == 1)
6567                 return "`" + GetTokenName (tokens [0]) + "'";
6568         
6569         StringBuilder sb = new StringBuilder ();
6570         names.Sort ();
6571         int count = names.Count;
6572         for (int i = 0; i < count; i++){
6573                 bool last = i + 1 == count;
6574                 if (last)
6575                         sb.Append ("or ");
6576                 sb.Append ('`');
6577                 sb.Append (names [i]);
6578                 sb.Append (last ? "'" : count < 3 ? "' " : "', ");
6579         }
6580         return sb.ToString ();
6581 }
6582
6583
6584 string GetSymbolName (int token)
6585 {
6586         switch (token){
6587         case Token.LITERAL:
6588                 return ((Constant)lexer.Value).GetValue ().ToString ();
6589         case Token.IDENTIFIER:
6590                 return ((Tokenizer.LocatedToken)lexer.Value).Value;
6591
6592         case Token.BOOL:
6593                 return "bool";
6594         case Token.BYTE:
6595                 return "byte";
6596         case Token.CHAR:
6597                 return "char";
6598         case Token.VOID:
6599                 return "void";
6600         case Token.DECIMAL:
6601                 return "decimal";
6602         case Token.DOUBLE:
6603                 return "double";
6604         case Token.FLOAT:
6605                 return "float";
6606         case Token.INT:
6607                 return "int";
6608         case Token.LONG:
6609                 return "long";
6610         case Token.SBYTE:
6611                 return "sbyte";
6612         case Token.SHORT:
6613                 return "short";
6614         case Token.STRING:
6615                 return "string";
6616         case Token.UINT:
6617                 return "uint";
6618         case Token.ULONG:
6619                 return "ulong";
6620         case Token.USHORT:
6621                 return "ushort";
6622         case Token.OBJECT:
6623                 return "object";
6624                 
6625         case Token.PLUS:
6626                 return "+";
6627         case Token.UMINUS:
6628         case Token.MINUS:
6629                 return "-";
6630         case Token.BANG:
6631                 return "!";
6632         case Token.BITWISE_AND:
6633                 return "&";
6634         case Token.BITWISE_OR:
6635                 return "|";
6636         case Token.STAR:
6637                 return "*";
6638         case Token.PERCENT:
6639                 return "%";
6640         case Token.DIV:
6641                 return "/";
6642         case Token.CARRET:
6643                 return "^";
6644         case Token.OP_INC:
6645                 return "++";
6646         case Token.OP_DEC:
6647                 return "--";
6648         case Token.OP_SHIFT_LEFT:
6649                 return "<<";
6650         case Token.OP_SHIFT_RIGHT:
6651                 return ">>";
6652         case Token.OP_LT:
6653                 return "<";
6654         case Token.OP_GT:
6655                 return ">";
6656         case Token.OP_LE:
6657                 return "<=";
6658         case Token.OP_GE:
6659                 return ">=";
6660         case Token.OP_EQ:
6661                 return "==";
6662         case Token.OP_NE:
6663                 return "!=";
6664         case Token.OP_AND:
6665                 return "&&";
6666         case Token.OP_OR:
6667                 return "||";
6668         case Token.OP_PTR:
6669                 return "->";
6670         case Token.OP_COALESCING:       
6671                 return "??";
6672         case Token.OP_MULT_ASSIGN:
6673                 return "*=";
6674         case Token.OP_DIV_ASSIGN:
6675                 return "/=";
6676         case Token.OP_MOD_ASSIGN:
6677                 return "%=";
6678         case Token.OP_ADD_ASSIGN:
6679                 return "+=";
6680         case Token.OP_SUB_ASSIGN:
6681                 return "-=";
6682         case Token.OP_SHIFT_LEFT_ASSIGN:
6683                 return "<<=";
6684         case Token.OP_SHIFT_RIGHT_ASSIGN:
6685                 return ">>=";
6686         case Token.OP_AND_ASSIGN:
6687                 return "&=";
6688         case Token.OP_XOR_ASSIGN:
6689                 return "^=";
6690         case Token.OP_OR_ASSIGN:
6691                 return "|=";
6692         }
6693
6694         return GetTokenName (token);
6695 }
6696
6697 static string GetTokenName (int token)
6698 {
6699         switch (token){
6700         case Token.ABSTRACT:
6701                 return "abstract";
6702         case Token.AS:
6703                 return "as";
6704         case Token.ADD:
6705                 return "add";
6706         case Token.BASE:
6707                 return "base";
6708         case Token.BREAK:
6709                 return "break";
6710         case Token.CASE:
6711                 return "case";
6712         case Token.CATCH:
6713                 return "catch";
6714         case Token.CHECKED:
6715                 return "checked";
6716         case Token.CLASS:
6717                 return "class";
6718         case Token.CONST:
6719                 return "const";
6720         case Token.CONTINUE:
6721                 return "continue";
6722         case Token.DEFAULT:
6723                 return "default";
6724         case Token.DELEGATE:
6725                 return "delegate";
6726         case Token.DO:
6727                 return "do";
6728         case Token.ELSE:
6729                 return "else";
6730         case Token.ENUM:
6731                 return "enum";
6732         case Token.EVENT:
6733                 return "event";
6734         case Token.EXPLICIT:
6735                 return "explicit";
6736         case Token.EXTERN:
6737                 return "extern";
6738         case Token.FALSE:
6739                 return "false";
6740         case Token.FINALLY:
6741                 return "finally";
6742         case Token.FIXED:
6743                 return "fixed";
6744         case Token.FOR:
6745                 return "for";
6746         case Token.FOREACH:
6747                 return "foreach";
6748         case Token.GOTO:
6749                 return "goto";
6750         case Token.IF:
6751                 return "if";
6752         case Token.IMPLICIT:
6753                 return "implicit";
6754         case Token.IN:
6755                 return "in";
6756         case Token.INTERFACE:
6757                 return "interface";
6758         case Token.INTERNAL:
6759                 return "internal";
6760         case Token.IS:
6761                 return "is";
6762         case Token.LOCK:
6763                 return "lock";
6764         case Token.NAMESPACE:
6765                 return "namespace";
6766         case Token.NEW:
6767                 return "new";
6768         case Token.NULL:
6769                 return "null";
6770         case Token.OPERATOR:
6771                 return "operator";
6772         case Token.OUT:
6773                 return "out";
6774         case Token.OVERRIDE:
6775                 return "override";
6776         case Token.PARAMS:
6777                 return "params";
6778         case Token.PRIVATE:
6779                 return "private";
6780         case Token.PROTECTED:
6781                 return "protected";
6782         case Token.PUBLIC:
6783                 return "public";
6784         case Token.READONLY:
6785                 return "readonly";
6786         case Token.REF:
6787                 return "ref";
6788         case Token.RETURN:
6789                 return "return";
6790         case Token.REMOVE:
6791                 return "remove";
6792         case Token.SEALED:
6793                 return "sealed";
6794         case Token.SIZEOF:
6795                 return "sizeof";
6796         case Token.STACKALLOC:
6797                 return "stackalloc";
6798         case Token.STATIC:
6799                 return "static";
6800         case Token.STRUCT:
6801                 return "struct";
6802         case Token.SWITCH:
6803                 return "switch";
6804         case Token.THIS:
6805                 return "this";
6806         case Token.THROW:
6807                 return "throw";
6808         case Token.TRUE:
6809                 return "true";
6810         case Token.TRY:
6811                 return "try";
6812         case Token.TYPEOF:
6813                 return "typeof";
6814         case Token.UNCHECKED:
6815                 return "unchecked";
6816         case Token.UNSAFE:
6817                 return "unsafe";
6818         case Token.USING:
6819                 return "using";
6820         case Token.VIRTUAL:
6821                 return "virtual";
6822         case Token.VOLATILE:
6823                 return "volatile";
6824         case Token.WHERE:
6825                 return "where";
6826         case Token.WHILE:
6827                 return "while";
6828         case Token.ARGLIST:
6829                 return "__arglist";
6830         case Token.PARTIAL:
6831                 return "partial";
6832         case Token.ARROW:
6833                 return "=>";
6834         case Token.FROM:
6835         case Token.FROM_FIRST:
6836                 return "from";
6837         case Token.JOIN:
6838                 return "join";
6839         case Token.ON:
6840                 return "on";
6841         case Token.EQUALS:
6842                 return "equals";
6843         case Token.SELECT:
6844                 return "select";
6845         case Token.GROUP:
6846                 return "group";
6847         case Token.BY:
6848                 return "by";
6849         case Token.LET:
6850                 return "let";
6851         case Token.ORDERBY:
6852                 return "orderby";
6853         case Token.ASCENDING:
6854                 return "ascending";
6855         case Token.DESCENDING:
6856                 return "descending";
6857         case Token.INTO:
6858                 return "into";
6859         case Token.GET:
6860                 return "get";
6861         case Token.SET:
6862                 return "set";
6863         case Token.OPEN_BRACE:
6864                 return "{";
6865         case Token.CLOSE_BRACE:
6866                 return "}";
6867         case Token.OPEN_BRACKET:
6868         case Token.OPEN_BRACKET_EXPR:
6869                 return "[";
6870         case Token.CLOSE_BRACKET:
6871                 return "]";
6872         case Token.OPEN_PARENS_CAST:
6873         case Token.OPEN_PARENS_LAMBDA:
6874         case Token.OPEN_PARENS:
6875                 return "(";
6876         case Token.CLOSE_PARENS:
6877                 return ")";
6878         case Token.DOT:
6879                 return ".";
6880         case Token.COMMA:
6881                 return ",";
6882         case Token.DEFAULT_COLON:
6883                 return "default:";
6884         case Token.COLON:
6885                 return ":";
6886         case Token.SEMICOLON:
6887                 return ";";
6888         case Token.TILDE:
6889                 return "~";
6890                 
6891         case Token.PLUS:
6892         case Token.UMINUS:
6893         case Token.MINUS:
6894         case Token.BANG:
6895         case Token.OP_LT:
6896         case Token.OP_GT:
6897         case Token.BITWISE_AND:
6898         case Token.BITWISE_OR:
6899         case Token.STAR:
6900         case Token.PERCENT:
6901         case Token.DIV:
6902         case Token.CARRET:
6903         case Token.OP_INC:
6904         case Token.OP_DEC:
6905         case Token.OP_SHIFT_LEFT:
6906         case Token.OP_SHIFT_RIGHT:
6907         case Token.OP_LE:
6908         case Token.OP_GE:
6909         case Token.OP_EQ:
6910         case Token.OP_NE:
6911         case Token.OP_AND:
6912         case Token.OP_OR:
6913         case Token.OP_PTR:
6914         case Token.OP_COALESCING:       
6915         case Token.OP_MULT_ASSIGN:
6916         case Token.OP_DIV_ASSIGN:
6917         case Token.OP_MOD_ASSIGN:
6918         case Token.OP_ADD_ASSIGN:
6919         case Token.OP_SUB_ASSIGN:
6920         case Token.OP_SHIFT_LEFT_ASSIGN:
6921         case Token.OP_SHIFT_RIGHT_ASSIGN:
6922         case Token.OP_AND_ASSIGN:
6923         case Token.OP_XOR_ASSIGN:
6924         case Token.OP_OR_ASSIGN:
6925                 return "<operator>";
6926
6927         case Token.BOOL:
6928         case Token.BYTE:
6929         case Token.CHAR:
6930         case Token.VOID:
6931         case Token.DECIMAL:
6932         case Token.DOUBLE:
6933         case Token.FLOAT:
6934         case Token.INT:
6935         case Token.LONG:
6936         case Token.SBYTE:
6937         case Token.SHORT:
6938         case Token.STRING:
6939         case Token.UINT:
6940         case Token.ULONG:
6941         case Token.USHORT:
6942         case Token.OBJECT:
6943                 return "type";
6944         
6945         case Token.ASSIGN:
6946                 return "=";
6947         case Token.OP_GENERICS_LT:
6948         case Token.GENERIC_DIMENSION:
6949                 return "<";
6950         case Token.OP_GENERICS_GT:
6951                 return ">";
6952         case Token.INTERR:
6953         case Token.INTERR_NULLABLE:
6954                 return "?";
6955         case Token.DOUBLE_COLON:
6956                 return "::";
6957         case Token.LITERAL:
6958                 return "value";
6959         case Token.IDENTIFIER:
6960                 return "identifier";
6961
6962                 // All of these are internal.
6963         case Token.NONE:
6964         case Token.ERROR:
6965         case Token.FIRST_KEYWORD:
6966         case Token.EOF:
6967         case Token.EVAL_COMPILATION_UNIT_PARSER:
6968         case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER:
6969         case Token.EVAL_STATEMENT_PARSER:
6970         case Token.LAST_KEYWORD:
6971         case Token.GENERATE_COMPLETION:
6972         case Token.COMPLETE_COMPLETION:
6973                 return "<internal>";
6974
6975                 // A bit more robust.
6976         default:
6977                 return yyNames [token];
6978         }
6979 }
6980
6981 /* end end end */
6982 }