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