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