2010-05-19 Jb Evain <jbevain@novell.com>
[mcs.git] / mcs / cs-parser.jay
blob647360860130734dacd28bf473d94265e8ac5d1d
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         ;
2989 // Expressions, section 7.5
2993 primary_expression
2994         : primary_expression_no_array_creation
2995         | array_creation_expression
2996         ;
2998 primary_expression_no_array_creation
2999         : literal
3000         | IDENTIFIER opt_type_argument_list
3001           {
3002                 var lt = (Tokenizer.LocatedToken) $1;
3003                 $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);   
3004           }
3005         | IDENTIFIER GENERATE_COMPLETION {
3006                 var lt = (Tokenizer.LocatedToken) $1;
3007                $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location);
3008           }
3009         | parenthesized_expression
3010         | default_value_expression
3011         | member_access
3012         | invocation_expression
3013         | element_access
3014         | this_access
3015         | base_access
3016         | post_increment_expression
3017         | post_decrement_expression
3018         | object_or_delegate_creation_expression
3019         | anonymous_type_expression
3020         | typeof_expression
3021         | sizeof_expression
3022         | checked_expression
3023         | unchecked_expression
3024         | pointer_member_access
3025         | anonymous_method_expression
3026         ;
3028 literal
3029         : boolean_literal
3030         | LITERAL
3031         | NULL                  { $$ = new NullLiteral (GetLocation ($1)); }
3032         ;
3034 boolean_literal
3035         : TRUE                  { $$ = new BoolLiteral (true, GetLocation ($1)); }
3036         | FALSE                 { $$ = new BoolLiteral (false, GetLocation ($1)); }
3037         ;
3041 // Here is the trick, tokenizer may think that parens is a special but
3042 // parser is interested in open parens only, so we merge them.
3043 // Consider: if (a)foo ();
3045 open_parens_any
3046         : OPEN_PARENS
3047         | OPEN_PARENS_CAST
3048         ;
3050 // 
3051 // Use this production to accept closing parenthesis or 
3052 // performing completion
3054 close_parens
3055         : CLOSE_PARENS
3056         | COMPLETE_COMPLETION
3057         ;
3060 parenthesized_expression
3061         : OPEN_PARENS expression CLOSE_PARENS
3062           {
3063                 $$ = new ParenthesizedExpression ((Expression) $2);
3064           }
3065         | OPEN_PARENS expression COMPLETE_COMPLETION
3066           {
3067                 $$ = new ParenthesizedExpression ((Expression) $2);
3068           }
3069         ;
3070         
3071 member_access
3072         : primary_expression DOT IDENTIFIER opt_type_argument_list
3073           {
3074                 var lt = (Tokenizer.LocatedToken) $3;
3075                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3076           }
3077         | builtin_types DOT IDENTIFIER opt_type_argument_list
3078           {
3079                 var lt = (Tokenizer.LocatedToken) $3;
3080                 // TODO: Location is wrong as some predefined types doesn't hold a location
3081                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3082           }
3083         | qualified_alias_member IDENTIFIER opt_type_argument_list
3084           {
3085                 var lt1 = (Tokenizer.LocatedToken) $1;
3086                 var lt2 = (Tokenizer.LocatedToken) $2;
3088                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
3089           }
3090         | primary_expression DOT GENERATE_COMPLETION {
3091                 $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3));
3092           }
3093         | primary_expression DOT IDENTIFIER GENERATE_COMPLETION {
3094                 var lt = (Tokenizer.LocatedToken) $3;
3095                 $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
3096           }
3097         | builtin_types DOT GENERATE_COMPLETION
3098           {
3099                 // TODO: Location is wrong as some predefined types doesn't hold a location
3100                 $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location);
3101           }
3102         | builtin_types DOT IDENTIFIER GENERATE_COMPLETION {
3103                 var lt = (Tokenizer.LocatedToken) $3;
3104                 $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
3105           }
3106         ;
3108 invocation_expression
3109         : primary_expression open_parens_any opt_argument_list close_parens
3110           {
3111                 $$ = new Invocation ((Expression) $1, (Arguments) $3);
3112           }
3113         ;
3115 opt_object_or_collection_initializer
3116         : /* empty */           { $$ = null; }
3117         | object_or_collection_initializer
3118         ;
3120 object_or_collection_initializer
3121         : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion
3122           {
3123                 if ($2 == null)
3124                         $$ = CollectionOrObjectInitializers.Empty;
3125                 else
3126                         $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
3127           }
3128         | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE
3129           {
3130                 $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
3131           }
3132         ;
3134 opt_member_initializer_list
3135         : /* empty */           { $$ = null; }
3136         | member_initializer_list
3137         {
3138                 $$ = $1;
3139         }
3140         ;
3142 member_initializer_list
3143         : member_initializer
3144           {
3145                 var a = new List<Expression> ();
3146                 a.Add ((Expression) $1);
3147                 $$ = a;
3148           }
3149         | member_initializer_list COMMA member_initializer
3150           {
3151                 var a = (List<Expression>)$1;
3152                 a.Add ((Expression) $3);
3153                 $$ = a;
3154           }
3155         | member_initializer_list error {
3156                 Error_SyntaxError (yyToken);
3157                 $$ = $1;
3158           }
3159         ;
3161 member_initializer
3162         : IDENTIFIER ASSIGN initializer_value
3163           {
3164                 var lt = (Tokenizer.LocatedToken) $1;
3165                 $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
3166           }
3167         | GENERATE_COMPLETION 
3168           {
3169                 $$ = new CompletionElementInitializer (null, GetLocation ($1));
3170           }
3171         | non_assignment_expression opt_COMPLETE_COMPLETION  {
3172                 CompletionSimpleName csn = $1 as CompletionSimpleName;
3173                 if (csn == null)
3174                         $$ = new CollectionElementInitializer ((Expression)$1);
3175                 else
3176                         $$ = new CompletionElementInitializer (csn.Prefix, csn.Location);
3177           }
3178         | OPEN_BRACE expression_list CLOSE_BRACE
3179           {
3180                 if ($2 == null)
3181                         $$ = null;
3182                 else
3183                         $$ = new CollectionElementInitializer ((List<Expression>)$2, GetLocation ($1));
3184           }
3185         | OPEN_BRACE CLOSE_BRACE
3186           {
3187                 Report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
3188                 $$ = null;
3189           }       
3190         ;
3192 initializer_value
3193         : expression
3194         | object_or_collection_initializer
3195         ;
3197 opt_argument_list
3198         : /* empty */           { $$ = null; }
3199         | argument_list
3200         ;
3202 argument_list
3203         : argument_or_named_argument
3204           { 
3205                 Arguments list = new Arguments (4);
3206                 list.Add ((Argument) $1);
3207                 $$ = list;
3208           }
3209         | argument_list COMMA argument
3210           {
3211                 Arguments list = (Arguments) $1;
3212                 if (list [list.Count - 1] is NamedArgument)
3213                         Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]);
3214                 
3215                 list.Add ((Argument) $3);
3216                 $$ = list;
3217           }
3218         | argument_list COMMA named_argument
3219           {
3220                 Arguments list = (Arguments) $1;
3221                 NamedArgument a = (NamedArgument) $3;
3222                 for (int i = 0; i < list.Count; ++i) {
3223                         NamedArgument na = list [i] as NamedArgument;
3224                         if (na != null && na.Name == a.Name)
3225                                 Report.Error (1740, na.Location, "Named argument `{0}' specified multiple times",
3226                                         na.Name);
3227                 }
3228                 
3229                 list.Add (a);
3230                 $$ = list;
3231           }
3232         | argument_list COMMA
3233           {
3234                 Report.Error (839, GetLocation ($2), "An argument is missing");
3235                 $$ = $1;
3236           }
3237         | COMMA argument_or_named_argument
3238           {
3239                 Report.Error (839, GetLocation ($1), "An argument is missing");
3240                 $$ = $1;
3241           }
3242         ;
3244 argument
3245         : expression
3246           {
3247                 $$ = new Argument ((Expression) $1);
3248           }
3249         | non_simple_argument
3250         ;
3252 argument_or_named_argument
3253         : argument
3254         | named_argument
3255         ;
3257 non_simple_argument
3258         : REF variable_reference 
3259           { 
3260                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3261           }
3262         | OUT variable_reference 
3263           { 
3264                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
3265           }
3266         | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
3267           {
3268                 $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1)));
3269           }
3270         | ARGLIST OPEN_PARENS CLOSE_PARENS
3271           {
3272                 $$ = new Argument (new Arglist (GetLocation ($1)));
3273           }       
3274         | ARGLIST
3275           {
3276                 $$ = new Argument (new ArglistAccess (GetLocation ($1)));
3277           }
3278         ;
3280 variable_reference
3281         : expression
3282         ;
3284 element_access
3285         : primary_expression_no_array_creation OPEN_BRACKET expression_list_arguments CLOSE_BRACKET     
3286           {
3287                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3);
3288           }
3289         | array_creation_expression OPEN_BRACKET expression_list_arguments CLOSE_BRACKET
3290           {
3291                 // LAMESPEC: Not allowed according to specification
3292                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3);
3293           }     
3294         | primary_expression_no_array_creation rank_specifiers
3295           {
3296                 // So the super-trick is that primary_expression
3297                 // can only be either a SimpleName or a MemberAccess. 
3298                 // The MemberAccess case arises when you have a fully qualified type-name like :
3299                 // Foo.Bar.Blah i;
3300                 // SimpleName is when you have
3301                 // Blah i;
3302                   
3303                 Expression expr = (Expression) $1;  
3304                 if (expr is ComposedCast){
3305                         $$ = new ComposedCast ((ComposedCast)expr, (string) $2);
3306                 } else if (expr is ATypeNameExpression){
3307                         //
3308                         // So we extract the string corresponding to the SimpleName
3309                         // or MemberAccess
3310                         // 
3311                         $$ = new ComposedCast ((ATypeNameExpression)expr, (string) $2);
3312                 } else {
3313                         Error_ExpectingTypeName (expr);
3314                         $$ = TypeManager.system_object_expr;
3315                 }
3316           }
3317         ;
3319 expression_list
3320         : expression
3321           {
3322                 var list = new List<Expression> (4);
3323                 list.Add ((Expression) $1);
3324                 $$ = list;
3325           }
3326         | expression_list COMMA expression
3327           {
3328                 var list = (List<Expression>) $1;
3329                 list.Add ((Expression) $3);
3330                 $$ = list;
3331           }
3332         | expression_list error {
3333                 Error_SyntaxError (yyToken);
3334                 $$ = $1;
3335           }
3336         ;
3337         
3338 expression_list_arguments
3339         : expression_list_argument
3340           {
3341                 Arguments args = new Arguments (4);
3342                 args.Add ((Argument) $1);
3343                 $$ = args;
3344           }
3345         | expression_list_arguments COMMA expression_list_argument
3346           {
3347                 Arguments args = (Arguments) $1;
3348                 args.Add ((Argument) $3);
3349                 $$ = args;        
3350           }
3351         ;
3352         
3353 expression_list_argument
3354         : expression
3355           {
3356                 $$ = new Argument ((Expression) $1);
3357           }
3358         | named_argument
3359         ;
3361 this_access
3362         : THIS
3363           {
3364                 $$ = new This (current_block, GetLocation ($1));
3365           }
3366         ;
3368 base_access
3369         : BASE DOT IDENTIFIER opt_type_argument_list
3370           {
3371                 var lt = (Tokenizer.LocatedToken) $3;
3372                 $$ = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location);
3373           }
3374         | BASE OPEN_BRACKET expression_list_arguments CLOSE_BRACKET
3375           {
3376                 $$ = new BaseIndexerAccess ((Arguments) $3, GetLocation ($1));
3377           }
3378         | BASE error
3379           {
3380                 Error_SyntaxError (yyToken);
3381                 $$ = new BaseAccess (null, GetLocation ($2));
3382           }
3383         ;
3385 post_increment_expression
3386         : primary_expression OP_INC
3387           {
3388                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1, GetLocation ($2));
3389           }
3390         ;
3392 post_decrement_expression
3393         : primary_expression OP_DEC
3394           {
3395                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1, GetLocation ($2));
3396           }
3397         ;
3399 object_or_delegate_creation_expression
3400         : new_expr_start open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer
3401           {
3402                 if ($5 != null) {
3403                         if (RootContext.Version <= LanguageVersion.ISO_2)
3404                                 Report.FeatureIsNotAvailable (GetLocation ($1), "object initializers");
3405                                 
3406                         $$ = new NewInitialize ((Expression) $1, (Arguments) $3, (CollectionOrObjectInitializers) $5, GetLocation ($1));
3407                 }
3408                 else
3409                         $$ = new New ((Expression) $1, (Arguments) $3, GetLocation ($1));
3410           }
3411         | new_expr_start object_or_collection_initializer
3412           {
3413                 if (RootContext.Version <= LanguageVersion.ISO_2)
3414                         Report.FeatureIsNotAvailable (GetLocation ($1), "collection initializers");
3415           
3416                 $$ = new NewInitialize ((Expression) $1, null, (CollectionOrObjectInitializers) $2, GetLocation ($1));
3417           }
3418         ;
3420 array_creation_expression
3421         : new_expr_start OPEN_BRACKET expression_list CLOSE_BRACKET 
3422           opt_rank_specifier    // shift/reduce on OPEN_BRACE
3423           opt_array_initializer
3424           {
3425                 $$ = new ArrayCreation ((FullNamedExpression) $1, (List<Expression>) $3, (string) $5, (ArrayInitializer) $6, GetLocation ($1));
3426           }
3427         | new_expr_start rank_specifiers opt_array_initializer
3428           {
3429                 if ($3 == null)
3430                         Report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer");
3432                 $$ = new ArrayCreation ((FullNamedExpression) $1, (string) $2, (ArrayInitializer) $3, GetLocation ($1));
3433           }
3434         | NEW rank_specifiers array_initializer
3435           {
3436                 if (RootContext.Version <= LanguageVersion.ISO_2)
3437                         Report.FeatureIsNotAvailable (GetLocation ($1), "implicitly typed arrays");
3438           
3439                 $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayInitializer) $3, GetLocation ($1));
3440           }
3441         | new_expr_start error
3442           {
3443                 Report.Error (1526, GetLocation ($1), "A new expression requires () or [] after type");
3444                 $$ = new ArrayCreation ((FullNamedExpression) $1, "[]", null, GetLocation ($1));
3445           }
3446         ;
3448 new_expr_start
3449         : NEW
3450           {
3451                 ++lexer.parsing_type;
3452           }
3453           simple_type
3454           {
3455                 --lexer.parsing_type;
3456                 $$ = $3;
3457           }
3458         ;
3460 anonymous_type_expression
3461         : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
3462           {
3463                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
3464                         Report.FeatureIsNotSupported (GetLocation ($1), "anonymous types");
3465                 else if (RootContext.Version <= LanguageVersion.ISO_2)
3466                         Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
3468                 $$ = new NewAnonymousType ((List<AnonymousTypeParameter>) $3, current_container, GetLocation ($1));
3469           }
3470         ;
3472 anonymous_type_parameters_opt_comma
3473         : anonymous_type_parameters_opt
3474         | anonymous_type_parameters COMMA
3475         ;
3477 anonymous_type_parameters_opt
3478         : { $$ = null; }
3479         | anonymous_type_parameters
3480         ;
3482 anonymous_type_parameters
3483         : anonymous_type_parameter
3484           {
3485                 var a = new List<AnonymousTypeParameter> (4);
3486                 a.Add ((AnonymousTypeParameter) $1);
3487                 $$ = a;
3488           }
3489         | anonymous_type_parameters COMMA anonymous_type_parameter
3490           {
3491                 var a = (List<AnonymousTypeParameter>) $1;
3492                 a.Add ((AnonymousTypeParameter) $3);
3493                 $$ = a;
3494           }
3495         ;
3497 anonymous_type_parameter
3498         : IDENTIFIER ASSIGN variable_initializer
3499           {
3500                 var lt = (Tokenizer.LocatedToken)$1;
3501                 $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
3502           }
3503         | IDENTIFIER
3504           {
3505                 var lt = (Tokenizer.LocatedToken)$1;
3506                 $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
3507                         lt.Value, lt.Location);
3508           }
3509         | BASE DOT IDENTIFIER opt_type_argument_list
3510           {
3511                 var lt = (Tokenizer.LocatedToken) $3;
3512                 BaseAccess ba = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location);
3513                 $$ = new AnonymousTypeParameter (ba, lt.Value, lt.Location);            
3514           }       
3515         | member_access
3516           {
3517                 MemberAccess ma = (MemberAccess) $1;
3518                 $$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
3519           }
3520         | error
3521           {
3522                 Report.Error (746, lexer.Location,
3523                         "Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression");
3524                 $$ = null;
3525           }
3526         ;
3528 opt_rank_specifier
3529         : /* empty */
3530           {
3531                 $$ = "";
3532           }
3533         | rank_specifiers
3534           {
3535                 $$ = $1;
3536           }
3537         ;
3539 opt_rank_specifier_or_nullable
3540         : opt_nullable
3541           {
3542                 if ($1 != null)
3543                         $$ = "?";
3544                 else
3545                         $$ = string.Empty;
3546           }
3547         | opt_nullable rank_specifiers
3548           {
3549                 if ($1 != null)
3550                         $$ = "?" + (string) $2;
3551                 else
3552                         $$ = $2;
3553           }
3554         ;
3556 rank_specifiers
3557         : rank_specifier
3558         | rank_specifier rank_specifiers
3559           {
3560                 $$ = (string) $1 + (string) $2;
3561           }
3562         ;
3564 rank_specifier
3565         : OPEN_BRACKET CLOSE_BRACKET
3566           {
3567                 $$ = "[]";
3568           }
3569         | OPEN_BRACKET dim_separators CLOSE_BRACKET
3570           {
3571                 $$ = "[" + (string) $2 + "]";
3572           }
3573         | OPEN_BRACKET error
3574           {
3575                 Error_SyntaxError (178, yyToken, "Invalid rank specifier");
3576                 $$ = "[]";
3577           }
3578         ;
3580 dim_separators
3581         : COMMA
3582           {
3583                 $$ = ",";
3584           }
3585         | dim_separators COMMA
3586           {
3587                 $$ = (string) $1 + ",";
3588           }
3589         ;
3591 opt_array_initializer
3592         : /* empty */
3593           {
3594                 $$ = null;
3595           }
3596         | array_initializer
3597           {
3598                 $$ = $1;
3599           }
3600         ;
3602 array_initializer
3603         : OPEN_BRACE CLOSE_BRACE
3604           {
3605                 $$ = new ArrayInitializer (0, GetLocation ($1));
3606           }
3607         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
3608           {
3609                 $$ = new ArrayInitializer ((List<Expression>) $2, GetLocation ($1));
3610           }
3611         ;
3613 variable_initializer_list
3614         : variable_initializer
3615           {
3616                 var list = new List<Expression> (4);
3617                 list.Add ((Expression) $1);
3618                 $$ = list;
3619           }
3620         | variable_initializer_list COMMA variable_initializer
3621           {
3622                 var list = (List<Expression>) $1;
3623                 list.Add ((Expression) $3);
3624                 $$ = list;
3625           }
3626         | error
3627           {
3628                 Error_SyntaxError (yyToken);
3629                 $$ = new List<Expression> ();
3630           }
3631         ;
3633 typeof_expression
3634         : TYPEOF
3635       {
3636                 lexer.TypeOfParsing = true;
3637           }
3638           open_parens_any typeof_type_expression CLOSE_PARENS
3639           {
3640                 lexer.TypeOfParsing = false;
3641                 Expression type = (Expression)$4;
3642                 if (type == TypeManager.system_void_expr)
3643                         $$ = new TypeOfVoid (GetLocation ($1));
3644                 else
3645                         $$ = new TypeOf (type, GetLocation ($1));
3646           }
3647         ;
3648         
3649 typeof_type_expression
3650         : type_and_void
3651         | unbound_type_name
3652         | error
3653          {
3654                 Error_TypeExpected (lexer.Location);
3655                 $$ = null;
3656          }
3657         ;
3658         
3659 unbound_type_name
3660         : IDENTIFIER generic_dimension
3661           {  
3662                 var lt = (Tokenizer.LocatedToken) $1;
3664                 $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
3665           }
3666         | qualified_alias_member IDENTIFIER generic_dimension
3667           {
3668                 var lt1 = (Tokenizer.LocatedToken) $1;
3669                 var lt2 = (Tokenizer.LocatedToken) $2;
3671                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
3672           }
3673         | unbound_type_name DOT IDENTIFIER
3674           {
3675                 var lt = (Tokenizer.LocatedToken) $3;
3676                 
3677                 $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);         
3678           }
3679         | unbound_type_name DOT IDENTIFIER generic_dimension
3680           {
3681                 var lt = (Tokenizer.LocatedToken) $3;
3682                 
3683                 $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);               
3684           }
3685         | namespace_or_type_name DOT IDENTIFIER generic_dimension
3686           {
3687                 var lt = (Tokenizer.LocatedToken) $3;
3688                 MemberName name = (MemberName) $1;
3690                 $$ = new MemberAccess (name.GetTypeExpression (), lt.Value, (int) $4, lt.Location);             
3691           }
3692         ;
3694 generic_dimension
3695         : GENERIC_DIMENSION
3696           {
3697                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
3698                         Report.FeatureIsNotSupported (GetLocation ($1), "generics");
3699                 else if (RootContext.Version < LanguageVersion.ISO_2)
3700                         Report.FeatureIsNotAvailable (GetLocation ($1), "generics");
3702                 $$ = $1;
3703           }
3704         ;
3705         
3706 qualified_alias_member
3707         : IDENTIFIER DOUBLE_COLON
3708           {
3709                 var lt = (Tokenizer.LocatedToken) $1;
3710                 if (RootContext.Version == LanguageVersion.ISO_1)
3711                         Report.FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
3713                 $$ = lt;                
3714           }
3715         ;
3717 sizeof_expression
3718         : SIZEOF open_parens_any type CLOSE_PARENS { 
3719                 $$ = new SizeOf ((Expression) $3, GetLocation ($1));
3720           }
3721         ;
3723 checked_expression
3724         : CHECKED open_parens_any expression CLOSE_PARENS
3725           {
3726                 $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
3727           }
3728         ;
3730 unchecked_expression
3731         : UNCHECKED open_parens_any expression CLOSE_PARENS
3732           {
3733                 $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
3734           }
3735         ;
3737 pointer_member_access 
3738         : primary_expression OP_PTR IDENTIFIER
3739           {
3740                 Expression deref;
3741                 var lt = (Tokenizer.LocatedToken) $3;
3743                 deref = new Indirection ((Expression) $1, lt.Location);
3744                 $$ = new MemberAccess (deref, lt.Value);
3745           }
3746         ;
3748 anonymous_method_expression
3749         : DELEGATE opt_anonymous_method_signature
3750           {
3751                 start_anonymous (false, (ParametersCompiled) $2, GetLocation ($1));
3752           }
3753           block
3754           {
3755                 $$ = end_anonymous ((ToplevelBlock) $4);
3756         }
3757         ;
3759 opt_anonymous_method_signature
3760         : 
3761           {
3762                 $$ = ParametersCompiled.Undefined;
3763           } 
3764         | anonymous_method_signature
3765         ;
3767 anonymous_method_signature
3768         : OPEN_PARENS
3769           {
3770                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
3771           }
3772           opt_formal_parameter_list CLOSE_PARENS
3773           {
3774                 valid_param_mod = 0;
3775                 $$ = $3;
3776           }
3777         ;
3779 default_value_expression
3780         : DEFAULT open_parens_any type CLOSE_PARENS
3781           {
3782                 if (RootContext.Version < LanguageVersion.ISO_2)
3783                         Report.FeatureIsNotAvailable (GetLocation ($1), "default value expression");
3785                 $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1));
3786           }
3787         ;
3789 unary_expression
3790         : primary_expression
3791         | BANG prefixed_unary_expression
3792           {
3793                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1));
3794           }
3795         | TILDE prefixed_unary_expression
3796           {
3797                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
3798           }
3799         | cast_expression
3800         ;
3802 cast_expression
3803         : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
3804           {
3805                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3806           }
3807         | OPEN_PARENS builtin_types CLOSE_PARENS prefixed_unary_expression
3808           {
3809                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3810           }
3811         ;
3813         //
3814         // The idea to split this out is from Rhys' grammar
3815         // to solve the problem with casts.
3816         //
3817 prefixed_unary_expression
3818         : unary_expression
3819         | PLUS prefixed_unary_expression
3820           { 
3821                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
3822           } 
3823         | MINUS prefixed_unary_expression 
3824           { 
3825                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
3826           }
3827         | OP_INC prefixed_unary_expression 
3828           {
3829                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1));
3830           }
3831         | OP_DEC prefixed_unary_expression 
3832           {
3833                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1));
3834           }
3835         | STAR prefixed_unary_expression
3836           {
3837                 $$ = new Indirection ((Expression) $2, GetLocation ($1));
3838           }
3839         | BITWISE_AND prefixed_unary_expression
3840           {
3841                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1));
3842           }
3843         ;
3845 multiplicative_expression
3846         : prefixed_unary_expression
3847         | multiplicative_expression STAR prefixed_unary_expression
3848           {
3849                 $$ = new Binary (Binary.Operator.Multiply, 
3850                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3851           }
3852         | multiplicative_expression DIV prefixed_unary_expression
3853           {
3854                 $$ = new Binary (Binary.Operator.Division, 
3855                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3856           }
3857         | multiplicative_expression PERCENT prefixed_unary_expression 
3858           {
3859                 $$ = new Binary (Binary.Operator.Modulus, 
3860                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3861           }
3862         ;
3864 additive_expression
3865         : multiplicative_expression
3866         | additive_expression PLUS multiplicative_expression 
3867           {
3868                 $$ = new Binary (Binary.Operator.Addition, 
3869                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3870           }
3871         | additive_expression MINUS multiplicative_expression
3872           {
3873                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
3874           }
3875         | parenthesized_expression MINUS multiplicative_expression
3876           {
3877                 // Shift/Reduce conflict
3878                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
3879           }
3880         | additive_expression AS type
3881           {
3882                 $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
3883           }
3884         | additive_expression IS type
3885           {
3886                 $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
3887           }       
3888         ;
3890 shift_expression
3891         : additive_expression
3892         | shift_expression OP_SHIFT_LEFT additive_expression
3893           {
3894                 $$ = new Binary (Binary.Operator.LeftShift, 
3895                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3896           }
3897         | shift_expression OP_SHIFT_RIGHT additive_expression
3898           {
3899                 $$ = new Binary (Binary.Operator.RightShift, 
3900                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3901           }
3902         ; 
3904 relational_expression
3905         : shift_expression
3906         | relational_expression OP_LT shift_expression
3907           {
3908                 $$ = new Binary (Binary.Operator.LessThan, 
3909                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3910           }
3911         | relational_expression OP_GT shift_expression
3912           {
3913                 $$ = new Binary (Binary.Operator.GreaterThan, 
3914                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3915           }
3916         | relational_expression OP_LE shift_expression
3917           {
3918                 $$ = new Binary (Binary.Operator.LessThanOrEqual, 
3919                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3920           }
3921         | relational_expression OP_GE shift_expression
3922           {
3923                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
3924                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3925           }
3926         ;
3928 equality_expression
3929         : relational_expression
3930         | equality_expression OP_EQ relational_expression
3931           {
3932                 $$ = new Binary (Binary.Operator.Equality, 
3933                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3934           }
3935         | equality_expression OP_NE relational_expression
3936           {
3937                 $$ = new Binary (Binary.Operator.Inequality, 
3938                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3939           }
3940         ; 
3942 and_expression
3943         : equality_expression
3944         | and_expression BITWISE_AND equality_expression
3945           {
3946                 $$ = new Binary (Binary.Operator.BitwiseAnd, 
3947                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3948           }
3949         ;
3951 exclusive_or_expression
3952         : and_expression
3953         | exclusive_or_expression CARRET and_expression
3954           {
3955                 $$ = new Binary (Binary.Operator.ExclusiveOr, 
3956                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3957           }
3958         ;
3960 inclusive_or_expression
3961         : exclusive_or_expression
3962         | inclusive_or_expression BITWISE_OR exclusive_or_expression
3963           {
3964                 $$ = new Binary (Binary.Operator.BitwiseOr, 
3965                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3966           }
3967         ;
3969 conditional_and_expression
3970         : inclusive_or_expression
3971         | conditional_and_expression OP_AND inclusive_or_expression
3972           {
3973                 $$ = new Binary (Binary.Operator.LogicalAnd, 
3974                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3975           }
3976         ;
3978 conditional_or_expression
3979         : conditional_and_expression
3980         | conditional_or_expression OP_OR conditional_and_expression
3981           {
3982                 $$ = new Binary (Binary.Operator.LogicalOr, 
3983                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3984           }
3985         ;
3986         
3987 null_coalescing_expression
3988         : conditional_or_expression
3989         | conditional_or_expression OP_COALESCING null_coalescing_expression
3990           {
3991                 if (RootContext.Version < LanguageVersion.ISO_2)
3992                         Report.FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
3993                         
3994                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, GetLocation ($2));
3995           }
3996         ;
3998 conditional_expression
3999         : null_coalescing_expression
4000         | null_coalescing_expression INTERR expression COLON expression 
4001           {
4002                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5);
4003           }
4004         ;
4006 assignment_expression
4007         : prefixed_unary_expression ASSIGN expression
4008           {
4009                 $$ = new SimpleAssign ((Expression) $1, (Expression) $3);
4010           }
4011         | prefixed_unary_expression OP_MULT_ASSIGN expression
4012           {
4013                 $$ = new CompoundAssign (
4014                         Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
4015           }
4016         | prefixed_unary_expression OP_DIV_ASSIGN expression
4017           {
4018                 $$ = new CompoundAssign (
4019                         Binary.Operator.Division, (Expression) $1, (Expression) $3);
4020           }
4021         | prefixed_unary_expression OP_MOD_ASSIGN expression
4022           {
4023                 $$ = new CompoundAssign (
4024                         Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
4025           }
4026         | prefixed_unary_expression OP_ADD_ASSIGN expression
4027           {
4028                 $$ = new CompoundAssign (
4029                         Binary.Operator.Addition, (Expression) $1, (Expression) $3);
4030           }
4031         | prefixed_unary_expression OP_SUB_ASSIGN expression
4032           {
4033                 $$ = new CompoundAssign (
4034                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
4035           }
4036         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
4037           {
4038                 $$ = new CompoundAssign (
4039                         Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
4040           }
4041         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
4042           {
4043                 $$ = new CompoundAssign (
4044                         Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
4045           }
4046         | prefixed_unary_expression OP_AND_ASSIGN expression
4047           {
4048                 $$ = new CompoundAssign (
4049                         Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
4050           }
4051         | prefixed_unary_expression OP_OR_ASSIGN expression
4052           {
4053                 $$ = new CompoundAssign (
4054                         Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
4055           }
4056         | prefixed_unary_expression OP_XOR_ASSIGN expression
4057           {
4058                 $$ = new CompoundAssign (
4059                         Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
4060           }
4061         ;
4063 lambda_parameter_list
4064         : lambda_parameter
4065           {
4066                 var pars = new List<Parameter> (4);
4067                 pars.Add ((Parameter) $1);
4069                 $$ = pars;
4070           }
4071         | lambda_parameter_list COMMA lambda_parameter
4072           {
4073                 var pars = (List<Parameter>) $1;
4074                 Parameter p = (Parameter)$3;
4075                 if (pars[0].GetType () != p.GetType ()) {
4076                         Report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
4077                 }
4078                 
4079                 pars.Add (p);
4080                 $$ = pars;
4081           }
4082         ;
4084 lambda_parameter
4085         : parameter_modifier parameter_type IDENTIFIER
4086           {
4087                 var lt = (Tokenizer.LocatedToken) $3;
4089                 $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
4090           }
4091         | parameter_type IDENTIFIER
4092           {
4093                 var lt = (Tokenizer.LocatedToken) $2;
4095                 $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
4096           }
4097         | IDENTIFIER
4098           {
4099                 var lt = (Tokenizer.LocatedToken) $1;
4100                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
4101           }
4102         ;
4104 opt_lambda_parameter_list
4105         : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
4106         | lambda_parameter_list         { 
4107                 var pars_list = (List<Parameter>) $1;
4108                 $$ = new ParametersCompiled (compiler, pars_list.ToArray ());
4109           }
4110         ;
4112 lambda_expression_body
4113         : {
4114                 start_block (lexer.Location);
4115           }
4116           expression 
4117           {
4118                 Block b = end_block (lexer.Location);
4119                 b.AddStatement (new ContextualReturn ((Expression) $2));
4120                 $$ = b;
4121           } 
4122         | block { 
4123                 $$ = $1; 
4124           } 
4125         ;
4127 lambda_expression
4128         : IDENTIFIER ARROW 
4129           {
4130                 var lt = (Tokenizer.LocatedToken) $1;
4131                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4132                 start_anonymous (true, new ParametersCompiled (compiler, p), GetLocation ($1));
4133           }
4134           lambda_expression_body
4135           {
4136                 $$ = end_anonymous ((ToplevelBlock) $4);
4137           }
4138         | OPEN_PARENS_LAMBDA
4139           {
4140                 if (RootContext.Version <= LanguageVersion.ISO_2)
4141                         Report.FeatureIsNotAvailable (GetLocation ($1), "lambda expressions");
4142           
4143                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
4144           }
4145           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4146           {
4147                 valid_param_mod = 0;
4148                 start_anonymous (true, (ParametersCompiled) $3, GetLocation ($1));
4149           }
4150           lambda_expression_body 
4151           {
4152                 $$ = end_anonymous ((ToplevelBlock) $7);
4153           }
4154         ;
4156 expression
4157         : assignment_expression 
4158         | non_assignment_expression 
4159         ;
4160         
4161 non_assignment_expression
4162         : conditional_expression
4163         | lambda_expression
4164         | query_expression 
4165         ;
4167 constant_expression
4168         : expression
4169         ;
4171 boolean_expression
4172         : expression
4173           {
4174                 $$ = new BooleanExpression ((Expression) $1);
4175           }
4176         ;
4179 // 10 classes
4181 class_declaration
4182         : opt_attributes
4183           opt_modifiers
4184           opt_partial
4185           CLASS
4186           {
4187                 lexer.ConstraintsParsing = true;
4188           }
4189           type_declaration_name
4190           {
4191                 MemberName name = MakeName ((MemberName) $6);
4192                 push_current_class (new Class (current_namespace, current_class, name, (Modifiers) $2, (Attributes) $1), $3);
4193           }
4194           opt_class_base
4195           opt_type_parameter_constraints_clauses
4196           {
4197                 lexer.ConstraintsParsing = false;
4199                 current_class.SetParameterInfo ((List<Constraints>) $9);
4201                 if (RootContext.Documentation != null) {
4202                         current_container.DocComment = Lexer.consume_doc_comment ();
4203                         Lexer.doc_state = XmlCommentState.Allowed;
4204                 }
4205           }
4206           class_body
4207           {
4208                 --lexer.parsing_declaration;      
4209                 if (RootContext.Documentation != null)
4210                         Lexer.doc_state = XmlCommentState.Allowed;
4211           }
4212           opt_semicolon 
4213           {
4214                 $$ = pop_current_class ();
4215           }
4216         ;       
4218 opt_partial
4219         : /* empty */
4220           { $$ = null; }
4221         | PARTIAL
4222           { $$ = $1; } // location
4223         ;
4225 opt_modifiers
4226         : /* empty */           { $$ = (int) 0; }
4227         | modifiers
4228         ;
4230 modifiers
4231         : modifier
4232         | modifiers modifier
4233           { 
4234                 var m1 = (Modifiers) $1;
4235                 var m2 = (Modifiers) $2;
4237                 if ((m1 & m2) != 0) {
4238                         Location l = lexer.Location;
4239                         Report.Error (1004, l, "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2));
4240                 }
4241                 $$ = m1 | m2;
4242           }
4243         ;
4245 modifier
4246         : NEW
4247           {
4248                 $$ = Modifiers.NEW;
4249                 if (current_container == RootContext.ToplevelTypes)
4250                         Report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements");
4251           }
4252         | PUBLIC                { $$ = Modifiers.PUBLIC; }
4253         | PROTECTED             { $$ = Modifiers.PROTECTED; }
4254         | INTERNAL              { $$ = Modifiers.INTERNAL; }
4255         | PRIVATE               { $$ = Modifiers.PRIVATE; }
4256         | ABSTRACT              { $$ = Modifiers.ABSTRACT; }
4257         | SEALED                { $$ = Modifiers.SEALED; }
4258         | STATIC                { $$ = Modifiers.STATIC; }
4259         | READONLY              { $$ = Modifiers.READONLY; }
4260         | VIRTUAL               { $$ = Modifiers.VIRTUAL; }
4261         | OVERRIDE              { $$ = Modifiers.OVERRIDE; }
4262         | EXTERN                { $$ = Modifiers.EXTERN; }
4263         | VOLATILE              { $$ = Modifiers.VOLATILE; }
4264         | UNSAFE                { $$ = Modifiers.UNSAFE; }
4265         ;
4267 opt_class_base
4268         : /* empty */
4269         | class_base
4270         ;
4272 class_base
4273         : COLON type_list
4274          {
4275                 current_container.AddBasesForPart (current_class, (List<FullNamedExpression>) $2);
4276          }
4277         ;
4279 opt_type_parameter_constraints_clauses
4280         : /* empty */           { $$ = null; }
4281         | type_parameter_constraints_clauses 
4282           {
4283                 $$ = $1;
4284           }
4285         ;
4287 type_parameter_constraints_clauses
4288         : type_parameter_constraints_clause
4289           {
4290                 var constraints = new List<Constraints> (1);
4291                 constraints.Add ((Constraints) $1);
4292                 $$ = constraints;
4293           }
4294         | type_parameter_constraints_clauses type_parameter_constraints_clause
4295           {
4296                 var constraints = (List<Constraints>) $1;
4297                 Constraints new_constraint = (Constraints)$2;
4299                 foreach (Constraints c in constraints) {
4300                         if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) {
4301                                 Report.Error (409, new_constraint.Location,
4302                                         "A constraint clause has already been specified for type parameter `{0}'",
4303                                         new_constraint.TypeParameter.Value);
4304                         }
4305                 }
4307                 constraints.Add (new_constraint);
4308                 $$ = constraints;
4309           }
4310         ; 
4312 type_parameter_constraints_clause
4313         : WHERE IDENTIFIER COLON type_parameter_constraints
4314           {
4315                 var lt = (Tokenizer.LocatedToken) $2;
4316                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List<FullNamedExpression>) $4, GetLocation ($1));
4317           }
4318         ; 
4320 type_parameter_constraints
4321         : type_parameter_constraint
4322           {
4323                 var constraints = new List<FullNamedExpression> (1);
4324                 constraints.Add ((FullNamedExpression) $1);
4325                 $$ = constraints;
4326           }
4327         | type_parameter_constraints COMMA type_parameter_constraint
4328           {
4329                 var constraints = (List<FullNamedExpression>) $1;
4330                 var prev = constraints [constraints.Count - 1] as SpecialContraintExpr;
4331                 if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) {                   
4332                         Report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified");
4333                 }
4334                 
4335                 prev = $3 as SpecialContraintExpr;
4336                 if (prev != null) {
4337                         if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) {
4338                                 Report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified");                 
4339                         } else {
4340                                 prev = constraints [0] as SpecialContraintExpr;
4341                                 if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) {                        
4342                                         Report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint");
4343                                 }
4344                         }
4345                 }
4347                 constraints.Add ((FullNamedExpression) $3);
4348                 $$ = constraints;
4349           }
4350         ;
4352 type_parameter_constraint
4353         : type
4354           {
4355                 if ($1 is ComposedCast)
4356                         Report.Error (706, GetLocation ($1), "Invalid constraint type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
4357           
4358                 $$ = $1;
4359           }
4360         | NEW OPEN_PARENS CLOSE_PARENS
4361           {
4362                 $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1));
4363           }
4364         | CLASS
4365           {
4366                 $$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1));
4367           }
4368         | STRUCT
4369           {
4370                 $$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1));
4371           }
4372         ;
4374 opt_type_parameter_variance
4375         : /* empty */
4376           {
4377                 $$ = Variance.None;
4378           }
4379         | type_parameter_variance
4380           {
4381                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
4382                         Report.FeatureIsNotSupported (lexer.Location, "generic type variance");
4383                 else if (RootContext.Version <= LanguageVersion.V_3)
4384                         Report.FeatureIsNotAvailable (lexer.Location, "generic type variance");
4386                 $$ = $1;
4387           }
4388         ;
4390 type_parameter_variance
4391         : OUT
4392           {
4393                 $$ = Variance.Covariant;
4394           }
4395         | IN
4396           {
4397                 $$ = Variance.Contravariant;
4398           }
4399         ;
4402 // Statements (8.2)
4406 // A block is "contained" on the following places:
4407 //      method_body
4408 //      property_declaration as part of the accessor body (get/set)
4409 //      operator_declaration
4410 //      constructor_declaration
4411 //      destructor_declaration
4412 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
4413 //      
4414 block
4415         : OPEN_BRACE  
4416           {
4417                 ++lexer.parsing_block;
4418                 start_block (GetLocation ($1));
4419           } 
4420           opt_statement_list block_end
4421           {
4422                 $$ = $4;
4423           }
4424         ;
4426 block_end 
4427         : CLOSE_BRACE 
4428           {
4429                 --lexer.parsing_block;
4430                 $$ = end_block (GetLocation ($1));
4431           }
4432         | COMPLETE_COMPLETION
4433           {
4434                 --lexer.parsing_block;
4435                 $$ = end_block (lexer.Location);
4436           }
4437         ;
4440 block_prepared
4441         : OPEN_BRACE
4442           {
4443                 ++lexer.parsing_block;
4444                 current_block.StartLocation = GetLocation ($1);
4445           }
4446           opt_statement_list CLOSE_BRACE 
4447           {
4448                 --lexer.parsing_block;
4449                 $$ = end_block (GetLocation ($4));
4450           }
4451         ;
4453 opt_statement_list
4454         : /* empty */
4455         | statement_list 
4456         ;
4458 statement_list
4459         : statement
4460         | statement_list statement
4461         ;
4463 statement
4464         : declaration_statement
4465           {
4466                 if ($1 != null && (Block) $1 != current_block){
4467                         current_block.AddStatement ((Statement) $1);
4468                         current_block = (Block) $1;
4469                 }
4470           }
4471         | valid_declaration_statement
4472           {
4473                 current_block.AddStatement ((Statement) $1);
4474           }
4475         | labeled_statement
4476         ;
4479 // The interactive_statement and its derivatives are only 
4480 // used to provide a special version of `expression_statement'
4481 // that has a side effect of assigning the expression to
4482 // $retval
4484 interactive_statement_list
4485         : interactive_statement
4486         | interactive_statement_list interactive_statement
4487         ;
4489 interactive_statement
4490         : declaration_statement
4491           {
4492                 if ($1 != null && (Block) $1 != current_block){
4493                         current_block.AddStatement ((Statement) $1);
4494                         current_block = (Block) $1;
4495                 }
4496           }
4497         | interactive_valid_declaration_statement
4498           {
4499                 current_block.AddStatement ((Statement) $1);
4500           }
4501         | labeled_statement
4502         ;
4504 valid_declaration_statement
4505         : block
4506         | empty_statement
4507         | expression_statement
4508         | selection_statement
4509         | iteration_statement
4510         | jump_statement                  
4511         | try_statement
4512         | checked_statement
4513         | unchecked_statement
4514         | lock_statement
4515         | using_statement
4516         | unsafe_statement
4517         | fixed_statement
4518         ;
4520 interactive_valid_declaration_statement
4521         : block
4522         | empty_statement
4523         | interactive_expression_statement
4524         | selection_statement
4525         | iteration_statement
4526         | jump_statement                  
4527         | try_statement
4528         | checked_statement
4529         | unchecked_statement
4530         | lock_statement
4531         | using_statement
4532         | unsafe_statement
4533         | fixed_statement
4534         ;
4536 embedded_statement
4537         : valid_declaration_statement
4538         | declaration_statement
4539           {
4540                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4541                   $$ = null;
4542           }
4543         | labeled_statement
4544           {
4545                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4546                   $$ = null;
4547           }
4548         ;
4550 empty_statement
4551         : SEMICOLON
4552           {
4553                 $$ = new EmptyStatement (GetLocation ($1));
4554           }
4555         ;
4557 labeled_statement
4558         : IDENTIFIER COLON 
4559           {
4560                 var lt = (Tokenizer.LocatedToken) $1;
4561                 LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location);
4563                 if (current_block.AddLabel (labeled))
4564                         current_block.AddStatement (labeled);
4565           }
4566           statement
4567         ;
4569 declaration_statement
4570         : local_variable_declaration SEMICOLON
4571           {
4572                 if ($1 != null){
4573                         var de = (Tuple<FullNamedExpression, List<object>>) $1;
4574                         $$ = declare_local_variables (de.Item1, de.Item2, de.Item1.Location);
4575                 }
4576           }
4578         | local_constant_declaration SEMICOLON
4579           {
4580                 if ($1 != null){
4581                         var de = (Tuple<FullNamedExpression, List<object>>) $1;
4583                         $$ = declare_local_constants (de.Item1, de.Item2);
4584                 }
4585           }
4586         ;
4588 /* 
4589  * The following is from Rhys' grammar:
4590  * > Types in local variable declarations must be recognized as 
4591  * > expressions to prevent reduce/reduce errors in the grammar.
4592  * > The expressions are converted into types during semantic analysis.
4593  */
4594 variable_type
4595         : primary_expression_no_array_creation opt_rank_specifier_or_nullable
4596           { 
4597                 // FIXME: Do something smart here regarding the composition of the type.
4599                 // Ok, the above "primary_expression" is there to get rid of
4600                 // both reduce/reduce and shift/reduces in the grammar, it should
4601                 // really just be "type_name".  If you use type_name, a reduce/reduce
4602                 // creeps up.  If you use namespace_or_type_name (which is all we need
4603                 // really) two shift/reduces appear.
4604                 // 
4606                 // So the super-trick is that primary_expression
4607                 // can only be either a SimpleName or a MemberAccess. 
4608                 // The MemberAccess case arises when you have a fully qualified type-name like :
4609                 // Foo.Bar.Blah i;
4610                 // SimpleName is when you have
4611                 // Blah i;
4612                 
4613                 Expression expr = (Expression) $1;
4614                 string rank_or_nullable = (string) $2;
4615                 
4616                 if (expr is ComposedCast){
4617                         $$ = new ComposedCast ((ComposedCast)expr, rank_or_nullable);
4618                 } else if (expr is ATypeNameExpression){
4619                         //
4620                         // So we extract the string corresponding to the SimpleName
4621                         // or MemberAccess
4622                         //
4623                         if (rank_or_nullable.Length == 0) {
4624                                 SimpleName sn = expr as SimpleName;
4625                                 if (sn != null && sn.Name == "var")
4626                                         $$ = new VarExpr (sn.Location);
4627                                 else
4628                                         $$ = $1;
4629                         } else {
4630                                 $$ = new ComposedCast ((ATypeNameExpression)expr, rank_or_nullable);
4631                         }
4632                 } else {
4633                         Error_ExpectingTypeName (expr);
4634                         $$ = TypeManager.system_object_expr;
4635                 }
4636           }
4637         | builtin_types opt_rank_specifier_or_nullable
4638           {
4639                 if ((string) $2 == "")
4640                         $$ = $1;
4641                 else
4642                         $$ = new ComposedCast ((FullNamedExpression) $1, (string) $2, lexer.Location);
4643           }
4644         | VOID opt_rank_specifier
4645           {
4646                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report);
4647                 $$ = TypeManager.system_void_expr;
4648           }
4649         ;
4651 local_variable_pointer_type
4652         : primary_expression_no_array_creation STAR
4653           {
4654                 ATypeNameExpression expr = $1 as ATypeNameExpression;
4656                 if (expr != null) {
4657                         $$ = new ComposedCast (expr, "*");
4658                 } else {
4659                         Error_ExpectingTypeName ((Expression)$1);
4660                         $$ = expr;
4661                 }
4662           }
4663         | builtin_types STAR
4664           {
4665                 $$ = new ComposedCast ((FullNamedExpression) $1, "*", GetLocation ($1));
4666           }
4667         | VOID STAR
4668           {
4669                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", GetLocation ($1));
4670           }
4671         | local_variable_pointer_type STAR
4672           {
4673                 $$ = new ComposedCast ((FullNamedExpression) $1, "*");
4674           }
4675         ;
4677 local_variable_type
4678         : variable_type
4679         | local_variable_pointer_type opt_rank_specifier
4680           {
4681                 if ($1 != null){
4682                         string rank = (string)$2;
4684                         if (rank == "")
4685                                 $$ = $1;
4686                         else
4687                                 $$ = new ComposedCast ((FullNamedExpression) $1, rank);
4688                 } else {
4689                         $$ = null;
4690                 }
4691           }
4692         ;
4694 local_variable_declaration
4695         : local_variable_type local_variable_declarators
4696           {
4697                 if ($1 != null) {
4698                         VarExpr ve = $1 as VarExpr;
4699                         if (ve != null) {
4700                                 if (!((VariableDeclaration) ((List<object>)$2) [0]).HasInitializer)
4701                                         ve.VariableInitializersCount = 0;
4702                                 else
4703                                         ve.VariableInitializersCount = ((List<object>)$2).Count;
4704                         }
4705                                 
4706                         $$ = new Tuple<FullNamedExpression, List<object>> ((FullNamedExpression) $1, (List<object>) $2);
4707                 } else
4708                         $$ = null;
4709           }
4710         ;
4712 local_constant_declaration
4713         : CONST variable_type constant_declarators
4714           {
4715                 if ($2 != null)
4716                         $$ = new Tuple<FullNamedExpression, List<object>> ((FullNamedExpression) $2, (List<object>) $3);
4717                 else
4718                         $$ = null;
4719           }
4720         ;
4722 expression_statement
4723         : statement_expression SEMICOLON { $$ = $1; }
4724         | statement_expression COMPLETE_COMPLETION { $$ = $1; }
4725         ;
4727 interactive_expression_statement
4728         : interactive_statement_expression SEMICOLON { $$ = $1; }
4729         | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; }
4730         ;
4732         //
4733         // We have to do the wrapping here and not in the case above,
4734         // because statement_expression is used for example in for_statement
4735         //
4736 statement_expression
4737         : expression
4738           {
4739                 ExpressionStatement s = $1 as ExpressionStatement;
4740                 if (s == null) {
4741                         Expression.Error_InvalidExpressionStatement (Report, GetLocation ($1));
4742                         s = EmptyExpressionStatement.Instance;
4743                 }
4745                 $$ = new StatementExpression (s);
4746           }
4747         | error
4748           {
4749                 Error_SyntaxError (yyToken);
4750                 $$ = null;
4751           }
4752         ;
4754 interactive_statement_expression
4755         : expression
4756           {
4757                 Expression expr = (Expression) $1;
4758                 ExpressionStatement s;
4760                 s = new OptionalAssign (new SimpleName ("$retval", lexer.Location), expr, lexer.Location);
4761                 $$ = new StatementExpression (s);
4762           }
4763         | error
4764           {
4765                 Error_SyntaxError (yyToken);
4766                 $$ = new EmptyStatement (GetLocation ($1));
4767           }
4768         ;
4769         
4770 selection_statement
4771         : if_statement
4772         | switch_statement
4773         ; 
4775 if_statement
4776         : IF open_parens_any boolean_expression CLOSE_PARENS 
4777           embedded_statement
4778           { 
4779                 if ($5 is EmptyStatement)
4780                         Report.Warning (642, 3, GetLocation ($5), "Possible mistaken empty statement");
4781                 
4782                 $$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
4783           }
4784         | IF open_parens_any boolean_expression CLOSE_PARENS
4785           embedded_statement ELSE embedded_statement
4786           {
4787                 $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1));
4789                 if ($5 is EmptyStatement)
4790                         Report.Warning (642, 3, GetLocation ($5), "Possible mistaken empty statement");
4791                 if ($7 is EmptyStatement)
4792                         Report.Warning (642, 3, GetLocation ($7), "Possible mistaken empty statement");
4793           }
4794         ;
4796 switch_statement
4797         : SWITCH open_parens_any
4798           { 
4799                 if (switch_stack == null)
4800                         switch_stack = new Stack<Block> (2);
4801                 switch_stack.Push (current_block);
4802           }
4803           expression CLOSE_PARENS 
4804           switch_block
4805           {
4806                 $$ = new Switch ((Expression) $4, (List<SwitchSection>) $6, GetLocation ($1));
4807                 current_block = (Block) switch_stack.Pop ();
4808           }
4809         ;
4811 switch_block
4812         : OPEN_BRACE
4813           opt_switch_sections
4814           CLOSE_BRACE
4815           {
4816                 $$ = $2;
4817           }
4818         ;
4820 opt_switch_sections
4821         : /* empty */           
4822           {
4823                 Report.Warning (1522, 1, lexer.Location, "Empty switch block"); 
4824                 $$ = new List<SwitchSection> ();
4825           }
4826         | switch_sections
4827         ;
4829 switch_sections
4830         : switch_section 
4831           {
4832                 var sections = new List<SwitchSection> (4);
4834                 sections.Add ((SwitchSection) $1);
4835                 $$ = sections;
4836           }
4837         | switch_sections switch_section
4838           {
4839                 var sections = (List<SwitchSection>) $1;
4841                 sections.Add ((SwitchSection) $2);
4842                 $$ = sections;
4843           }
4844         ;
4846 switch_section
4847         : switch_labels
4848           {
4849                 current_block = current_block.CreateSwitchBlock (lexer.Location);
4850           }
4851           statement_list 
4852           {
4853                 $$ = new SwitchSection ((List<SwitchLabel>) $1, current_block.Explicit);
4854           }
4855         ;
4857 switch_labels
4858         : switch_label 
4859           {
4860                 var labels = new List<SwitchLabel> (4);
4862                 labels.Add ((SwitchLabel) $1);
4863                 $$ = labels;
4864           }
4865         | switch_labels switch_label 
4866           {
4867                 var labels = (List<SwitchLabel>) ($1);
4868                 labels.Add ((SwitchLabel) $2);
4870                 $$ = labels;
4871           }
4872         ;
4874 switch_label
4875         : CASE constant_expression COLON
4876          {
4877                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
4878          }
4879         | DEFAULT_COLON
4880           {
4881                 $$ = new SwitchLabel (null, GetLocation ($1));
4882           }
4883         ;
4885 iteration_statement
4886         : while_statement
4887         | do_statement
4888         | for_statement
4889         | foreach_statement
4890         ;
4892 while_statement
4893         : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement
4894           {
4895                 Location l = GetLocation ($1);
4896                 $$ = new While ((BooleanExpression) $3, (Statement) $5, l);
4897           }
4898         ;
4900 do_statement
4901         : DO embedded_statement 
4902           WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
4903           {
4904                 Location l = GetLocation ($1);
4906                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, l);
4907           }
4908         ;
4910 for_statement
4911         : FOR open_parens_any opt_for_initializer SEMICOLON
4912           {
4913                 Location l = lexer.Location;
4914                 start_block (l);  
4915                 Block assign_block = current_block;
4917                 if ($3 is Tuple<FullNamedExpression, List<object>>){
4918                         var de = (Tuple<FullNamedExpression, List<object>>) $3;
4919                         
4920                         var type = de.Item1;
4922                         foreach (VariableDeclaration decl in de.Item2){
4924                                 LocalInfo vi;
4926                                 vi = current_block.AddVariable (type, decl.identifier, decl.Location);
4927                                 if (vi == null)
4928                                         continue;
4930                                 Expression expr = decl.GetInitializer (type);
4931                                         
4932                                 LocalVariableReference var;
4933                                 var = new LocalVariableReference (assign_block, decl.identifier, l);
4935                                 if (expr != null) {
4936                                         Assign a = new SimpleAssign (var, expr, decl.Location);
4937                                         
4938                                         assign_block.AddStatement (new StatementExpression (a));
4939                                 }
4940                         }
4941                         
4942                         // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal.
4943                         // This can be referred to as $5 below.
4944                         $$ = null;
4945                 } else {
4946                         $$ = $3;
4947                 }
4948           } 
4949           opt_for_condition SEMICOLON
4950           opt_for_iterator CLOSE_PARENS 
4951           embedded_statement
4952           {
4953                 Location l = GetLocation ($1);
4955                 For f = new For ((Statement) $5, (BooleanExpression) $6, (Statement) $8, (Statement) $10, l);
4957                 current_block.AddStatement (f);
4959                 $$ = end_block (lexer.Location);
4960           }
4961         ;
4963 opt_for_initializer
4964         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
4965         | for_initializer       
4966         ;
4968 for_initializer
4969         : local_variable_declaration
4970         | statement_expression_list
4971         ;
4973 opt_for_condition
4974         : /* empty */           { $$ = null; }
4975         | boolean_expression
4976         ;
4978 opt_for_iterator
4979         : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
4980         | for_iterator
4981         ;
4983 for_iterator
4984         : statement_expression_list
4985         ;
4987 statement_expression_list
4988         : statement_expression  
4989           {
4990                 // CHANGE: was `null'
4991                 Statement s = (Statement) $1;
4992                 Block b = new Block (current_block, s.loc, lexer.Location);   
4994                 b.AddStatement (s);
4995                 $$ = b;
4996           }
4997         | statement_expression_list COMMA statement_expression
4998           {
4999                 Block b = (Block) $1;
5001                 b.AddStatement ((Statement) $3);
5002                 $$ = $1;
5003           }
5004         ;
5006 foreach_statement
5007         : FOREACH open_parens_any type IN expression CLOSE_PARENS
5008           {
5009                 Report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement");
5010                 $$ = null;
5011           }
5012         | FOREACH open_parens_any type IDENTIFIER IN
5013           expression CLOSE_PARENS 
5014           {
5015                 start_block (lexer.Location);
5016                 Block foreach_block = current_block;
5018                 var lt = (Tokenizer.LocatedToken) $4;
5019                 Location l = lt.Location;
5020                 LocalInfo vi = foreach_block.AddVariable ((Expression) $3, lt.Value, l);
5021                 if (vi != null) {
5022                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach);
5024                         // Get a writable reference to this read-only variable.
5025                         //
5026                         // Note that the $$ here refers to the value of _this_ code block,
5027                         // not the value of the LHS non-terminal.  This can be referred to as $8 below.
5028                         $$ = new LocalVariableReference (foreach_block, lt.Value, l, vi, false);
5029                 } else {
5030                         $$ = null;
5031                 }
5032           } 
5033           embedded_statement 
5034           {
5035                 LocalVariableReference v = (LocalVariableReference) $8;
5036                 Location l = GetLocation ($1);
5038                 if (v != null) {
5039                         Foreach f = new Foreach ((Expression) $3, v, (Expression) $6, (Statement) $9, l);
5040                         current_block.AddStatement (f);
5041                 }
5043                 $$ = end_block (lexer.Location);
5044           }
5045         ;
5047 jump_statement
5048         : break_statement
5049         | continue_statement
5050         | goto_statement
5051         | return_statement
5052         | throw_statement
5053         | yield_statement
5054         ;
5056 break_statement
5057         : BREAK SEMICOLON
5058           {
5059                 $$ = new Break (GetLocation ($1));
5060           }
5061         ;
5063 continue_statement
5064         : CONTINUE SEMICOLON
5065           {
5066                 $$ = new Continue (GetLocation ($1));
5067           }
5068         ;
5070 goto_statement
5071         : GOTO IDENTIFIER SEMICOLON 
5072           {
5073                 var lt = (Tokenizer.LocatedToken) $2;
5074                 $$ = new Goto (lt.Value, lt.Location);
5075           }
5076         | GOTO CASE constant_expression SEMICOLON
5077           {
5078                 $$ = new GotoCase ((Expression) $3, GetLocation ($1));
5079           }
5080         | GOTO DEFAULT SEMICOLON 
5081           {
5082                 $$ = new GotoDefault (GetLocation ($1));
5083           }
5084         ; 
5086 return_statement
5087         : RETURN opt_expression SEMICOLON
5088           {
5089                 $$ = new Return ((Expression) $2, GetLocation ($1));
5090           }
5091         ;
5093 throw_statement
5094         : THROW opt_expression SEMICOLON
5095           {
5096                 $$ = new Throw ((Expression) $2, GetLocation ($1));
5097           }
5098         ;
5100 yield_statement 
5101         : IDENTIFIER RETURN expression SEMICOLON
5102           {
5103                 var lt = (Tokenizer.LocatedToken) $1;
5104                 string s = lt.Value;
5105                 if (s != "yield"){
5106                         Report.Error (1003, lt.Location, "; expected");
5107                         $$ = null;
5108                 }
5109                 if (RootContext.Version == LanguageVersion.ISO_1){
5110                         Report.FeatureIsNotAvailable (lt.Location, "yield statement");
5111                         $$ = null;
5112                 }
5113                 current_block.Toplevel.IsIterator = true;
5114                 $$ = new Yield ((Expression) $3, lt.Location); 
5115           }
5116         | IDENTIFIER RETURN SEMICOLON
5117           {
5118                 Report.Error (1627, GetLocation ($2), "Expression expected after yield return");
5119                 $$ = null;
5120           }
5121         | IDENTIFIER BREAK SEMICOLON
5122           {
5123                 var lt = (Tokenizer.LocatedToken) $1;
5124                 string s = lt.Value;
5125                 if (s != "yield"){
5126                         Report.Error (1003, lt.Location, "; expected");
5127                         $$ = null;
5128                 }
5129                 if (RootContext.Version == LanguageVersion.ISO_1){
5130                         Report.FeatureIsNotAvailable (lt.Location, "yield statement");
5131                         $$ = null;
5132                 }
5133                 
5134                 current_block.Toplevel.IsIterator = true;
5135                 $$ = new YieldBreak (lt.Location);
5136           }
5137         ;
5139 opt_expression
5140         : /* empty */
5141         | expression
5142         ;
5144 try_statement
5145         : TRY block catch_clauses
5146           {
5147                 $$ = new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), false);
5148           }
5149         | TRY block FINALLY block
5150           {
5151                 $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1));
5152           }
5153         | TRY block catch_clauses FINALLY block
5154           {
5155                 $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), true), (Block) $5, GetLocation ($1));
5156           }
5157         | TRY block error 
5158           {
5159                 Report.Error (1524, GetLocation ($1), "Expected catch or finally");
5160                 $$ = null;
5161           }
5162         ;
5164 catch_clauses
5165         : catch_clause 
5166           {
5167                 var l = new List<Catch> (2);
5169                 l.Add ((Catch) $1);
5170                 $$ = l;
5171           }
5172         | catch_clauses catch_clause
5173           {
5174                 var l = (List<Catch>) $1;
5175                 
5176                 Catch c = (Catch) $2;
5177                 if (l [0].IsGeneral) {
5178                         Report.Error (1017, c.loc, "Try statement already has an empty catch block");
5179                 } else {
5180                         if (c.IsGeneral)
5181                                 l.Insert (0, c);
5182                         else
5183                                 l.Add (c);
5184                 }
5185                 
5186                 $$ = l;
5187           }
5188         ;
5190 opt_identifier
5191         : /* empty */   { $$ = null; }
5192         | IDENTIFIER
5193         ;
5195 catch_clause 
5196         : CATCH opt_catch_args 
5197           {
5198                 if ($2 != null) {
5199                         var cc = (Tuple<FullNamedExpression, Tokenizer.LocatedToken>) $2;
5200                         var lt = cc.Item2;
5202                         if (lt != null){
5203                                 List<object> one = new List<object> (1);
5205                                 one.Add (new VariableDeclaration (lt, null));
5207                                 start_block (lexer.Location);
5208                                 current_block = declare_local_variables (cc.Item1, one, lt.Location);
5209                         }
5210                 }
5211           } block {
5212                 Expression type = null;
5213                 string id = null;
5214                 Block var_block = null;
5216                 if ($2 != null){
5217                         var cc = (Tuple<FullNamedExpression, Tokenizer.LocatedToken>) $2;
5218                         type = cc.Item1;
5219                         var lt = cc.Item2;
5221                         if (lt != null){
5222                                 id = lt.Value;
5223                                 var_block = end_block (lexer.Location);
5224                         }
5225                 }
5227                 $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc);
5228           }
5229         ;
5231 opt_catch_args
5232         : /* empty */ { $$ = null; }
5233         | catch_args
5234         ;         
5236 catch_args 
5237         : open_parens_any type opt_identifier CLOSE_PARENS 
5238           {
5239                 $$ = new Tuple<FullNamedExpression, Tokenizer.LocatedToken> ((FullNamedExpression)$2, (Tokenizer.LocatedToken) $3);
5240           }
5241         | open_parens_any CLOSE_PARENS 
5242           {
5243                 Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected");
5244                 $$ = null;
5245           }
5246         ;
5248 checked_statement
5249         : CHECKED block
5250           {
5251                 $$ = new Checked ((Block) $2);
5252           }
5253         ;
5255 unchecked_statement
5256         : UNCHECKED block
5257           {
5258                 $$ = new Unchecked ((Block) $2);
5259           }
5260         ;
5262 unsafe_statement
5263         : UNSAFE 
5264           {
5265                 RootContext.CheckUnsafeOption (GetLocation ($1), Report);
5266           } block {
5267                 $$ = new Unsafe ((Block) $3);
5268           }
5269         ;
5271 fixed_statement
5272         : FIXED open_parens_any 
5273           type_and_void fixed_pointer_declarators 
5274           CLOSE_PARENS
5275           {
5276                 start_block (lexer.Location);
5277           }
5278           embedded_statement 
5279           {
5280                 Expression type = (Expression) $3;
5281                 var list = (List<KeyValuePair<Tokenizer.LocatedToken, Expression>>) $4;
5282                 Fixed f = new Fixed (type,
5283                         list.ConvertAll (i => {
5284                                 var v = new KeyValuePair<LocalInfo, Expression> (current_block.AddVariable (type, i.Key.Value, i.Key.Location), i.Value);
5285                                 if (v.Key != null) {
5286                                         v.Key.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
5287                                         v.Key.Pinned = true;
5288                                 }
5289                                 return v;
5290                         }), (Statement) $7, GetLocation ($1));
5292                 current_block.AddStatement (f);
5294                 $$ = end_block (lexer.Location);
5295           }
5296         ;
5298 fixed_pointer_declarators
5299         : fixed_pointer_declarator      { 
5300                 var declarators = new List<KeyValuePair<Tokenizer.LocatedToken, Expression>> (2);
5301                 if ($1 != null)
5302                         declarators.Add ((KeyValuePair<Tokenizer.LocatedToken, Expression>)$1);
5303                 $$ = declarators;
5304           }
5305         | fixed_pointer_declarators COMMA fixed_pointer_declarator
5306           {
5307                 var declarators = (List<KeyValuePair<Tokenizer.LocatedToken, Expression>>) $1;
5308                 if ($3 != null)
5309                         declarators.Add ((KeyValuePair<Tokenizer.LocatedToken, Expression>)$3);
5310                 $$ = declarators;
5311           }
5312         ;
5314 fixed_pointer_declarator
5315         : IDENTIFIER ASSIGN expression
5316           {
5317                 var lt = (Tokenizer.LocatedToken) $1;
5318                 $$ = new KeyValuePair<Tokenizer.LocatedToken, Expression> (lt, (Expression) $3);
5319           }
5320         | IDENTIFIER
5321           {
5322                 Report.Error (210, ((Tokenizer.LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration");
5323                 $$ = null;
5324           }
5325         ;
5327 lock_statement
5328         : LOCK open_parens_any expression CLOSE_PARENS 
5329           {
5330                 //
5331           } 
5332           embedded_statement
5333           {
5334                 $$ = new Lock ((Expression) $3, (Statement) $6, GetLocation ($1));
5335           }
5336         ;
5338 using_statement
5339         : USING open_parens_any local_variable_declaration CLOSE_PARENS
5340           {
5341                 start_block (lexer.Location);
5342                 Block assign_block = current_block;
5344                 var de = (Tuple<FullNamedExpression, List<object>>) $3;
5345                 Location l = GetLocation ($1);
5347                 var vars = new Stack<Tuple<LocalVariableReference, Expression>> ();
5349                 foreach (VariableDeclaration decl in de.Item2) {
5350                         LocalInfo vi = current_block.AddVariable (de.Item1, decl.identifier, decl.Location);
5351                         if (vi == null)
5352                                 continue;
5353                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
5355                         Expression expr = decl.GetInitializer (de.Item1);
5356                         if (expr == null) {
5357                                 Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
5358                                 continue;
5359                         }
5360                         LocalVariableReference var;
5362                         // Get a writable reference to this read-only variable.
5363                         var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
5365                         // This is so that it is not a warning on using variables
5366                         vi.Used = true;
5368                         vars.Push (new Tuple<LocalVariableReference, Expression> (var, expr));
5370                         // Assign a = new SimpleAssign (var, expr, decl.Location);
5371                         // assign_block.AddStatement (new StatementExpression (a));
5372                 }
5374                 // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
5375                 // It can be referred to as $5 below.
5376                 $$ = vars;
5377           }
5378           embedded_statement
5379           {
5380                 Statement stmt = (Statement) $6;
5381                 var vars = (Stack<Tuple<LocalVariableReference, Expression>>) $5;
5382                 Location l = GetLocation ($1);
5384                 while (vars.Count > 0) {
5385                           var de = vars.Pop ();
5386                           stmt = new Using (de.Item1, de.Item2, stmt, l);
5387                 }
5388                 current_block.AddStatement (stmt);
5389                 $$ = end_block (lexer.Location);
5390           }
5391         | USING open_parens_any expression CLOSE_PARENS
5392           {
5393                 start_block (lexer.Location);
5394           }
5395           embedded_statement
5396           {
5397                 current_block.AddStatement (new UsingTemporary ((Expression) $3, (Statement) $6, GetLocation ($1)));
5398                 $$ = end_block (lexer.Location);
5399           }
5400         ; 
5403 // LINQ
5405 query_expression
5406         : first_from_clause query_body 
5407           {
5408                 lexer.query_parsing = false;
5409                         
5410                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5411                         
5412                 from.Tail.Next = (Linq.AQueryClause)$2;
5413                 $$ = from;
5414                 
5415                 current_block.SetEndLocation (lexer.Location);
5416                 current_block = current_block.Parent;
5417           }
5418         | nested_from_clause query_body
5419           {
5420                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5421                         
5422                 from.Tail.Next = (Linq.AQueryClause)$2;
5423                 $$ = from;
5424                 
5425                 current_block.SetEndLocation (lexer.Location);
5426                 current_block = current_block.Parent;
5427           }     
5429         // Bubble up COMPLETE_COMPLETION productions
5430         | first_from_clause COMPLETE_COMPLETION {
5431                 lexer.query_parsing = false;
5432                 $$ = $1;
5434                 current_block.SetEndLocation (lexer.Location);
5435                 current_block = current_block.Parent;
5436           }
5437         | nested_from_clause COMPLETE_COMPLETION {
5438                 $$ = $1;
5439                 current_block.SetEndLocation (lexer.Location);
5440                 current_block = current_block.Parent;
5441           }
5442         ;
5443         
5444 first_from_clause
5445         : FROM_FIRST IDENTIFIER IN expression
5446           {
5447                 $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4));
5448                 var lt = (Tokenizer.LocatedToken) $2;
5449                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5450           }
5451         | FROM_FIRST type IDENTIFIER IN expression
5452           {
5453                 var lt = (Tokenizer.LocatedToken) $3;
5454                 $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5));
5455                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5456           }
5457         ;
5459 nested_from_clause
5460         : FROM IDENTIFIER IN expression
5461           {
5462                 $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4));
5463                 var lt = (Tokenizer.LocatedToken) $2;
5464                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5465           }
5466         | FROM type IDENTIFIER IN expression
5467           {
5468                 $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5));
5469                 var lt = (Tokenizer.LocatedToken) $3;
5470                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5471           }
5472         ;
5473         
5474 from_clause
5475         : FROM IDENTIFIER IN
5476           {
5477                 current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1));
5478           }
5479           expression
5480           {
5481                 var lt = (Tokenizer.LocatedToken) $2;
5482                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5483                 $$ = new Linq.SelectMany (current_block.Toplevel, sn, (Expression)$5);
5484                 
5485                 current_block.SetEndLocation (lexer.Location);
5486                 current_block = current_block.Parent;
5487                 
5488                 ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5489           }       
5490         | FROM type IDENTIFIER IN
5491           {
5492                 current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1));
5493           }
5494           expression
5495           {
5496                 var lt = (Tokenizer.LocatedToken) $3;
5497                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5499                 FullNamedExpression type = (FullNamedExpression)$2;
5500                 
5501                 $$ = new Linq.SelectMany (current_block.Toplevel, sn, new Linq.Cast (type, (FullNamedExpression)$6));
5502                 
5503                 current_block.SetEndLocation (lexer.Location);
5504                 current_block = current_block.Parent;
5505                 
5506                 ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5507           }
5508         ;       
5510 query_body
5511         : opt_query_body_clauses select_or_group_clause opt_query_continuation 
5512           {
5513                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5514                 
5515                 if ($3 != null)
5516                         head.Next = (Linq.AQueryClause)$3;
5517                                 
5518                 if ($1 != null) {
5519                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5520                         clause.Tail.Next = head;
5521                         head = clause;
5522                 }
5523                 
5524                 $$ = head;
5525           }
5526         | opt_query_body_clauses COMPLETE_COMPLETION
5527         ;
5528         
5529 select_or_group_clause
5530         : SELECT
5531           {
5532                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5533           }
5534           expression
5535           {
5536                 $$ = new Linq.Select (current_block.Toplevel, (Expression)$3, GetLocation ($1));
5538                 current_block.SetEndLocation (lexer.Location);
5539                 current_block = current_block.Parent;
5540           }
5541         | GROUP
5542           {
5543                 if (linq_clause_blocks == null)
5544                         linq_clause_blocks = new Stack<Block> ();
5545                         
5546                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5547                 linq_clause_blocks.Push (current_block);
5548           }
5549           expression
5550           {
5551                 current_block.SetEndLocation (lexer.Location);
5552                 current_block = current_block.Parent;
5553           
5554                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5555           }
5556           BY expression
5557           {
5558                 $$ = new Linq.GroupBy (current_block.Toplevel, (Expression)$3, (ToplevelBlock) linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1));
5559                 
5560                 current_block.SetEndLocation (lexer.Location);
5561                 current_block = current_block.Parent;
5562           }
5563         ;
5564         
5565 opt_query_body_clauses
5566         : /* empty */
5567         | query_body_clauses
5568         ;
5569         
5570 query_body_clauses
5571         : query_body_clause
5572         | query_body_clauses query_body_clause
5573           {
5574                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
5575                 $$ = $1;
5576           }
5577         ;
5578         
5579 query_body_clause
5580         : from_clause
5581         | let_clause 
5582         | where_clause
5583         | join_clause
5584         | orderby_clause
5585         ;
5586         
5587 let_clause
5588         : LET IDENTIFIER ASSIGN 
5589           {
5590                 current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1));
5591           }
5592           expression
5593           {
5594                 var lt = (Tokenizer.LocatedToken) $2;
5595                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5596                 $$ = new Linq.Let (current_block.Toplevel, current_container, sn, (Expression)$5);
5597                 
5598                 current_block.SetEndLocation (lexer.Location);
5599                 current_block = current_block.Parent;
5600                 
5601                 ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5602           }
5603         ;
5605 where_clause
5606         : WHERE
5607           {
5608                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5609           }
5610           boolean_expression
5611           {
5612                 $$ = new Linq.Where (current_block.Toplevel, (BooleanExpression)$3, GetLocation ($1));
5614                 current_block.SetEndLocation (lexer.Location);
5615                 current_block = current_block.Parent;
5616           }
5617         ;
5618         
5619 join_clause
5620         : JOIN IDENTIFIER IN
5621           {
5622                 if (linq_clause_blocks == null)
5623                         linq_clause_blocks = new Stack<Block> ();
5624                         
5625                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5626                 linq_clause_blocks.Push (current_block);
5627           }
5628           expression ON
5629           {
5630                 current_block.SetEndLocation (lexer.Location);
5631                 current_block = current_block.Parent;
5633                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5634                 linq_clause_blocks.Push (current_block);
5635           }
5636           expression EQUALS
5637           {
5638                 current_block.AddStatement (new ContextualReturn ((Expression) $8));
5639                 current_block.SetEndLocation (lexer.Location);
5640                 current_block = current_block.Parent;
5642                 var lt = (Tokenizer.LocatedToken) $2;
5643                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), lexer.Location);
5644           }
5645           expression opt_join_into
5646           {
5647                 var lt = (Tokenizer.LocatedToken) $2;
5648                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5649                 SimpleMemberName sn2 = null;
5650                 
5651                 ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop ();
5652                 ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop ();
5654                 if ($12 == null) {
5655                         $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, current_block.Toplevel, GetLocation ($1));
5656                 } else {
5657                         var lt2 = (Tokenizer.LocatedToken) $12;
5658                         sn2 = new SimpleMemberName (lt2.Value, lt2.Location);
5659                         $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, current_block.Toplevel,
5660                                 sn2, GetLocation ($1));
5661                 }
5663                 current_block.AddStatement (new ContextualReturn ((Expression) $11));
5664                 current_block.SetEndLocation (lexer.Location);
5665                 current_block = current_block.Parent;
5666                         
5667                 if (sn2 == null)
5668                         ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5669                 else
5670                         ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2);
5671           }
5672         | JOIN type IDENTIFIER IN
5673           {
5674                 if (linq_clause_blocks == null)
5675                         linq_clause_blocks = new Stack<Block> ();
5676                         
5677                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5678                 linq_clause_blocks.Push (current_block);
5679           }
5680           expression ON
5681           {
5682                 current_block.SetEndLocation (lexer.Location);
5683                 current_block = current_block.Parent;
5685                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5686                 linq_clause_blocks.Push (current_block);
5687           }
5688           expression EQUALS
5689           {
5690                 current_block.AddStatement (new ContextualReturn ((Expression) $9));
5691                 current_block.SetEndLocation (lexer.Location);
5692                 current_block = current_block.Parent;
5694                 var lt = (Tokenizer.LocatedToken) $3;
5695                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), lexer.Location);
5696           }
5697           expression opt_join_into
5698           {
5699                 var lt = (Tokenizer.LocatedToken) $3;
5700                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5701                 SimpleMemberName sn2 = null;
5702                 ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop ();
5703                 ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop ();
5704                 
5705                 Linq.Cast cast = new Linq.Cast ((FullNamedExpression)$2, (Expression)$6);
5706                 if ($13 == null) {
5707                         $$ = new Linq.Join (block, sn, cast, outer_selector, current_block.Toplevel, GetLocation ($1));
5708                 } else {
5709                         var lt2 = (Tokenizer.LocatedToken) $13;
5710                         sn2 = new SimpleMemberName (lt2.Value, lt2.Location);
5711                         $$ = new Linq.GroupJoin (block, sn, cast, outer_selector, current_block.Toplevel,
5712                                 sn2, GetLocation ($1));
5713                 }
5714                 
5715                 current_block.AddStatement (new ContextualReturn ((Expression) $12));
5716                 current_block.SetEndLocation (lexer.Location);
5717                 current_block = current_block.Parent;
5718                         
5719                 if (sn2 == null)
5720                         ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5721                 else
5722                         ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2);
5723           }
5724         ;
5725         
5726 opt_join_into
5727         : /* empty */
5728         | INTO IDENTIFIER
5729           {
5730                 $$ = $2;
5731           }
5732         ;
5733         
5734 orderby_clause
5735         : ORDERBY
5736           {
5737                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5738           }
5739           orderings
5740           {
5741                 current_block.SetEndLocation (lexer.Location);
5742                 current_block = current_block.Parent;
5743           
5744                 $$ = $3;
5745           }
5746         ;
5747         
5748 orderings
5749         : order_by
5750         | order_by COMMA
5751           {
5752                 current_block.SetEndLocation (lexer.Location);
5753                 current_block = current_block.Parent;
5754           
5755                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5756           }
5757           orderings_then_by
5758           {
5759                 ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4;
5760                 $$ = $1;
5761           }
5762         ;
5763         
5764 orderings_then_by
5765         : then_by
5766         | orderings_then_by COMMA
5767          {
5768                 current_block.SetEndLocation (lexer.Location);
5769                 current_block = current_block.Parent;
5770           
5771                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);   
5772          }
5773          then_by
5774          {
5775                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$3;
5776                 $$ = $1;
5777          }
5778         ;       
5779         
5780 order_by
5781         : expression
5782           {
5783                 $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1);        
5784           }
5785         | expression ASCENDING
5786           {
5787                 $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1);        
5788           }
5789         | expression DESCENDING
5790           {
5791                 $$ = new Linq.OrderByDescending (current_block.Toplevel, (Expression)$1);       
5792           }
5793         ;
5795 then_by
5796         : expression
5797           {
5798                 $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); 
5799           }
5800         | expression ASCENDING
5801           {
5802                 $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); 
5803           }
5804         | expression DESCENDING
5805           {
5806                 $$ = new Linq.ThenByDescending (current_block.Toplevel, (Expression)$1);        
5807           }     
5808         ;
5811 opt_query_continuation
5812         : /* empty */
5813         | INTO IDENTIFIER
5814           {
5815                 // query continuation block is not linked with query block but with block
5816                 // before. This means each query can use same range variable names for
5817                 // different identifiers.
5819                 current_block.SetEndLocation (GetLocation ($1));
5820                 current_block = current_block.Parent;
5822                 var lt = (Tokenizer.LocatedToken) $2;
5823                 
5824                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5825           }
5826           query_body
5827           {
5828                 $$ = new Linq.QueryExpression (current_block, (Linq.AQueryClause)$4);
5829           }
5830         ;
5831         
5833 // Support for using the compiler as an interactive parser
5835 // The INTERACTIVE_PARSER token is first sent to parse our
5836 // productions;  If the result is a Statement, the parsing
5837 // is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
5838 // to setup the blocks in advance.
5840 // This setup is here so that in the future we can add 
5841 // support for other constructs (type parsing, namespaces, etc)
5842 // that do not require a block to be setup in advance
5845 interactive_parsing
5846         : EVAL_STATEMENT_PARSER EOF 
5847         | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives 
5848         | EVAL_STATEMENT_PARSER { 
5849                 Evaluator.LoadAliases (current_namespace);
5851                 push_current_class (new Class (current_namespace, current_class, new MemberName ("Class" + class_count++),
5852                         Modifiers.PUBLIC, null), null);
5854                 var baseclass_list = new List<FullNamedExpression> ();
5855                 baseclass_list.Add (new TypeExpression (Evaluator.InteractiveBaseClass, lexer.Location));
5856                 current_container.AddBasesForPart (current_class, baseclass_list);
5858                 // (ref object retval)
5859                 Parameter [] mpar = new Parameter [1];
5860                 mpar [0] = new Parameter (TypeManager.system_object_expr, "$retval", Parameter.Modifier.REF, null, Location.Null);
5862                 ParametersCompiled pars = new ParametersCompiled (compiler, mpar);
5863                 current_local_parameters = pars;
5864                 Method method = new Method (
5865                         current_class,
5866                         null, // generic
5867                         TypeManager.system_void_expr,
5868                         Modifiers.PUBLIC | Modifiers.STATIC,
5869                         new MemberName ("Host"),
5870                         pars,
5871                         null /* attributes */);
5873                 oob_stack.Push (method);
5874                 ++lexer.parsing_block;
5875                 start_block (lexer.Location);
5876           }             
5877           interactive_statement_list opt_COMPLETE_COMPLETION
5878           {
5879                 --lexer.parsing_block;
5880                 Method method = (Method) oob_stack.Pop ();
5882                 method.Block = (ToplevelBlock) end_block(lexer.Location);
5883                 current_container.AddMethod (method);
5885                 --lexer.parsing_declaration;
5886                 InteractiveResult = pop_current_class ();
5887                 current_local_parameters = null;
5888           } 
5889         | EVAL_COMPILATION_UNIT_PARSER {
5890                 Evaluator.LoadAliases (current_namespace);
5891           }
5892           interactive_compilation_unit
5893         ;
5895 interactive_compilation_unit
5896         : outer_declarations 
5897         | outer_declarations global_attributes 
5898         | global_attributes 
5899         | /* nothing */
5900         ;
5902 opt_COMPLETE_COMPLETION
5903         : /* nothing */
5904         | COMPLETE_COMPLETION
5905         ;
5907 close_brace_or_complete_completion
5908         : CLOSE_BRACE
5909         | COMPLETE_COMPLETION
5910         ;
5913 // <summary>
5914 //   A class used to pass around variable declarations and constants
5915 // </summary>
5916 class VariableDeclaration {
5917         public string identifier;
5918         Expression initializer;
5919         public Location Location;
5920         public Attributes OptAttributes;
5921         public string DocComment;
5923         public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer, Attributes opt_attrs)
5924         {
5925                 this.identifier = lt.Value;
5926                 this.initializer = initializer;
5927                 this.Location = lt.Location;
5928                 this.OptAttributes = opt_attrs;
5929         }
5931         public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer)
5932                 : this (lt, initializer, null)
5933         {
5934         }
5936         public Expression GetInitializer (FullNamedExpression type)
5937         {
5938                 if (initializer is ArrayInitializer)
5939                         return new ArrayCreation (type, "", (ArrayInitializer)initializer, Location);
5941                 return initializer;
5942         }
5944         public bool HasInitializer {
5945                 get { return initializer != null; }
5946         }
5949 class VariableMemberDeclaration
5951         public readonly MemberName MemberName;
5952         Expression initializer;
5953         
5954         public VariableMemberDeclaration (MemberName mn, Expression initializer)
5955         {
5956                 MemberName = mn;
5957                 this.initializer = initializer;
5958         }
5960         public Expression GetInitializer (FullNamedExpression type)
5961         {
5962                 if (initializer is ArrayInitializer)
5963                         return new ArrayCreation (type, "", (ArrayInitializer)initializer, MemberName.Location);
5965                 return initializer;
5966         }
5970 // <summary>
5971 //  A class used to hold info about an operator declarator
5972 // </summary>
5973 struct OperatorDeclaration {
5974         public readonly Operator.OpType optype;
5975         public readonly FullNamedExpression ret_type;
5976         public readonly Location location;
5978         public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
5979         {
5980                 optype = op;
5981                 this.ret_type = ret_type;
5982                 this.location = location;
5983         }
5986 void Error_ExpectingTypeName (Expression expr)
5988         if (expr is Invocation){
5989                 Report.Error (1002, expr.Location, "Expecting `;'");
5990         } else {
5991                 Expression.Error_InvalidExpressionStatement (Report, expr.Location);
5992         }
5995 void Error_ParameterModifierNotValid (string modifier, Location loc)
5997         Report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
5998                                       modifier);
6001 void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
6003         Report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
6004                 Parameter.GetModifierSignature (mod));
6007 void Error_TypeExpected (Location loc)
6009         Report.Error (1031, loc, "Type expected");
6012 void Error_NamedArgumentExpected (NamedArgument a)
6014         Report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
6017 void push_current_class (TypeContainer tc, object partial_token)
6019         if (RootContext.EvalMode){
6020                 tc.ModFlags = (tc.ModFlags & ~(Modifiers.PRIVATE|Modifiers.INTERNAL)) | Modifiers.PUBLIC;
6021                 undo.AddTypeContainer (current_container, tc);
6022         }
6024         if (partial_token != null)
6025                 current_container = current_container.AddPartial (tc);
6026         else
6027                 current_container = current_container.AddTypeContainer (tc);
6029         ++lexer.parsing_declaration;
6030         current_class = tc;
6033 DeclSpace pop_current_class ()
6035         DeclSpace retval = current_class;
6037         current_class = current_class.Parent;
6038         current_container = current_class.PartialContainer;
6040         return retval;
6043 // <summary>
6044 //   Given the @class_name name, it creates a fully qualified name
6045 //   based on the containing declaration space
6046 // </summary>
6047 MemberName
6048 MakeName (MemberName class_name)
6050         Namespace ns = current_namespace.NS;
6052         if (current_container == RootContext.ToplevelTypes) {
6053                 if (ns.Name.Length != 0)
6054                         return new MemberName (ns.MemberName, class_name);
6055                 else
6056                         return class_name;
6057         } else {
6058                 return new MemberName (current_container.MemberName, class_name);
6059         }
6062 Block declare_local_variables (FullNamedExpression type, List<object> variable_declarators, Location loc)
6064         Block implicit_block;
6066         //
6067         // If we are doing interactive editing, we want variable declarations
6068         // that are in the top block to be added instead to the class as 
6069         // static variables
6070         //
6071         if (RootContext.StatementMode){
6072                 bool hoist = true;
6074                 for (Block b = current_block; b != null; b = b.Parent){
6075                         if (b is ExplicitBlock && !(b is ToplevelBlock)){
6076                                 // There has been an explicit block, we cant add to the class
6077                                 hoist = false;
6078                                 break;
6079                         }
6080                 }               
6081                 if (hoist){
6082                         //
6083                         // We can use "current_block" since we know there are no explicit blocks
6084                         //
6085                         foreach (VariableDeclaration decl in variable_declarators){
6086                                 // We can not use the super-handy f.Initializer, because
6087                                 // multiple lines would force code to be executed out of sync
6088                                 var init = decl.GetInitializer (type);
6089                                 if (init != null){
6090                                         string id = "$" + decl.identifier;
6091                                         LocalInfo vi = current_block.AddVariable (type, id, decl.Location);                                     
6093                                         // Avoid warning about this variable not being used.
6094                                         vi.Used = true;
6096                                         LocalVariableReference var;
6097                                         var = new LocalVariableReferenceWithClassSideEffect (current_container, decl.identifier, current_block, id, vi, decl.Location);
6098                                         Assign assign = new SimpleAssign (var, init, decl.Location);
6099                                         current_block.AddStatement (new StatementExpression (assign));
6100                                         assign = new SimpleAssign (new SimpleName (decl.identifier, decl.Location), var);
6101                                         current_block.AddStatement (new StatementExpression (assign));
6102                                 } else {
6103                                         Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.PUBLIC | Modifiers.STATIC,
6104                                                 new MemberName (decl.identifier, loc), null);
6105                                         current_container.AddField (f);
6107                                         // Register the field to be visible later as a global variable
6108                                         Evaluator.QueueField (f);
6109                                 }
6110                         }
6112                         return current_block;
6113                 }
6114         }
6116         //
6117         // We use the `Used' property to check whether statements
6118         // have been added to the current block.  If so, we need
6119         // to create another block to contain the new declaration
6120         // otherwise, as an optimization, we use the same block to
6121         // add the declaration.
6122         //
6123         // FIXME: A further optimization is to check if the statements
6124         // that were added were added as part of the initialization
6125         // below.  In which case, no other statements have been executed
6126         // and we might be able to reduce the number of blocks for
6127         // situations like this:
6128         //
6129         // int j = 1;  int k = j + 1;
6130         //
6131         if (current_block.Used)
6132                 implicit_block = new Block (current_block, loc, lexer.Location);
6133         else
6134                 implicit_block = current_block;
6136         foreach (VariableDeclaration decl in variable_declarators){
6138                 if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) {
6139                         if (decl.HasInitializer){
6140                                 Assign assign;
6141                                 
6142                                 var lvr = new LocalVariableReference (implicit_block, decl.identifier, loc);
6144                                 assign = new SimpleAssign (lvr, decl.GetInitializer (type), decl.Location);
6146                                 implicit_block.AddStatement (new StatementExpression (assign));
6147                         }
6148                 }
6149         }
6150         
6151         return implicit_block;
6154 Block declare_local_constants (FullNamedExpression type, List<object> declarators)
6156         Block implicit_block;
6158         if (current_block.Used)
6159                 implicit_block = new Block (current_block);
6160         else
6161                 implicit_block = current_block;
6163         foreach (VariableDeclaration decl in declarators){
6164                 implicit_block.AddConstant (type, decl.identifier, decl.GetInitializer (type), decl.Location);
6165         }
6166         
6167         return implicit_block;
6170 string CheckAttributeTarget (string a, Location l)
6172         switch (a) {
6173         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
6174                         return a;
6175         }
6177         Report.Warning (658, 1, l,
6178                  "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
6179         return string.Empty;
6182 static bool IsUnaryOperator (Operator.OpType op)
6184         switch (op) {
6185                 
6186         case Operator.OpType.LogicalNot: 
6187         case Operator.OpType.OnesComplement: 
6188         case Operator.OpType.Increment:
6189         case Operator.OpType.Decrement:
6190         case Operator.OpType.True: 
6191         case Operator.OpType.False: 
6192         case Operator.OpType.UnaryPlus: 
6193         case Operator.OpType.UnaryNegation:
6194                 return true;
6195         }
6196         return false;
6199 void syntax_error (Location l, string msg)
6201         Report.Error (1003, l, "Syntax error, " + msg);
6204 Tokenizer lexer;
6206 public Tokenizer Lexer {
6207         get {
6208                 return lexer;
6209         }
6210 }                  
6212 static CSharpParser ()
6214         oob_stack = new Stack<object> ();
6217 public CSharpParser (SeekableStreamReader reader, CompilationUnit file, CompilerContext ctx)
6219         if (RootContext.EvalMode)
6220                 undo = new Undo ();
6222         this.file = file;
6223         this.compiler = ctx;
6224         current_namespace = new NamespaceEntry (null, file, null);
6225         current_class = current_namespace.SlaveDeclSpace;
6226         current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
6227         oob_stack.Clear ();
6228         lexer = new Tokenizer (reader, file, ctx);
6229         
6230         use_global_stacks = true;
6233 public void parse ()
6235         eof_token = Token.EOF;
6236         Tokenizer.LocatedToken.Initialize ();
6237         
6238         try {
6239                 if (yacc_verbose_flag > 1)
6240                         yyparse (lexer, new yydebug.yyDebugSimple ());
6241                 else
6242                         yyparse (lexer);
6243                         
6244                 Tokenizer tokenizer = lexer as Tokenizer;
6245                 tokenizer.cleanup ();           
6246         } catch (Exception e){
6247                 if (e is yyParser.yyUnexpectedEof)
6248                         UnexpectedEOF = true;
6250                 if (e is yyParser.yyException)
6251                         Report.Error (-25, lexer.Location, "Parsing error");
6252                 else if (yacc_verbose_flag > 0)
6253                         throw;  // Used by compiler-tester to test internal errors
6254                 else 
6255                         Report.Error (589, lexer.Location, "Internal compiler error during parsing");
6256         }
6258         if (RootContext.ToplevelTypes.NamespaceEntry != null)
6259                 throw new InternalErrorException ("who set it?");
6262 void CheckToken (int error, int yyToken, string msg, Location loc)
6264         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
6265                 Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken));
6266         else
6267                 Report.Error (error, loc, msg);
6270 void CheckIdentifierToken (int yyToken, Location loc)
6272         CheckToken (1041, yyToken, "Identifier expected", loc);
6275 string ConsumeStoredComment ()
6277         string s = tmpComment;
6278         tmpComment = null;
6279         Lexer.doc_state = XmlCommentState.Allowed;
6280         return s;
6283 Location GetLocation (object obj)
6285         if (obj is Tokenizer.LocatedToken)
6286                 return ((Tokenizer.LocatedToken) obj).Location;
6287         if (obj is MemberName)
6288                 return ((MemberName) obj).Location;
6290 //      if (obj is Expression)
6291 //              return ((Expression) obj).Location;             
6293         return lexer.Location;
6296 Report Report {
6297         get { return compiler.Report; }
6300 void start_block (Location loc)
6302         if (current_block == null || parsing_anonymous_method) {
6303                 current_block = new ToplevelBlock (compiler, current_block, current_local_parameters, current_generic_method, loc);
6304                 parsing_anonymous_method = false;
6305         } else {
6306                 current_block = new ExplicitBlock (current_block, loc, Location.Null);
6307         }
6310 Block
6311 end_block (Location loc)
6313         Block retval = current_block.Explicit;
6314         retval.SetEndLocation (loc);
6315         current_block = retval.Parent;
6316         return retval;
6319 void
6320 start_anonymous (bool lambda, ParametersCompiled parameters, Location loc)
6322         if (RootContext.Version == LanguageVersion.ISO_1){
6323                 Report.FeatureIsNotAvailable (loc, "anonymous methods");
6324         }
6326         oob_stack.Push (current_anonymous_method);
6327         oob_stack.Push (current_local_parameters);
6329         current_local_parameters = parameters;
6331         current_anonymous_method = lambda 
6332                 ? new LambdaExpression (loc) 
6333                 : new AnonymousMethodExpression (loc);
6335         // Force the next block to be created as a ToplevelBlock
6336         parsing_anonymous_method = true;
6340  * Completes the anonymous method processing, if lambda_expr is null, this
6341  * means that we have a Statement instead of an Expression embedded 
6342  */
6343 AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block)
6345         AnonymousMethodExpression retval;
6347         current_anonymous_method.Block = anon_block;
6348         retval = current_anonymous_method;
6350         current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
6351         current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
6353         return retval;
6356 public NamespaceEntry CurrentNamespace {
6357        get { 
6358            return current_namespace;
6359        }
6363 void Error_SyntaxError (int token)
6365         Error_SyntaxError (0, token, "Unexpected symbol");
6368 void Error_SyntaxError (int error_code, int token, string msg)
6370         string symbol = GetSymbolName (token);
6371         string expecting = GetExpecting ();
6372         
6373         if (error_code == 0) {
6374                 if (expecting == "`)'")
6375                         error_code = 1026;
6376                 else
6377                         error_code = 1525;
6378         }
6379         
6380         if (expecting != null)
6381                 Report.Error (error_code, lexer.Location, "{2} `{0}', expecting {1}", 
6382                         symbol, expecting, msg);          
6383         else
6384                 Report.Error (error_code, lexer.Location, "{1} `{0}'", symbol, msg);
6387 string GetExpecting ()
6389         int [] tokens = yyExpectingTokens (yyExpectingState);
6390         var names = new List<string> (tokens.Length);
6391         bool has_type = false;
6392         bool has_identifier = false;
6393         for (int i = 0; i < tokens.Length; i++){
6394                 int token = tokens [i];
6395                 has_identifier |= token == Token.IDENTIFIER;
6396                 
6397                 string name = GetTokenName (token);
6398                 if (name == "<internal>")
6399                         continue;
6400                         
6401                 has_type |= name == "type";
6402                 if (names.Contains (name))
6403                         continue;
6404                 
6405                 names.Add (name);
6406         }
6408         //
6409         // Too many tokens to enumerate
6410         //
6411         if (names.Count > 8)
6412                 return null;
6414         if (has_type && has_identifier)
6415                 names.Remove ("identifier");
6417         if (names.Count == 1)
6418                 return "`" + GetTokenName (tokens [0]) + "'";
6419         
6420         StringBuilder sb = new StringBuilder ();
6421         names.Sort ();
6422         int count = names.Count;
6423         for (int i = 0; i < count; i++){
6424                 bool last = i + 1 == count;
6425                 if (last)
6426                         sb.Append ("or ");
6427                 sb.Append ('`');
6428                 sb.Append (names [i]);
6429                 sb.Append (last ? "'" : count < 3 ? "' " : "', ");
6430         }
6431         return sb.ToString ();
6435 string GetSymbolName (int token)
6437         switch (token){
6438         case Token.LITERAL:
6439                 return ((Constant)lexer.Value).GetValue ().ToString ();
6440         case Token.IDENTIFIER:
6441                 return ((Tokenizer.LocatedToken)lexer.Value).Value;
6443         case Token.BOOL:
6444                 return "bool";
6445         case Token.BYTE:
6446                 return "byte";
6447         case Token.CHAR:
6448                 return "char";
6449         case Token.VOID:
6450                 return "void";
6451         case Token.DECIMAL:
6452                 return "decimal";
6453         case Token.DOUBLE:
6454                 return "double";
6455         case Token.FLOAT:
6456                 return "float";
6457         case Token.INT:
6458                 return "int";
6459         case Token.LONG:
6460                 return "long";
6461         case Token.SBYTE:
6462                 return "sbyte";
6463         case Token.SHORT:
6464                 return "short";
6465         case Token.STRING:
6466                 return "string";
6467         case Token.UINT:
6468                 return "uint";
6469         case Token.ULONG:
6470                 return "ulong";
6471         case Token.USHORT:
6472                 return "ushort";
6473         case Token.OBJECT:
6474                 return "object";
6475                 
6476         case Token.PLUS:
6477                 return "+";
6478         case Token.UMINUS:
6479         case Token.MINUS:
6480                 return "-";
6481         case Token.BANG:
6482                 return "!";
6483         case Token.BITWISE_AND:
6484                 return "&";
6485         case Token.BITWISE_OR:
6486                 return "|";
6487         case Token.STAR:
6488                 return "*";
6489         case Token.PERCENT:
6490                 return "%";
6491         case Token.DIV:
6492                 return "/";
6493         case Token.CARRET:
6494                 return "^";
6495         case Token.OP_INC:
6496                 return "++";
6497         case Token.OP_DEC:
6498                 return "--";
6499         case Token.OP_SHIFT_LEFT:
6500                 return "<<";
6501         case Token.OP_SHIFT_RIGHT:
6502                 return ">>";
6503         case Token.OP_LT:
6504                 return "<";
6505         case Token.OP_GT:
6506                 return ">";
6507         case Token.OP_LE:
6508                 return "<=";
6509         case Token.OP_GE:
6510                 return ">=";
6511         case Token.OP_EQ:
6512                 return "==";
6513         case Token.OP_NE:
6514                 return "!=";
6515         case Token.OP_AND:
6516                 return "&&";
6517         case Token.OP_OR:
6518                 return "||";
6519         case Token.OP_PTR:
6520                 return "->";
6521         case Token.OP_COALESCING:       
6522                 return "??";
6523         case Token.OP_MULT_ASSIGN:
6524                 return "*=";
6525         case Token.OP_DIV_ASSIGN:
6526                 return "/=";
6527         case Token.OP_MOD_ASSIGN:
6528                 return "%=";
6529         case Token.OP_ADD_ASSIGN:
6530                 return "+=";
6531         case Token.OP_SUB_ASSIGN:
6532                 return "-=";
6533         case Token.OP_SHIFT_LEFT_ASSIGN:
6534                 return "<<=";
6535         case Token.OP_SHIFT_RIGHT_ASSIGN:
6536                 return ">>=";
6537         case Token.OP_AND_ASSIGN:
6538                 return "&=";
6539         case Token.OP_XOR_ASSIGN:
6540                 return "^=";
6541         case Token.OP_OR_ASSIGN:
6542                 return "|=";
6543         }
6545         return GetTokenName (token);
6548 static string GetTokenName (int token)
6550         switch (token){
6551         case Token.ABSTRACT:
6552                 return "abstract";
6553         case Token.AS:
6554                 return "as";
6555         case Token.ADD:
6556                 return "add";
6557         case Token.BASE:
6558                 return "base";
6559         case Token.BREAK:
6560                 return "break";
6561         case Token.CASE:
6562                 return "case";
6563         case Token.CATCH:
6564                 return "catch";
6565         case Token.CHECKED:
6566                 return "checked";
6567         case Token.CLASS:
6568                 return "class";
6569         case Token.CONST:
6570                 return "const";
6571         case Token.CONTINUE:
6572                 return "continue";
6573         case Token.DEFAULT:
6574                 return "default";
6575         case Token.DELEGATE:
6576                 return "delegate";
6577         case Token.DO:
6578                 return "do";
6579         case Token.ELSE:
6580                 return "else";
6581         case Token.ENUM:
6582                 return "enum";
6583         case Token.EVENT:
6584                 return "event";
6585         case Token.EXPLICIT:
6586                 return "explicit";
6587         case Token.EXTERN:
6588                 return "extern";
6589         case Token.FALSE:
6590                 return "false";
6591         case Token.FINALLY:
6592                 return "finally";
6593         case Token.FIXED:
6594                 return "fixed";
6595         case Token.FOR:
6596                 return "for";
6597         case Token.FOREACH:
6598                 return "foreach";
6599         case Token.GOTO:
6600                 return "goto";
6601         case Token.IF:
6602                 return "if";
6603         case Token.IMPLICIT:
6604                 return "implicit";
6605         case Token.IN:
6606                 return "in";
6607         case Token.INTERFACE:
6608                 return "interface";
6609         case Token.INTERNAL:
6610                 return "internal";
6611         case Token.IS:
6612                 return "is";
6613         case Token.LOCK:
6614                 return "lock";
6615         case Token.NAMESPACE:
6616                 return "namespace";
6617         case Token.NEW:
6618                 return "new";
6619         case Token.NULL:
6620                 return "null";
6621         case Token.OPERATOR:
6622                 return "operator";
6623         case Token.OUT:
6624                 return "out";
6625         case Token.OVERRIDE:
6626                 return "override";
6627         case Token.PARAMS:
6628                 return "params";
6629         case Token.PRIVATE:
6630                 return "private";
6631         case Token.PROTECTED:
6632                 return "protected";
6633         case Token.PUBLIC:
6634                 return "public";
6635         case Token.READONLY:
6636                 return "readonly";
6637         case Token.REF:
6638                 return "ref";
6639         case Token.RETURN:
6640                 return "return";
6641         case Token.REMOVE:
6642                 return "remove";
6643         case Token.SEALED:
6644                 return "sealed";
6645         case Token.SIZEOF:
6646                 return "sizeof";
6647         case Token.STACKALLOC:
6648                 return "stackalloc";
6649         case Token.STATIC:
6650                 return "static";
6651         case Token.STRUCT:
6652                 return "struct";
6653         case Token.SWITCH:
6654                 return "switch";
6655         case Token.THIS:
6656                 return "this";
6657         case Token.THROW:
6658                 return "throw";
6659         case Token.TRUE:
6660                 return "true";
6661         case Token.TRY:
6662                 return "try";
6663         case Token.TYPEOF:
6664                 return "typeof";
6665         case Token.UNCHECKED:
6666                 return "unchecked";
6667         case Token.UNSAFE:
6668                 return "unsafe";
6669         case Token.USING:
6670                 return "using";
6671         case Token.VIRTUAL:
6672                 return "virtual";
6673         case Token.VOLATILE:
6674                 return "volatile";
6675         case Token.WHERE:
6676                 return "where";
6677         case Token.WHILE:
6678                 return "while";
6679         case Token.ARGLIST:
6680                 return "__arglist";
6681         case Token.PARTIAL:
6682                 return "partial";
6683         case Token.ARROW:
6684                 return "=>";
6685         case Token.FROM:
6686         case Token.FROM_FIRST:
6687                 return "from";
6688         case Token.JOIN:
6689                 return "join";
6690         case Token.ON:
6691                 return "on";
6692         case Token.EQUALS:
6693                 return "equals";
6694         case Token.SELECT:
6695                 return "select";
6696         case Token.GROUP:
6697                 return "group";
6698         case Token.BY:
6699                 return "by";
6700         case Token.LET:
6701                 return "let";
6702         case Token.ORDERBY:
6703                 return "orderby";
6704         case Token.ASCENDING:
6705                 return "ascending";
6706         case Token.DESCENDING:
6707                 return "descending";
6708         case Token.INTO:
6709                 return "into";
6710         case Token.GET:
6711                 return "get";
6712         case Token.SET:
6713                 return "set";
6714         case Token.OPEN_BRACE:
6715                 return "{";
6716         case Token.CLOSE_BRACE:
6717                 return "}";
6718         case Token.OPEN_BRACKET:
6719                 return "[";
6720         case Token.CLOSE_BRACKET:
6721                 return "]";
6722         case Token.OPEN_PARENS_CAST:
6723         case Token.OPEN_PARENS_LAMBDA:
6724         case Token.OPEN_PARENS:
6725                 return "(";
6726         case Token.CLOSE_PARENS:
6727                 return ")";
6728         case Token.DOT:
6729                 return ".";
6730         case Token.COMMA:
6731                 return ",";
6732         case Token.DEFAULT_COLON:
6733                 return "default:";
6734         case Token.COLON:
6735                 return ":";
6736         case Token.SEMICOLON:
6737                 return ";";
6738         case Token.TILDE:
6739                 return "~";
6740                 
6741         case Token.PLUS:
6742         case Token.UMINUS:
6743         case Token.MINUS:
6744         case Token.BANG:
6745         case Token.OP_LT:
6746         case Token.OP_GT:
6747         case Token.BITWISE_AND:
6748         case Token.BITWISE_OR:
6749         case Token.STAR:
6750         case Token.PERCENT:
6751         case Token.DIV:
6752         case Token.CARRET:
6753         case Token.OP_INC:
6754         case Token.OP_DEC:
6755         case Token.OP_SHIFT_LEFT:
6756         case Token.OP_SHIFT_RIGHT:
6757         case Token.OP_LE:
6758         case Token.OP_GE:
6759         case Token.OP_EQ:
6760         case Token.OP_NE:
6761         case Token.OP_AND:
6762         case Token.OP_OR:
6763         case Token.OP_PTR:
6764         case Token.OP_COALESCING:       
6765         case Token.OP_MULT_ASSIGN:
6766         case Token.OP_DIV_ASSIGN:
6767         case Token.OP_MOD_ASSIGN:
6768         case Token.OP_ADD_ASSIGN:
6769         case Token.OP_SUB_ASSIGN:
6770         case Token.OP_SHIFT_LEFT_ASSIGN:
6771         case Token.OP_SHIFT_RIGHT_ASSIGN:
6772         case Token.OP_AND_ASSIGN:
6773         case Token.OP_XOR_ASSIGN:
6774         case Token.OP_OR_ASSIGN:
6775                 return "<operator>";
6777         case Token.BOOL:
6778         case Token.BYTE:
6779         case Token.CHAR:
6780         case Token.VOID:
6781         case Token.DECIMAL:
6782         case Token.DOUBLE:
6783         case Token.FLOAT:
6784         case Token.INT:
6785         case Token.LONG:
6786         case Token.SBYTE:
6787         case Token.SHORT:
6788         case Token.STRING:
6789         case Token.UINT:
6790         case Token.ULONG:
6791         case Token.USHORT:
6792         case Token.OBJECT:
6793                 return "type";
6794         
6795         case Token.ASSIGN:
6796                 return "=";
6797         case Token.OP_GENERICS_LT:
6798         case Token.GENERIC_DIMENSION:
6799                 return "<";
6800         case Token.OP_GENERICS_GT:
6801                 return ">";
6802         case Token.INTERR:
6803         case Token.INTERR_NULLABLE:
6804                 return "?";
6805         case Token.DOUBLE_COLON:
6806                 return "::";
6807         case Token.LITERAL:
6808                 return "value";
6809         case Token.IDENTIFIER:
6810                 return "identifier";
6812                 // All of these are internal.
6813         case Token.NONE:
6814         case Token.ERROR:
6815         case Token.FIRST_KEYWORD:
6816         case Token.EOF:
6817         case Token.EVAL_COMPILATION_UNIT_PARSER:
6818         case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER:
6819         case Token.EVAL_STATEMENT_PARSER:
6820         case Token.LAST_KEYWORD:
6821         case Token.GENERATE_COMPLETION:
6822         case Token.COMPLETE_COMPLETION:
6823                 return "<internal>";
6825                 // A bit more robust.
6826         default:
6827                 return yyNames [token];
6828         }
6831 /* end end end */