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