2010-03-05 Rodrigo Kumpera <rkumpera@novell.com>
[mcs.git] / mcs / cs-parser.jay
blob18c8c57b1899ab1729223ae23dc016495a2e4b03
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                 if ($10 != null && name.TypeArguments == null)
1304                         Report.Error (80, lexer.Location,
1305                                       "Constraints are not allowed on non-generic declarations");
1307                 Method method;
1309                 GenericMethod generic = null;
1310                 if (name.TypeArguments != null) {
1311                         generic = new GenericMethod (current_namespace, current_class, name,
1312                                                      (FullNamedExpression) $3, current_local_parameters);
1314                         generic.SetParameterInfo ((List<Constraints>) $10);
1315                 }
1317                 method = new Method (current_class, generic, (FullNamedExpression) $3, (Modifiers) $2,
1318                                      name, current_local_parameters, (Attributes) $1);
1320                 current_generic_method = generic;
1322                 if (RootContext.Documentation != null)
1323                         method.DocComment = Lexer.consume_doc_comment ();
1325                 $$ = method;
1326           }
1327         | opt_attributes
1328           opt_modifiers
1329           PARTIAL
1330           VOID method_declaration_name
1331           OPEN_PARENS
1332           {
1333                 valid_param_mod = ParameterModifierType.All;
1334           }
1335           opt_formal_parameter_list CLOSE_PARENS 
1336           {
1337                 lexer.ConstraintsParsing = true;
1338           }
1339           opt_type_parameter_constraints_clauses
1340           {
1341                 lexer.ConstraintsParsing = false;
1342                 valid_param_mod = 0;
1344                 MemberName name = (MemberName) $5;
1345                 current_local_parameters = (ParametersCompiled) $8;
1347                 if ($10 != null && name.TypeArguments == null)
1348                         Report.Error (80, lexer.Location,
1349                                       "Constraints are not allowed on non-generic declarations");
1351                 Method method;
1352                 GenericMethod generic = null;
1353                 if (name.TypeArguments != null) {
1354                         generic = new GenericMethod (current_namespace, current_class, name,
1355                                                      TypeManager.system_void_expr, current_local_parameters);
1357                         generic.SetParameterInfo ((List<Constraints>) $11);
1358                 }
1360                 var modifiers = (Modifiers) $2;
1363                 const Modifiers invalid_partial_mod = Modifiers.AccessibilityMask | Modifiers.ABSTRACT | Modifiers.EXTERN |
1364                         Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.SEALED | Modifiers.VIRTUAL;
1366                 if ((modifiers & invalid_partial_mod) != 0) {
1367                         Report.Error (750, name.Location, "A partial method cannot define access modifier or " +
1368                         "any of abstract, extern, new, override, sealed, or virtual modifiers");
1369                         modifiers &= ~invalid_partial_mod;
1370                 }
1372                 if ((current_class.ModFlags & Modifiers.PARTIAL) == 0) {
1373                         Report.Error (751, name.Location, "A partial method must be declared within a " +
1374                         "partial class or partial struct");
1375                 }
1376                 
1377                 modifiers |= Modifiers.PARTIAL | Modifiers.PRIVATE;
1378                 
1379                 method = new Method (current_class, generic, TypeManager.system_void_expr,
1380                                      modifiers, name, current_local_parameters, (Attributes) $1);
1382                 current_generic_method = generic;
1384                 if (RootContext.Documentation != null)
1385                         method.DocComment = Lexer.consume_doc_comment ();
1387                 $$ = method;
1388           }
1389         | opt_attributes
1390           opt_modifiers
1391           member_type
1392           modifiers method_declaration_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1393           {
1394                 MemberName name = (MemberName) $5;
1395                 Report.Error (1585, name.Location, 
1396                         "Member modifier `{0}' must precede the member type and name", ModifiersExtensions.Name ((Modifiers) $4));
1398                 Method method = new Method (current_class, null, TypeManager.system_void_expr,
1399                                             0, name, (ParametersCompiled) $7, (Attributes) $1);
1401                 current_local_parameters = (ParametersCompiled) $7;
1403                 if (RootContext.Documentation != null)
1404                         method.DocComment = Lexer.consume_doc_comment ();
1406                 $$ = method;
1407           }
1408         ;
1410 method_body
1411         : block
1412         | SEMICOLON             { $$ = null; }
1413         ;
1415 opt_formal_parameter_list
1416         : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
1417         | formal_parameter_list
1418         ;
1419         
1420 formal_parameter_list
1421         : fixed_parameters
1422           { 
1423                 var pars_list = (List<Parameter>) $1;
1424                 $$ = new ParametersCompiled (compiler, pars_list.ToArray ());
1425           } 
1426         | fixed_parameters COMMA parameter_array
1427           {
1428                 var pars_list = (List<Parameter>) $1;
1429                 pars_list.Add ((Parameter) $3);
1431                 $$ = new ParametersCompiled (compiler, pars_list.ToArray ()); 
1432           }
1433         | fixed_parameters COMMA arglist_modifier
1434           {
1435                 var pars_list = (List<Parameter>) $1;
1436                 pars_list.Add (new ArglistParameter (GetLocation ($3)));
1437                 $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true);
1438           }
1439         | parameter_array COMMA error
1440           {
1441                 if ($1 != null)
1442                         Report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list");
1444                 $$ = new ParametersCompiled (compiler, new Parameter[] { (Parameter) $1 } );                    
1445           }
1446         | fixed_parameters COMMA parameter_array COMMA error
1447           {
1448                 if ($3 != null)
1449                         Report.Error (231, ((Parameter) $3).Location, "A params parameter must be the last parameter in a formal parameter list");
1451                 var pars_list = (List<Parameter>) $1;
1452                 pars_list.Add (new ArglistParameter (GetLocation ($3)));
1454                 $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true);
1455           }
1456         | arglist_modifier COMMA error
1457           {
1458                 Report.Error (257, GetLocation ($1), "An __arglist parameter must be the last parameter in a formal parameter list");
1460                 $$ = new ParametersCompiled (compiler, new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true);
1461           }
1462         | fixed_parameters COMMA ARGLIST COMMA error 
1463           {
1464                 Report.Error (257, GetLocation ($3), "An __arglist parameter must be the last parameter in a formal parameter list");
1466                 var pars_list = (List<Parameter>) $1;
1467                 pars_list.Add (new ArglistParameter (GetLocation ($3)));
1469                 $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true);
1470           }
1471         | parameter_array 
1472           {
1473                 $$ = new ParametersCompiled (compiler, new Parameter[] { (Parameter) $1 } );
1474           }
1475         | arglist_modifier
1476           {
1477                 $$ = new ParametersCompiled (compiler, new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true);
1478           }
1479         ;
1481 fixed_parameters
1482         : fixed_parameter       
1483           {
1484                 parameters_bucket.Clear ();
1485                 Parameter p = (Parameter) $1;
1486                 parameters_bucket.Add (p);
1487                 
1488                 default_parameter_used = p.HasDefaultValue;
1489                 $$ = parameters_bucket;
1490           }
1491         | fixed_parameters COMMA fixed_parameter
1492           {
1493                 var pars = (List<Parameter>) $1;
1494                 Parameter p = (Parameter) $3;
1495                 if (p != null) {
1496                         if (p.HasExtensionMethodModifier)
1497                                 Report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter");
1498                         else if (!p.HasDefaultValue && default_parameter_used)
1499                                 Report.Error (1737, p.Location, "Optional parameter cannot precede required parameters");
1501                         default_parameter_used |= p.HasDefaultValue;
1502                         pars.Add (p);
1503                 }
1504                 $$ = $1;
1505           }
1506         ;
1508 fixed_parameter
1509         : opt_attributes
1510           opt_parameter_modifier
1511           parameter_type
1512           IDENTIFIER
1513           {
1514                 var lt = (Tokenizer.LocatedToken) $4;
1515                 $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
1516           }
1517         | opt_attributes
1518           opt_parameter_modifier
1519           parameter_type
1520           IDENTIFIER OPEN_BRACKET CLOSE_BRACKET
1521           {
1522                 var lt = (Tokenizer.LocatedToken) $4;
1523                 Report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name");
1524                 $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
1525           }
1526         | opt_attributes
1527           opt_parameter_modifier
1528           parameter_type
1529           error
1530           {
1531                 Location l = GetLocation ($4);
1532                 CheckIdentifierToken (yyToken, l);
1533                 $$ = new Parameter ((FullNamedExpression) $3, "NeedSomeGeneratorHere", (Parameter.Modifier) $2, (Attributes) $1, l);
1534           }
1535         | opt_attributes
1536           opt_parameter_modifier
1537           parameter_type
1538           IDENTIFIER
1539           ASSIGN
1540           constant_expression
1541           {
1542                 if (RootContext.Version <= LanguageVersion.V_3) {
1543                         Report.FeatureIsNotAvailable (GetLocation ($5), "optional parameter");
1544                 }
1545                 
1546                 Parameter.Modifier mod = (Parameter.Modifier) $2;
1547                 if (mod != Parameter.Modifier.NONE) {
1548                         switch (mod) {
1549                         case Parameter.Modifier.REF:
1550                         case Parameter.Modifier.OUT:
1551                                 Report.Error (1741, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter",
1552                                         Parameter.GetModifierSignature (mod));
1553                                 break;
1554                                 
1555                         case Parameter.Modifier.This:
1556                                 Report.Error (1743, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter",
1557                                         Parameter.GetModifierSignature (mod));
1558                                 break;
1559                         default:
1560                                 throw new NotImplementedException (mod.ToString ());
1561                         }
1562                                 
1563                         mod = Parameter.Modifier.NONE;
1564                 }
1565                 
1566                 if ((valid_param_mod & ParameterModifierType.DefaultValue) == 0)
1567                         Report.Error (1065, GetLocation ($6), "Optional parameter is not valid in this context");
1568                 
1569                 var lt = (Tokenizer.LocatedToken) $4;
1570                 $$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, lt.Location);
1571                 if ($6 != null)
1572                         ((Parameter) $$).DefaultValue = (Expression) $6;
1573           }
1574         ;
1576 opt_parameter_modifier
1577         : /* empty */           { $$ = Parameter.Modifier.NONE; }
1578         | parameter_modifiers
1579         ;
1581 parameter_modifiers
1582         : parameter_modifier
1583           {
1584                 $$ = $1;
1585           }
1586         | parameter_modifiers parameter_modifier
1587           {
1588                 Parameter.Modifier p2 = (Parameter.Modifier)$2;
1589                 Parameter.Modifier mod = (Parameter.Modifier)$1 | p2;
1590                 if (((Parameter.Modifier)$1 & p2) == p2) {
1591                         Error_DuplicateParameterModifier (lexer.Location, p2);
1592                 } else {
1593                         switch (mod & ~Parameter.Modifier.This) {
1594                                 case Parameter.Modifier.REF:
1595                                         Report.Error (1101, lexer.Location, "The parameter modifiers `this' and `ref' cannot be used altogether");
1596                                         break;
1597                                 case Parameter.Modifier.OUT:
1598                                         Report.Error (1102, lexer.Location, "The parameter modifiers `this' and `out' cannot be used altogether");
1599                                         break;
1600                                 default:
1601                                         Report.Error (1108, lexer.Location, "A parameter cannot have specified more than one modifier");
1602                                         break;
1603                         }
1604                 }
1605                 $$ = mod;
1606           }
1607         ;
1609 parameter_modifier
1610         : REF
1611           {
1612                 if ((valid_param_mod & ParameterModifierType.Ref) == 0)
1613                         Error_ParameterModifierNotValid ("ref", GetLocation ($1));
1614                         
1615                 $$ = Parameter.Modifier.REF;
1616           }
1617         | OUT
1618           {
1619                 if ((valid_param_mod & ParameterModifierType.Out) == 0)
1620                         Error_ParameterModifierNotValid ("out", GetLocation ($1));
1621           
1622                 $$ = Parameter.Modifier.OUT;
1623           }
1624         | THIS
1625           {
1626                 if ((valid_param_mod & ParameterModifierType.This) == 0)
1627                         Error_ParameterModifierNotValid ("this", GetLocation ($1));
1629                 if (RootContext.Version <= LanguageVersion.ISO_2)
1630                         Report.FeatureIsNotAvailable (GetLocation ($1), "extension methods");
1631                                 
1632                 $$ = Parameter.Modifier.This;
1633           }
1634         ;
1636 parameter_array
1637         : opt_attributes params_modifier type IDENTIFIER
1638           {
1639                 var lt = (Tokenizer.LocatedToken) $4;
1640                 $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location);
1641           }
1642         | opt_attributes params_modifier type IDENTIFIER ASSIGN constant_expression
1643           {
1644                 Report.Error (1751, GetLocation ($2), "Cannot specify a default value for a parameter array");
1645                 
1646                 var lt = (Tokenizer.LocatedToken) $4;
1647                 $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location);            
1648           }
1649         | opt_attributes params_modifier type error {
1650                 CheckIdentifierToken (yyToken, GetLocation ($4));
1651                 $$ = null;
1652           }
1653         ;
1654         
1655 params_modifier
1656         : PARAMS
1657           {
1658                 if ((valid_param_mod & ParameterModifierType.Params) == 0)
1659                         Report.Error (1670, (GetLocation ($1)), "The `params' modifier is not allowed in current context");
1660           }
1661         | PARAMS parameter_modifier
1662           {
1663                 Parameter.Modifier mod = (Parameter.Modifier)$2;
1664                 if ((mod & Parameter.Modifier.This) != 0) {
1665                         Report.Error (1104, GetLocation ($1), "The parameter modifiers `this' and `params' cannot be used altogether");
1666                 } else {
1667                         Report.Error (1611, GetLocation ($1), "The params parameter cannot be declared as ref or out");
1668                 }         
1669           }
1670         | PARAMS params_modifier
1671           {
1672                 Error_DuplicateParameterModifier (GetLocation ($1), Parameter.Modifier.PARAMS);
1673           }
1674         ;
1675         
1676 arglist_modifier
1677         : ARGLIST
1678           {
1679                 if ((valid_param_mod & ParameterModifierType.Arglist) == 0)
1680                         Report.Error (1669, GetLocation ($1), "__arglist is not valid in this context");
1681           }
1682         ;
1683         
1684 property_declaration
1685         : opt_attributes
1686           opt_modifiers
1687           member_type
1688           member_declaration_name
1689           {
1690                 if (RootContext.Documentation != null)
1691                         tmpComment = Lexer.consume_doc_comment ();
1692           }
1693           OPEN_BRACE 
1694           {
1695                 implicit_value_parameter_type = (FullNamedExpression) $3;
1696                 lexer.PropertyParsing = true;
1697           }
1698           accessor_declarations 
1699           {
1700                 lexer.PropertyParsing = false;
1701                 has_get = has_set = false;
1702           }
1703           CLOSE_BRACE
1704           { 
1705                 Property prop;
1706                 Accessors accessors = (Accessors) $8;
1707                 Accessor get_block = accessors != null ? accessors.get_or_add : null;
1708                 Accessor set_block = accessors != null ? accessors.set_or_remove : null;
1709                 bool order = accessors != null ? accessors.declared_in_reverse : false;
1711                 MemberName name = (MemberName) $4;
1712                 FullNamedExpression ptype = (FullNamedExpression) $3;
1714                 prop = new Property (current_class, ptype, (Modifiers) $2,
1715                                      name, (Attributes) $1, get_block, set_block, order, current_block);
1717                 if (ptype == TypeManager.system_void_expr)
1718                         Report.Error (547, name.Location, "`{0}': property or indexer cannot have void type", prop.GetSignatureForError ());
1719                         
1720                 if (accessors == null)
1721                         Report.Error (548, prop.Location, "`{0}': property or indexer must have at least one accessor", prop.GetSignatureForError ());
1723                 if (current_container.Kind == MemberKind.Interface) {
1724                         if (prop.Get.Block != null)
1725                                 Report.Error (531, prop.Location, "`{0}.get': interface members cannot have a definition", prop.GetSignatureForError ());
1727                         if (prop.Set.Block != null)
1728                                 Report.Error (531, prop.Location, "`{0}.set': interface members cannot have a definition", prop.GetSignatureForError ());
1729                 }
1731                 current_container.AddProperty (prop);
1732                 implicit_value_parameter_type = null;
1734                 if (RootContext.Documentation != null)
1735                         prop.DocComment = ConsumeStoredComment ();
1737           }
1738         ;
1740 accessor_declarations
1741         : get_accessor_declaration
1742          {
1743                 $$ = new Accessors ((Accessor) $1, null);
1744          }
1745         | get_accessor_declaration accessor_declarations
1746          { 
1747                 Accessors accessors = (Accessors) $2;
1748                 accessors.get_or_add = (Accessor) $1;
1749                 $$ = accessors;
1750          }
1751         | set_accessor_declaration
1752          {
1753                 $$ = new Accessors (null, (Accessor) $1);
1754          }
1755         | set_accessor_declaration accessor_declarations
1756          { 
1757                 Accessors accessors = (Accessors) $2;
1758                 accessors.set_or_remove = (Accessor) $1;
1759                 accessors.declared_in_reverse = true;
1760                 $$ = accessors;
1761          }
1762         | error
1763           {
1764                 if (yyToken == Token.CLOSE_BRACE) {
1765                         $$ = null;
1766                 } else {
1767                         if (yyToken == Token.SEMICOLON)
1768                                 Report.Error (1597, lexer.Location, "Semicolon after method or accessor block is not valid");
1769                         else
1770                                 Report.Error (1014, GetLocation ($1), "A get or set accessor expected");
1772                         $$ = new Accessors (null, null);
1773                 }
1774           }
1775         ;
1777 get_accessor_declaration
1778         : opt_attributes opt_modifiers GET
1779           {
1780                 // If this is not the case, then current_local_parameters has already
1781                 // been set in indexer_declaration
1782                 if (parsing_indexer == false)
1783                         current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
1784                 else 
1785                         current_local_parameters = indexer_parameters;
1786                 lexer.PropertyParsing = false;
1787           }
1788           accessor_body
1789           {
1790                 if (has_get) {
1791                         Report.Error (1007, GetLocation ($3), "Property accessor already defined");
1792                         break;
1793                 }
1794                 Accessor accessor = new Accessor ((ToplevelBlock) $5, (Modifiers) $2, (Attributes) $1, current_local_parameters, GetLocation ($3));
1795                 has_get = true;
1796                 current_local_parameters = null;
1797                 lexer.PropertyParsing = true;
1799                 if (RootContext.Documentation != null)
1800                         if (Lexer.doc_state == XmlCommentState.Error)
1801                                 Lexer.doc_state = XmlCommentState.NotAllowed;
1803                 $$ = accessor;
1804           }
1805         ;
1807 set_accessor_declaration
1808         : opt_attributes opt_modifiers SET 
1809           {
1810                 Parameter implicit_value_parameter = new Parameter (
1811                         implicit_value_parameter_type, "value", 
1812                         Parameter.Modifier.NONE, null, GetLocation ($3));
1814                 if (!parsing_indexer) {
1815                         current_local_parameters = new ParametersCompiled (compiler, new Parameter [] { implicit_value_parameter });
1816                 } else {
1817                         current_local_parameters = ParametersCompiled.MergeGenerated (compiler,
1818                                 indexer_parameters, true, implicit_value_parameter, null);
1819                 }
1820                 
1821                 lexer.PropertyParsing = false;
1822           }
1823           accessor_body
1824           {
1825                 if (has_set) {
1826                         Report.Error (1007, GetLocation ($3), "Property accessor already defined");
1827                         break;
1828                 }
1829                 Accessor accessor = new Accessor ((ToplevelBlock) $5, (Modifiers) $2, (Attributes) $1, current_local_parameters, GetLocation ($3));
1830                 has_set = true;
1831                 current_local_parameters = null;
1832                 lexer.PropertyParsing = true;
1834                 if (RootContext.Documentation != null
1835                         && Lexer.doc_state == XmlCommentState.Error)
1836                         Lexer.doc_state = XmlCommentState.NotAllowed;
1838                 $$ = accessor;
1839           }
1840         ;
1842 accessor_body
1843         : block 
1844         | SEMICOLON
1845           {
1846                 $$ = null;
1847           }
1848         | error
1849           {
1850                 Error_SyntaxError (1043, yyToken, "Invalid accessor body");
1851                 $$ = null;
1852           }
1853         ;
1855 interface_declaration
1856         : opt_attributes
1857           opt_modifiers
1858           opt_partial
1859           INTERFACE
1860           {
1861                 lexer.ConstraintsParsing = true;
1862           }
1863           type_declaration_name
1864           {
1865                 MemberName name = MakeName ((MemberName) $6);
1866                 push_current_class (new Interface (current_namespace, current_class, name, (Modifiers) $2, (Attributes) $1), $3);
1867           }
1868           opt_class_base
1869           opt_type_parameter_constraints_clauses
1870           {
1871                 lexer.ConstraintsParsing = false;
1873                 current_class.SetParameterInfo ((List<Constraints>) $9);
1875                 if (RootContext.Documentation != null) {
1876                         current_container.DocComment = Lexer.consume_doc_comment ();
1877                         Lexer.doc_state = XmlCommentState.Allowed;
1878                 }
1879           }
1880           interface_body
1881           {
1882                 --lexer.parsing_declaration;      
1883                 if (RootContext.Documentation != null)
1884                         Lexer.doc_state = XmlCommentState.Allowed;
1885           }
1886           opt_semicolon 
1887           {
1888                 $$ = pop_current_class ();
1889           }
1890         | opt_attributes opt_modifiers opt_partial INTERFACE error {
1891                 CheckIdentifierToken (yyToken, GetLocation ($5));
1892           }
1893         ;
1895 interface_body
1896         : OPEN_BRACE
1897           opt_interface_member_declarations
1898           CLOSE_BRACE
1899         ;
1901 opt_interface_member_declarations
1902         : /* empty */
1903         | interface_member_declarations
1904         ;
1906 interface_member_declarations
1907         : interface_member_declaration
1908         | interface_member_declarations interface_member_declaration
1909         ;
1911 interface_member_declaration
1912         : constant_declaration
1913           {
1914                 Report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
1915           }
1916         | field_declaration
1917           {
1918                 Report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
1919           }
1920         | method_declaration
1921         | property_declaration
1922         | event_declaration
1923         | indexer_declaration
1924         | operator_declaration
1925           {
1926                 Report.Error (567, GetLocation ($1), "Interfaces cannot contain operators");
1927           }
1928         | constructor_declaration
1929           {
1930                 Report.Error (526, GetLocation ($1), "Interfaces cannot contain contructors");
1931           }
1932         | type_declaration
1933           {
1934                 Report.Error (524, GetLocation ($1), "Interfaces cannot declare classes, structs, interfaces, delegates, or enumerations");
1935           }
1936         ;
1938 operator_declaration
1939         : opt_attributes opt_modifiers operator_declarator 
1940           {
1941           }
1942           operator_body
1943           {
1944                 if ($3 == null)
1945                         break;
1947                 OperatorDeclaration decl = (OperatorDeclaration) $3;
1948                 Operator op = new Operator (
1949                         current_class, decl.optype, decl.ret_type, (Modifiers) $2, 
1950                         current_local_parameters,
1951                         (ToplevelBlock) $5, (Attributes) $1, decl.location);
1953                 if (RootContext.Documentation != null) {
1954                         op.DocComment = tmpComment;
1955                         Lexer.doc_state = XmlCommentState.Allowed;
1956                 }
1958                 // Note again, checking is done in semantic analysis
1959                 current_container.AddOperator (op);
1961                 current_local_parameters = null;
1962           }
1963         ;
1965 operator_body 
1966         : block
1967         | SEMICOLON { $$ = null; }
1968         ; 
1970 operator_type
1971         : type_expression_or_array
1972         | VOID
1973           {
1974                 Report.Error (590, GetLocation ($1), "User-defined operators cannot return void");
1975                 $$ = TypeManager.system_void_expr;              
1976           }
1977         ;
1979 operator_declarator
1980         : operator_type OPERATOR overloadable_operator OPEN_PARENS
1981           {
1982                 valid_param_mod = ParameterModifierType.DefaultValue;
1983           }
1984           opt_formal_parameter_list CLOSE_PARENS
1985           {
1986                 valid_param_mod = 0;
1988                 Location loc = GetLocation ($2);
1989                 Operator.OpType op = (Operator.OpType) $3;
1990                 current_local_parameters = (ParametersCompiled)$6;
1991                 
1992                 int p_count = current_local_parameters.Count;
1993                 if (p_count == 1) {
1994                         if (op == Operator.OpType.Addition)
1995                                 op = Operator.OpType.UnaryPlus;
1996                         else if (op == Operator.OpType.Subtraction)
1997                                 op = Operator.OpType.UnaryNegation;
1998                 }
1999                 
2000                 if (IsUnaryOperator (op)) {
2001                         if (p_count == 2) {
2002                                 Report.Error (1020, loc, "Overloadable binary operator expected");
2003                         } else if (p_count != 1) {
2004                                 Report.Error (1535, loc, "Overloaded unary operator `{0}' takes one parameter",
2005                                         Operator.GetName (op));
2006                         }
2007                 } else {
2008                         if (p_count > 2) {
2009                                 Report.Error (1534, loc, "Overloaded binary operator `{0}' takes two parameters",
2010                                         Operator.GetName (op));
2011                         } else if (p_count != 2) {
2012                                 Report.Error (1019, loc, "Overloadable unary operator expected");
2013                         }
2014                 }
2015                 
2016                 if (RootContext.Documentation != null) {
2017                         tmpComment = Lexer.consume_doc_comment ();
2018                         Lexer.doc_state = XmlCommentState.NotAllowed;
2019                 }
2021                 $$ = new OperatorDeclaration (op, (FullNamedExpression) $1, loc);
2022           }
2023         | conversion_operator_declarator
2024         ;
2026 overloadable_operator
2027 // Unary operators:
2028         : BANG   { $$ = Operator.OpType.LogicalNot; }
2029         | TILDE  { $$ = Operator.OpType.OnesComplement; }  
2030         | OP_INC { $$ = Operator.OpType.Increment; }
2031         | OP_DEC { $$ = Operator.OpType.Decrement; }
2032         | TRUE   { $$ = Operator.OpType.True; }
2033         | FALSE  { $$ = Operator.OpType.False; }
2034 // Unary and binary:
2035         | PLUS { $$ = Operator.OpType.Addition; }
2036         | MINUS { $$ = Operator.OpType.Subtraction; }
2037 // Binary:
2038         | STAR { $$ = Operator.OpType.Multiply; }
2039         | DIV {  $$ = Operator.OpType.Division; }
2040         | PERCENT { $$ = Operator.OpType.Modulus; }
2041         | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
2042         | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
2043         | CARRET { $$ = Operator.OpType.ExclusiveOr; }
2044         | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
2045         | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
2046         | OP_EQ { $$ = Operator.OpType.Equality; }
2047         | OP_NE { $$ = Operator.OpType.Inequality; }
2048         | OP_GT { $$ = Operator.OpType.GreaterThan; }
2049         | OP_LT { $$ = Operator.OpType.LessThan; }
2050         | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
2051         | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
2052         ;
2054 conversion_operator_declarator
2055         : IMPLICIT OPERATOR type OPEN_PARENS
2056           {
2057                 valid_param_mod = ParameterModifierType.DefaultValue;
2058           }
2059           opt_formal_parameter_list CLOSE_PARENS
2060           {
2061                 valid_param_mod = 0;
2063                 Location loc = GetLocation ($2);
2064                 current_local_parameters = (ParametersCompiled)$6;  
2065                   
2066                 if (RootContext.Documentation != null) {
2067                         tmpComment = Lexer.consume_doc_comment ();
2068                         Lexer.doc_state = XmlCommentState.NotAllowed;
2069                 }
2071                 $$ = new OperatorDeclaration (Operator.OpType.Implicit, (FullNamedExpression) $3, loc);
2072           }
2073         | EXPLICIT OPERATOR type OPEN_PARENS
2074           {
2075                 valid_param_mod = ParameterModifierType.DefaultValue;
2076           }
2077           opt_formal_parameter_list CLOSE_PARENS
2078           {
2079                 valid_param_mod = 0;
2080                 
2081                 Location loc = GetLocation ($2);
2082                 current_local_parameters = (ParametersCompiled)$6;  
2083                   
2084                 if (RootContext.Documentation != null) {
2085                         tmpComment = Lexer.consume_doc_comment ();
2086                         Lexer.doc_state = XmlCommentState.NotAllowed;
2087                 }
2089                 $$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc);
2090           }
2091         | IMPLICIT error 
2092           {
2093                 Error_SyntaxError (yyToken);
2094                 current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
2095                 $$ = new OperatorDeclaration (Operator.OpType.Implicit, null, GetLocation ($1));
2096           }
2097         | EXPLICIT error 
2098           {
2099                 Error_SyntaxError (yyToken);
2100                 current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
2101                 $$ = new OperatorDeclaration (Operator.OpType.Explicit, null, GetLocation ($1));
2102           }
2103         ;
2105 constructor_declaration
2106         : constructor_declarator
2107           constructor_body
2108           { 
2109                 Constructor c = (Constructor) $1;
2110                 c.Block = (ToplevelBlock) $2;
2111                 
2112                 if (RootContext.Documentation != null)
2113                         c.DocComment = ConsumeStoredComment ();
2115                 current_container.AddConstructor (c);
2117                 current_local_parameters = null;
2118                 if (RootContext.Documentation != null)
2119                         Lexer.doc_state = XmlCommentState.Allowed;
2120           }
2121         ;
2123 constructor_declarator
2124         : opt_attributes
2125           opt_modifiers
2126           IDENTIFIER
2127           {
2128                 if (RootContext.Documentation != null) {
2129                         tmpComment = Lexer.consume_doc_comment ();
2130                         Lexer.doc_state = XmlCommentState.Allowed;
2131                 }
2132                 
2133                 valid_param_mod = ParameterModifierType.All;
2134           }
2135           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2136           {
2137                 valid_param_mod = 0;
2138                 current_local_parameters = (ParametersCompiled) $6;  
2139                 
2140                 //
2141                 // start block here, so possible anonymous methods inside
2142                 // constructor initializer can get correct parent block
2143                 //
2144                 start_block (lexer.Location);
2145           }
2146           opt_constructor_initializer
2147           {
2148                 var lt = (Tokenizer.LocatedToken) $3;
2149                 var mods = (Modifiers) $2;
2150                 ConstructorInitializer ci = (ConstructorInitializer) $9;
2152                 Constructor c = new Constructor (current_class, lt.Value, mods,
2153                         (Attributes) $1, current_local_parameters, ci, lt.Location);
2154                 
2155                 if (lt.Value != current_container.MemberName.Name) {
2156                         Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
2157                 } else if ((mods & Modifiers.STATIC) != 0) {
2158                         if ((mods & Modifiers.AccessibilityMask) != 0){
2159                                 Report.Error (515, c.Location,
2160                                         "`{0}': static constructor cannot have an access modifier",
2161                                         c.GetSignatureForError ());
2162                         }
2163                         if (ci != null) {
2164                                 Report.Error (514, c.Location,
2165                                         "`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
2166                                         c.GetSignatureForError ());
2167                         
2168                         }
2169                 }
2170                 
2171                 $$ = c;
2172           }
2173         ;
2175 constructor_body
2176         : block_prepared
2177         | SEMICOLON             { current_block = null; $$ = null; }
2178         ;
2180 opt_constructor_initializer
2181         : /* Empty */
2182         | constructor_initializer
2183         ;
2185 constructor_initializer
2186         : COLON BASE OPEN_PARENS
2187           {
2188                 ++lexer.parsing_block;
2189           }
2190           opt_argument_list CLOSE_PARENS
2191           {
2192                 --lexer.parsing_block;
2193                 $$ = new ConstructorBaseInitializer ((Arguments) $5, GetLocation ($2));
2194           }
2195         | COLON THIS OPEN_PARENS
2196           {
2197                 ++lexer.parsing_block;
2198           }
2199           opt_argument_list CLOSE_PARENS
2200           {
2201                 --lexer.parsing_block;
2202                 $$ = new ConstructorThisInitializer ((Arguments) $5, GetLocation ($2));
2203           }
2204         | COLON error {
2205                 Report.Error (1018, GetLocation ($1), "Keyword `this' or `base' expected");
2206                 $$ = null;
2207           }
2208         ;
2210 destructor_declaration
2211         : opt_attributes opt_modifiers TILDE 
2212           {
2213                 if (RootContext.Documentation != null) {
2214                         tmpComment = Lexer.consume_doc_comment ();
2215                         Lexer.doc_state = XmlCommentState.NotAllowed;
2216                 }
2217                 
2218                 current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
2219           }
2220           IDENTIFIER OPEN_PARENS CLOSE_PARENS method_body
2221           {
2222                 var lt = (Tokenizer.LocatedToken) $5;
2223                 if (lt.Value != current_container.MemberName.Name){
2224                         Report.Error (574, lt.Location, "Name of destructor must match name of class");
2225                 } else if (current_container.Kind != MemberKind.Class){
2226                         Report.Error (575, lt.Location, "Only class types can contain destructor");
2227                 } else {
2228                         Destructor d = new Destructor (current_class, (Modifiers) $2,
2229                                 ParametersCompiled.EmptyReadOnlyParameters, (Attributes) $1, lt.Location);
2230                         if (RootContext.Documentation != null)
2231                                 d.DocComment = ConsumeStoredComment ();
2232                   
2233                         d.Block = (ToplevelBlock) $8;
2234                         current_container.AddMethod (d);
2235                 }
2237                 current_local_parameters = null;
2238           }
2239         ;
2241 event_declaration
2242         : opt_attributes
2243           opt_modifiers
2244           EVENT type variable_declarators SEMICOLON
2245           {
2246                 foreach (VariableMemberDeclaration var in (List<object>) $5) {
2248                         EventField e = new EventField (
2249                                 current_class, (FullNamedExpression) $4, (Modifiers) $2, var.MemberName, (Attributes) $1);
2250                                 
2251                         e.Initializer = var.GetInitializer ((FullNamedExpression) $4);
2252                         if (current_container.Kind == MemberKind.Interface && e.Initializer != null) {
2253                                 Report.Error (68, e.Location, "`{0}': event in interface cannot have initializer", e.GetSignatureForError ());
2254                         }
2255                         
2256                         if (var.MemberName.Left != null) {
2257                                 Report.Error (71, e.Location,
2258                                         "`{0}': An explicit interface implementation of an event must use property syntax",
2259                                         e.GetSignatureForError ());
2260                         }
2262                         current_container.AddEvent (e);
2264                         if (RootContext.Documentation != null) {
2265                                 e.DocComment = Lexer.consume_doc_comment ();
2266                                 Lexer.doc_state = XmlCommentState.Allowed;
2267                         }
2268                 }
2269           }
2270         | opt_attributes
2271           opt_modifiers
2272           EVENT type member_declaration_name
2273           OPEN_BRACE
2274           {
2275                 implicit_value_parameter_type = (FullNamedExpression) $4;  
2276                 current_local_parameters = new ParametersCompiled (compiler,
2277                         new Parameter (implicit_value_parameter_type, "value", 
2278                         Parameter.Modifier.NONE, null, GetLocation ($3)));
2280                 lexer.EventParsing = true;
2281           }
2282           event_accessor_declarations
2283           {
2284                 lexer.EventParsing = false;  
2285           }
2286           CLOSE_BRACE
2287           {
2288                 MemberName name = (MemberName) $5;
2289                 
2290                 if (current_container.Kind == MemberKind.Interface) {
2291                         Report.Error (69, GetLocation ($3), "Event in interface cannot have add or remove accessors");
2292                         $8 = new Accessors (null, null);
2293                 } else if ($8 == null) {
2294                         Report.Error (65, GetLocation ($3), "`{0}.{1}': event property must have both add and remove accessors",
2295                                 current_container.GetSignatureForError (), name.GetSignatureForError ());
2296                         $8 = new Accessors (null, null);
2297                 }
2298                 
2299                 Accessors accessors = (Accessors) $8;
2301                 if (accessors.get_or_add == null || accessors.set_or_remove == null)
2302                         // CS0073 is already reported, so no CS0065 here.
2303                         $$ = null;
2304                 else {
2305                         Event e = new EventProperty (
2306                                 current_class, (FullNamedExpression) $4, (Modifiers) $2, name,
2307                                 (Attributes) $1, accessors.get_or_add, accessors.set_or_remove);
2308                         if (RootContext.Documentation != null) {
2309                                 e.DocComment = Lexer.consume_doc_comment ();
2310                                 Lexer.doc_state = XmlCommentState.Allowed;
2311                         }
2313                         current_container.AddEvent (e);
2314                         implicit_value_parameter_type = null;
2315                 }
2316                 current_local_parameters = null;
2317           }
2318         | opt_attributes opt_modifiers EVENT type member_declaration_name error
2319           {
2320                 MemberName mn = (MemberName) $5;
2321                 if (mn.Left != null)
2322                         Report.Error (71, mn.Location, "An explicit interface implementation of an event must use property syntax");
2324                 if (RootContext.Documentation != null)
2325                         Lexer.doc_state = XmlCommentState.Allowed;
2327                 Error_SyntaxError (yyToken);
2328                 $$ = null;
2329           }
2330         ;
2332 event_accessor_declarations
2333         : add_accessor_declaration remove_accessor_declaration
2334           {
2335                 $$ = new Accessors ((Accessor) $1, (Accessor) $2);
2336           }
2337         | remove_accessor_declaration add_accessor_declaration
2338           {
2339                 Accessors accessors = new Accessors ((Accessor) $2, (Accessor) $1);
2340                 accessors.declared_in_reverse = true;
2341                 $$ = accessors;
2342           }     
2343         | add_accessor_declaration  { $$ = null; } 
2344         | remove_accessor_declaration { $$ = null; } 
2345         | error
2346           { 
2347                 Report.Error (1055, GetLocation ($1), "An add or remove accessor expected");
2348                 $$ = null;
2349           }
2350         | { $$ = null; }
2351         ;
2353 add_accessor_declaration
2354         : opt_attributes ADD
2355           {
2356                 lexer.EventParsing = false;
2357           }
2358           block
2359           {
2360                 Accessor accessor = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, null, GetLocation ($2));
2361                 lexer.EventParsing = true;
2362                 $$ = accessor;
2363           }
2364         | opt_attributes ADD error {
2365                 Report.Error (73, GetLocation ($2), "An add or remove accessor must have a body");
2366                 $$ = null;
2367           }
2368         | opt_attributes modifiers ADD {
2369                 Report.Error (1609, GetLocation ($3), "Modifiers cannot be placed on event accessor declarations");
2370                 $$ = null;
2371           }
2372         ;
2374 remove_accessor_declaration
2375         : opt_attributes REMOVE
2376           {
2377                 lexer.EventParsing = false;
2378           }
2379           block
2380           {
2381                 $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, null, GetLocation ($2));
2382                 lexer.EventParsing = true;
2383           }
2384         | opt_attributes REMOVE error {
2385                 Report.Error (73, GetLocation ($2), "An add or remove accessor must have a body");
2386                 $$ = null;
2387           }
2388         | opt_attributes modifiers REMOVE {
2389                 Report.Error (1609, GetLocation ($3), "Modifiers cannot be placed on event accessor declarations");
2390                 $$ = null;
2391           }
2392         ;
2394 indexer_declaration
2395         : opt_attributes opt_modifiers
2396           member_type indexer_declaration_name OPEN_BRACKET
2397           {
2398                 valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue;
2399           }
2400           opt_formal_parameter_list CLOSE_BRACKET
2401           OPEN_BRACE
2402           {
2403                 valid_param_mod = 0;
2404                 implicit_value_parameter_type = (FullNamedExpression) $3;
2405                 indexer_parameters = (ParametersCompiled) $7;
2406                 
2407                 if (indexer_parameters.IsEmpty) {
2408                         Report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter");
2409                 }
2411                 if (RootContext.Documentation != null) {
2412                         tmpComment = Lexer.consume_doc_comment ();
2413                         Lexer.doc_state = XmlCommentState.Allowed;
2414                 }
2416                 lexer.PropertyParsing = true;
2417                 parsing_indexer  = true;
2418                 
2419           }
2420           accessor_declarations 
2421           {
2422                   lexer.PropertyParsing = false;
2423                   has_get = has_set = false;
2424                   parsing_indexer  = false;
2425           }
2426           CLOSE_BRACE
2427           { 
2428                 Accessors accessors = (Accessors) $11;
2429                 Accessor get_block = accessors != null ? accessors.get_or_add : null;
2430                 Accessor set_block = accessors != null ? accessors.set_or_remove : null;
2431                 bool order = accessors != null ? accessors.declared_in_reverse : false;
2433                 Indexer indexer = new Indexer (current_class, (FullNamedExpression) $3,
2434                         (MemberName)$4, (Modifiers) $2, (ParametersCompiled) $7, (Attributes) $1,
2435                         get_block, set_block, order);
2436                                        
2437                 if ($3 == TypeManager.system_void_expr)
2438                         Report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ());
2439                         
2440                 if (accessors == null)
2441                         Report.Error (548, indexer.Location, "`{0}': property or indexer must have at least one accessor", indexer.GetSignatureForError ());
2443                 if (current_container.Kind == MemberKind.Interface) {
2444                         if (indexer.Get.Block != null)
2445                                 Report.Error (531, indexer.Location, "`{0}.get': interface members cannot have a definition", indexer.GetSignatureForError ());
2447                         if (indexer.Set.Block != null)
2448                                 Report.Error (531, indexer.Location, "`{0}.set': interface members cannot have a definition", indexer.GetSignatureForError ());
2449                 }
2451                 if (RootContext.Documentation != null)
2452                         indexer.DocComment = ConsumeStoredComment ();
2454                 current_container.AddIndexer (indexer);
2455                 
2456                 current_local_parameters = null;
2457                 implicit_value_parameter_type = null;
2458                 indexer_parameters = null;
2459           }
2460         ;
2462 enum_declaration
2463         : opt_attributes
2464           opt_modifiers
2465           ENUM type_declaration_name
2466           opt_enum_base {
2467                 if (RootContext.Documentation != null)
2468                         enumTypeComment = Lexer.consume_doc_comment ();
2469           }
2470           enum_body
2471           opt_semicolon
2472           {
2473                 MemberName name = (MemberName) $4;
2474                 if (name.IsGeneric) {
2475                         Report.Error (1675, name.Location, "Enums cannot have type parameters");
2476                 }
2478                 name = MakeName (name);
2479                 Enum e = new Enum (current_namespace, current_class, (TypeExpr) $5, (Modifiers) $2,
2480                                    name, (Attributes) $1);
2481                 
2482                 if (RootContext.Documentation != null)
2483                         e.DocComment = enumTypeComment;
2486                 EnumMember em = null;
2487                 foreach (VariableDeclaration ev in (IList<VariableDeclaration>) $7) {
2488                         em = new EnumMember (
2489                                 e, em, ev.identifier, ev.GetInitializer ((FullNamedExpression) $5),
2490                                 ev.OptAttributes, ev.Location);
2492 //                      if (RootContext.Documentation != null)
2493                                 em.DocComment = ev.DocComment;
2495                         e.AddEnumMember (em);
2496                 }
2497                 if (RootContext.EvalMode)
2498                         undo.AddTypeContainer (current_container, e);
2500                 current_container.AddTypeContainer (e);
2502                 $$ = e;
2504           }
2505         ;
2507 opt_enum_base
2508         : /* empty */
2509           {
2510                 $$ = TypeManager.system_int32_expr;
2511           }
2512         | COLON type
2513          {
2514                 if ($2 != TypeManager.system_int32_expr && $2 != TypeManager.system_uint32_expr &&
2515                         $2 != TypeManager.system_int64_expr && $2 != TypeManager.system_uint64_expr &&
2516                         $2 != TypeManager.system_int16_expr && $2 != TypeManager.system_uint16_expr &&
2517                         $2 != TypeManager.system_byte_expr && $2 != TypeManager.system_sbyte_expr) {
2518                         Enum.Error_1008 (GetLocation ($2), Report);
2519                         $2 = TypeManager.system_int32_expr;
2520                 }
2521          
2522                 $$ = $2;
2523          }
2524         | COLON error
2525          {
2526                 Error_TypeExpected (GetLocation ($1));
2527                 $$ = TypeManager.system_int32_expr;
2528          }
2529         ;
2531 enum_body
2532         : OPEN_BRACE
2533           {
2534                 if (RootContext.Documentation != null)
2535                         Lexer.doc_state = XmlCommentState.Allowed;
2536           }
2537           opt_enum_member_declarations
2538           {
2539                 // here will be evaluated after CLOSE_BLACE is consumed.
2540                 if (RootContext.Documentation != null)
2541                         Lexer.doc_state = XmlCommentState.Allowed;
2542           }
2543           CLOSE_BRACE
2544           {
2545                 $$ = $3;
2546           }
2547         ;
2549 opt_enum_member_declarations
2550         : /* empty */                   { $$ = new VariableDeclaration [0]; }
2551         | enum_member_declarations opt_comma { $$ = $1; }
2552         ;
2554 enum_member_declarations
2555         : enum_member_declaration 
2556           {
2557                 var l = new List<VariableDeclaration> (4);
2558                 l.Add ((VariableDeclaration) $1);
2559                 $$ = l;
2560           }
2561         | enum_member_declarations COMMA enum_member_declaration
2562           {
2563                 var l = (List<VariableDeclaration>) $1;
2564                 l.Add ((VariableDeclaration) $3);
2565                 $$ = l;
2566           }
2567         ;
2569 enum_member_declaration
2570         : opt_attributes IDENTIFIER 
2571           {
2572                 VariableDeclaration vd = new VariableDeclaration (
2573                         (Tokenizer.LocatedToken) $2, null, (Attributes) $1);
2575                 if (RootContext.Documentation != null) {
2576                         vd.DocComment = Lexer.consume_doc_comment ();
2577                         Lexer.doc_state = XmlCommentState.Allowed;
2578                 }
2580                 $$ = vd;
2581           }
2582         | opt_attributes IDENTIFIER
2583           {
2584                 ++lexer.parsing_block;
2585                 if (RootContext.Documentation != null) {
2586                         tmpComment = Lexer.consume_doc_comment ();
2587                         Lexer.doc_state = XmlCommentState.NotAllowed;
2588                 }
2589           }
2590           ASSIGN constant_expression
2591           { 
2592                 --lexer.parsing_block;    
2593                 VariableDeclaration vd = new VariableDeclaration (
2594                         (Tokenizer.LocatedToken) $2, (Expression) $5, (Attributes) $1);
2596                 if (RootContext.Documentation != null)
2597                         vd.DocComment = ConsumeStoredComment ();
2599                 $$ = vd;
2600           }
2601         ;
2603 delegate_declaration
2604         : opt_attributes
2605           opt_modifiers
2606           DELEGATE
2607           member_type type_declaration_name
2608           OPEN_PARENS
2609           {
2610                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue;
2611           }
2612           opt_formal_parameter_list CLOSE_PARENS
2613           {
2614                 valid_param_mod = 0;
2616                 MemberName name = MakeName ((MemberName) $5);
2617                 ParametersCompiled p = (ParametersCompiled) $8;
2619                 Delegate del = new Delegate (current_namespace, current_class, (FullNamedExpression) $4,
2620                                              (Modifiers) $2, name, p, (Attributes) $1);
2622                 if (RootContext.Documentation != null) {
2623                         del.DocComment = Lexer.consume_doc_comment ();
2624                         Lexer.doc_state = XmlCommentState.Allowed;
2625                 }
2627                 current_container.AddDelegate (del);
2628                 current_delegate = del;
2629                 lexer.ConstraintsParsing = true;
2630           }
2631           opt_type_parameter_constraints_clauses
2632           {
2633                 lexer.ConstraintsParsing = false;
2634           }
2635           SEMICOLON
2636           {
2637                 current_delegate.SetParameterInfo ((List<Constraints>) $11);
2638                 $$ = current_delegate;
2640                 current_delegate = null;
2641           }
2642         ;
2644 opt_nullable
2645         : /* empty */
2646           {
2647                 $$ = null;
2648           }
2649         | INTERR_NULLABLE
2650           {
2651                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
2652                         Report.FeatureIsNotSupported (GetLocation ($1), "nullable types");
2653                 else if (RootContext.Version < LanguageVersion.ISO_2)
2654                         Report.FeatureIsNotAvailable (GetLocation ($1), "nullable types");
2655           
2656                 $$ = this;
2657           }
2658         ;
2660 namespace_or_type_name
2661         : member_name
2662         | qualified_alias_member IDENTIFIER opt_type_argument_list
2663           {
2664                 var lt1 = (Tokenizer.LocatedToken) $1;
2665                 var lt2 = (Tokenizer.LocatedToken) $2;
2666                 
2667                 $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
2668           }
2669         ;
2671 member_name
2672         : type_name
2673         | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list
2674           {
2675                 var lt = (Tokenizer.LocatedToken) $3;
2676                 $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location);
2677           }
2678         ;
2680 type_name
2681         : IDENTIFIER opt_type_argument_list
2682           {
2683                 var lt = (Tokenizer.LocatedToken) $1;
2684                 $$ = new MemberName (lt.Value, (TypeArguments)$2, lt.Location);   
2685           }
2686         ;
2687         
2689 // Generics arguments  (any type, without attributes)
2691 opt_type_argument_list
2692         : /* empty */                { $$ = null; } 
2693         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2694           {
2695                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
2696                         Report.FeatureIsNotSupported (GetLocation ($1), "generics");
2697                 else if (RootContext.Version < LanguageVersion.ISO_2)
2698                         Report.FeatureIsNotAvailable (GetLocation ($1), "generics");      
2699           
2700                 $$ = $2;
2701           }
2702         | OP_GENERICS_LT error
2703           {
2704                 Error_TypeExpected (lexer.Location);
2705                 $$ = new TypeArguments ();
2706           }
2707         ;
2709 type_arguments
2710         : type
2711           {
2712                 TypeArguments type_args = new TypeArguments ();
2713                 type_args.Add ((FullNamedExpression) $1);
2714                 $$ = type_args;
2715           }
2716         | type_arguments COMMA type
2717           {
2718                 TypeArguments type_args = (TypeArguments) $1;
2719                 type_args.Add ((FullNamedExpression) $3);
2720                 $$ = type_args;
2721           }       
2722         ;
2725 // Generics parameters (identifiers only, with attributes), used in type or method declarations
2727 type_declaration_name
2728         : IDENTIFIER
2729           {
2730                 lexer.parsing_generic_declaration = true;
2731           }
2732           opt_type_parameter_list
2733           {
2734                 lexer.parsing_generic_declaration = false;
2735                 var lt = (Tokenizer.LocatedToken) $1;
2736                 $$ = new MemberName (lt.Value, (TypeArguments)$3, lt.Location);   
2737           }
2738         ;
2740 member_declaration_name
2741         : method_declaration_name
2742           {
2743                 MemberName mn = (MemberName)$1;
2744                 if (mn.TypeArguments != null)
2745                         syntax_error (mn.Location, string.Format ("Member `{0}' cannot declare type arguments",
2746                                 mn.GetSignatureForError ()));
2747           }
2748         ;
2750 method_declaration_name
2751         : type_declaration_name
2752         | explicit_interface IDENTIFIER opt_type_parameter_list
2753           {
2754                 lexer.parsing_generic_declaration = false;        
2755                 var lt = (Tokenizer.LocatedToken) $2;
2756                 $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $3, lt.Location);
2757           }
2758         ;
2759         
2760 indexer_declaration_name
2761         : THIS
2762           {
2763                 lexer.parsing_generic_declaration = false;        
2764                 $$ = new MemberName (TypeContainer.DefaultIndexerName, GetLocation ($1));
2765           }
2766         | explicit_interface THIS
2767           {
2768                 lexer.parsing_generic_declaration = false;
2769                 $$ = new MemberName ((MemberName) $1, TypeContainer.DefaultIndexerName, null, GetLocation ($1));
2770           }
2771         ;
2773 explicit_interface
2774         : IDENTIFIER opt_type_argument_list DOT
2775           {
2776                 var lt = (Tokenizer.LocatedToken) $1;
2777                 $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location);
2778           }
2779         | qualified_alias_member IDENTIFIER opt_type_argument_list DOT
2780           {
2781                 var lt1 = (Tokenizer.LocatedToken) $1;
2782                 var lt2 = (Tokenizer.LocatedToken) $2;
2783                 
2784                 $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
2785           }
2786         | explicit_interface IDENTIFIER opt_type_argument_list DOT
2787           {
2788                 var lt = (Tokenizer.LocatedToken) $2;
2789                 $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $3, lt.Location);
2790           }
2791         ;
2792         
2793 opt_type_parameter_list
2794         : /* empty */                { $$ = null; } 
2795         | OP_GENERICS_LT_DECL type_parameters OP_GENERICS_GT
2796           {
2797                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
2798                         Report.FeatureIsNotSupported (GetLocation ($1), "generics");
2799                 else if (RootContext.Version < LanguageVersion.ISO_2)
2800                         Report.FeatureIsNotAvailable (GetLocation ($1), "generics");
2801           
2802                 $$ = $2;
2803           }
2804         ;
2806 type_parameters
2807         : type_parameter
2808           {
2809                 TypeArguments type_args = new TypeArguments ();
2810                 type_args.Add ((FullNamedExpression)$1);
2811                 $$ = type_args;
2812           }
2813         | type_parameters COMMA type_parameter
2814           {
2815                 TypeArguments type_args = (TypeArguments) $1;
2816                 type_args.Add ((FullNamedExpression)$3);
2817                 $$ = type_args;
2818           }       
2819         ;
2821 type_parameter
2822         : opt_attributes opt_type_parameter_variance IDENTIFIER
2823           {
2824                 var lt = (Tokenizer.LocatedToken)$3;
2825                 $$ = new TypeParameterName (lt.Value, (Attributes)$1, (Variance) $2, lt.Location);
2826           }
2827         | error
2828           {
2829                 if (GetTokenName (yyToken) == "type")
2830                         Report.Error (81, GetLocation ($1), "Type parameter declaration must be an identifier not a type");
2831                 else
2832                         Error_SyntaxError (yyToken);
2833                         
2834                 $$ = new TypeParameterName ("", null, lexer.Location);
2835           }
2836         ;
2839 // All types where void is allowed
2841 type_and_void
2842         : type_expression_or_array
2843         | VOID
2844           {
2845                 $$ = TypeManager.system_void_expr;
2846           }
2847         ;
2848         
2849 member_type
2850         : type_and_void
2851           {
2852                 lexer.parsing_generic_declaration = true;
2853           }
2854         ;
2857 // A type which does not allow `void' to be used
2859 type
2860         : type_expression_or_array
2861         | VOID
2862           {
2863                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report);
2864                 $$ = TypeManager.system_void_expr;
2865           }     
2866         ;
2867         
2868 simple_type
2869         : type_expression
2870         | VOID
2871           {
2872                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report);
2873                 $$ = TypeManager.system_void_expr;
2874           }     
2875         ;
2876         
2877 parameter_type
2878         : type_expression_or_array
2879         | VOID
2880           {
2881                 Report.Error (1536, GetLocation ($1), "Invalid parameter type `void'");
2882                 $$ = TypeManager.system_void_expr;
2883           }     
2884         ;
2886 type_expression_or_array
2887         : type_expression
2888         | type_expression rank_specifiers
2889           {
2890                 string rank_specifiers = (string) $2;
2891                 $$ = new ComposedCast ((FullNamedExpression) $1, rank_specifiers);
2892           }
2893         ;
2894         
2895 type_expression
2896         : namespace_or_type_name opt_nullable
2897           {
2898                 MemberName name = (MemberName) $1;
2900                 if ($2 != null) {
2901                         $$ = new ComposedCast (name.GetTypeExpression (), "?", lexer.Location);
2902                 } else {
2903                         if (name.Left == null && name.Name == "var")
2904                                 $$ = new VarExpr (name.Location);
2905                         else
2906                                 $$ = name.GetTypeExpression ();
2907                 }
2908           }
2909         | builtin_types opt_nullable
2910           {
2911                 if ($2 != null)
2912                         $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location);
2913           }
2914         | type_expression STAR
2915           {
2916                 //
2917                 // Note that here only unmanaged types are allowed but we
2918                 // can't perform checks during this phase - we do it during
2919                 // semantic analysis.
2920                 //
2921                 $$ = new ComposedCast ((FullNamedExpression) $1, "*", Lexer.Location);
2922           }
2923         | VOID STAR
2924           {
2925                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", GetLocation ($1));
2926           }     
2927         ;
2929 type_list
2930         : base_type_name
2931           {
2932                 var types = new List<FullNamedExpression> (2);
2933                 types.Add ((FullNamedExpression) $1);
2934                 $$ = types;
2935           }
2936         | type_list COMMA base_type_name
2937           {
2938                 var types = (List<FullNamedExpression>) $1;
2939                 types.Add ((FullNamedExpression) $3);
2940                 $$ = types;
2941           }
2942         ;
2944 base_type_name
2945         : type
2946           {
2947                 if ($1 is ComposedCast)
2948                         Report.Error (1521, GetLocation ($1), "Invalid base type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
2949                 $$ = $1;
2950           }
2951         | error
2952           {
2953                 Error_TypeExpected (lexer.Location);
2954                 $$ = null;
2955           }
2956         ;
2957         
2959  * replaces all the productions for isolating the various
2960  * simple types, but we need this to reuse it easily in variable_type
2961  */
2962 builtin_types
2963         : OBJECT        { $$ = TypeManager.system_object_expr; }
2964         | STRING        { $$ = TypeManager.system_string_expr; }
2965         | BOOL          { $$ = TypeManager.system_boolean_expr; }
2966         | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
2967         | FLOAT         { $$ = TypeManager.system_single_expr; }
2968         | DOUBLE        { $$ = TypeManager.system_double_expr; }
2969         | integral_type
2970         ;
2972 integral_type
2973         : SBYTE         { $$ = TypeManager.system_sbyte_expr; }
2974         | BYTE          { $$ = TypeManager.system_byte_expr; }
2975         | SHORT         { $$ = TypeManager.system_int16_expr; }
2976         | USHORT        { $$ = TypeManager.system_uint16_expr; }
2977         | INT           { $$ = TypeManager.system_int32_expr; }
2978         | UINT          { $$ = TypeManager.system_uint32_expr; }
2979         | LONG          { $$ = TypeManager.system_int64_expr; }
2980         | ULONG         { $$ = TypeManager.system_uint64_expr; }
2981         | CHAR          { $$ = TypeManager.system_char_expr; }
2982         ;
2984 predefined_type
2985         : builtin_types
2986         | VOID
2987           {
2988                 $$ = TypeManager.system_void_expr;      
2989           }
2990         ;
2993 // Expressions, section 7.5
2997 primary_expression
2998         : primary_expression_no_array_creation
2999         | array_creation_expression
3000         ;
3002 primary_expression_no_array_creation
3003         : literal
3004         | IDENTIFIER opt_type_argument_list
3005           {
3006                 var lt = (Tokenizer.LocatedToken) $1;
3007                 $$ = new SimpleName (MemberName.MakeName (lt.Value, (TypeArguments)$2), (TypeArguments)$2, lt.Location);          
3008           }
3009         | IDENTIFIER GENERATE_COMPLETION {
3010                 var lt = (Tokenizer.LocatedToken) $1;
3011                $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location);
3012           }
3013         | parenthesized_expression
3014         | default_value_expression
3015         | member_access
3016         | invocation_expression
3017         | element_access
3018         | this_access
3019         | base_access
3020         | post_increment_expression
3021         | post_decrement_expression
3022         | object_or_delegate_creation_expression
3023         | anonymous_type_expression
3024         | typeof_expression
3025         | sizeof_expression
3026         | checked_expression
3027         | unchecked_expression
3028         | pointer_member_access
3029         | anonymous_method_expression
3030         ;
3032 literal
3033         : boolean_literal
3034         | LITERAL
3035         | NULL                  { $$ = new NullLiteral (GetLocation ($1)); }
3036         ;
3038 boolean_literal
3039         : TRUE                  { $$ = new BoolLiteral (true, GetLocation ($1)); }
3040         | FALSE                 { $$ = new BoolLiteral (false, GetLocation ($1)); }
3041         ;
3045 // Here is the trick, tokenizer may think that parens is a special but
3046 // parser is interested in open parens only, so we merge them.
3047 // Consider: if (a)foo ();
3049 open_parens_any
3050         : OPEN_PARENS
3051         | OPEN_PARENS_CAST
3052         ;
3054 // 
3055 // Use this production to accept closing parenthesis or 
3056 // performing completion
3058 close_parens
3059         : CLOSE_PARENS
3060         | COMPLETE_COMPLETION
3061         ;
3064 parenthesized_expression
3065         : OPEN_PARENS expression CLOSE_PARENS
3066           {
3067                 $$ = new ParenthesizedExpression ((Expression) $2);
3068           }
3069         | OPEN_PARENS expression COMPLETE_COMPLETION
3070           {
3071                 $$ = new ParenthesizedExpression ((Expression) $2);
3072           }
3073         ;
3074         
3075 member_access
3076         : primary_expression DOT IDENTIFIER opt_type_argument_list
3077           {
3078                 var lt = (Tokenizer.LocatedToken) $3;
3079                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3080           }
3081         | predefined_type DOT IDENTIFIER opt_type_argument_list
3082           {
3083                 var lt = (Tokenizer.LocatedToken) $3;
3084                 // TODO: Location is wrong as some predefined types doesn't hold a location
3085                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3086           }
3087         | qualified_alias_member IDENTIFIER opt_type_argument_list
3088           {
3089                 var lt1 = (Tokenizer.LocatedToken) $1;
3090                 var lt2 = (Tokenizer.LocatedToken) $2;
3092                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
3093           }
3094         | primary_expression DOT GENERATE_COMPLETION {
3095                 $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3));
3096           }
3097         | primary_expression DOT IDENTIFIER GENERATE_COMPLETION {
3098                 var lt = (Tokenizer.LocatedToken) $3;
3099                 $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
3100           }
3101         | predefined_type DOT GENERATE_COMPLETION
3102           {
3103                 // TODO: Location is wrong as some predefined types doesn't hold a location
3104                 $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location);
3105           }
3106         | predefined_type DOT IDENTIFIER GENERATE_COMPLETION {
3107                 var lt = (Tokenizer.LocatedToken) $3;
3108                 $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
3109           }
3110         ;
3112 invocation_expression
3113         : primary_expression open_parens_any opt_argument_list close_parens
3114           {
3115                 $$ = new Invocation ((Expression) $1, (Arguments) $3);
3116           }
3117         ;
3119 opt_object_or_collection_initializer
3120         : /* empty */           { $$ = null; }
3121         | object_or_collection_initializer
3122         ;
3124 object_or_collection_initializer
3125         : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion
3126           {
3127                 if ($2 == null)
3128                         $$ = CollectionOrObjectInitializers.Empty;
3129                 else
3130                         $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
3131           }
3132         | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE
3133           {
3134                 $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
3135           }
3136         ;
3138 opt_member_initializer_list
3139         : /* empty */           { $$ = null; }
3140         | member_initializer_list
3141         {
3142                 $$ = $1;
3143         }
3144         ;
3146 member_initializer_list
3147         : member_initializer
3148           {
3149                 var a = new List<Expression> ();
3150                 a.Add ((Expression) $1);
3151                 $$ = a;
3152           }
3153         | member_initializer_list COMMA member_initializer
3154           {
3155                 var a = (List<Expression>)$1;
3156                 a.Add ((Expression) $3);
3157                 $$ = a;
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                 $$ = new CollectionElementInitializer ((List<Expression>)$2, GetLocation ($1));
3181           }
3182         | OPEN_BRACE CLOSE_BRACE
3183           {
3184                 Report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
3185                 $$ = null;
3186           }       
3187         ;
3189 initializer_value
3190         : expression
3191         | object_or_collection_initializer
3192         ;
3194 opt_argument_list
3195         : /* empty */           { $$ = null; }
3196         | argument_list
3197         ;
3199 argument_list
3200         : argument_or_named_argument
3201           { 
3202                 Arguments list = new Arguments (4);
3203                 list.Add ((Argument) $1);
3204                 $$ = list;
3205           }
3206         | argument_list COMMA argument
3207           {
3208                 Arguments list = (Arguments) $1;
3209                 if (list [list.Count - 1] is NamedArgument)
3210                         Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]);
3211                 
3212                 list.Add ((Argument) $3);
3213                 $$ = list;
3214           }
3215         | argument_list COMMA named_argument
3216           {
3217                 Arguments list = (Arguments) $1;
3218                 NamedArgument a = (NamedArgument) $3;
3219                 for (int i = 0; i < list.Count; ++i) {
3220                         NamedArgument na = list [i] as NamedArgument;
3221                         if (na != null && na.Name == a.Name)
3222                                 Report.Error (1740, na.Location, "Named argument `{0}' specified multiple times",
3223                                         na.Name);
3224                 }
3225                 
3226                 list.Add (a);
3227                 $$ = list;
3228           }
3229         | argument_list COMMA
3230           {
3231                 Report.Error (839, GetLocation ($2), "An argument is missing");
3232                 $$ = null;
3233           }
3234         | COMMA argument_or_named_argument
3235           {
3236                 Report.Error (839, GetLocation ($1), "An argument is missing");
3237                 $$ = null;
3238           }
3239         ;
3241 argument
3242         : expression
3243           {
3244                 $$ = new Argument ((Expression) $1);
3245           }
3246         | non_simple_argument
3247         ;
3249 argument_or_named_argument
3250         : argument
3251         | named_argument
3252         ;
3254 non_simple_argument
3255         : REF variable_reference 
3256           { 
3257                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3258           }
3259         | OUT variable_reference 
3260           { 
3261                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
3262           }
3263         | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
3264           {
3265                 $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1)));
3266           }
3267         | ARGLIST OPEN_PARENS CLOSE_PARENS
3268           {
3269                 $$ = new Argument (new Arglist (GetLocation ($1)));
3270           }       
3271         | ARGLIST
3272           {
3273                 $$ = new Argument (new ArglistAccess (GetLocation ($1)));
3274           }
3275         ;
3277 variable_reference
3278         : expression
3279         ;
3281 element_access
3282         : primary_expression_no_array_creation OPEN_BRACKET expression_list_arguments CLOSE_BRACKET     
3283           {
3284                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3);
3285           }
3286         | array_creation_expression OPEN_BRACKET expression_list_arguments CLOSE_BRACKET
3287           {
3288                 // LAMESPEC: Not allowed according to specification
3289                 $$ = new ElementAccess ((Expression) $1, (Arguments) $3);
3290           }     
3291         | primary_expression_no_array_creation rank_specifiers
3292           {
3293                 // So the super-trick is that primary_expression
3294                 // can only be either a SimpleName or a MemberAccess. 
3295                 // The MemberAccess case arises when you have a fully qualified type-name like :
3296                 // Foo.Bar.Blah i;
3297                 // SimpleName is when you have
3298                 // Blah i;
3299                   
3300                 Expression expr = (Expression) $1;  
3301                 if (expr is ComposedCast){
3302                         $$ = new ComposedCast ((ComposedCast)expr, (string) $2);
3303                 } else if (expr is ATypeNameExpression){
3304                         //
3305                         // So we extract the string corresponding to the SimpleName
3306                         // or MemberAccess
3307                         // 
3308                         $$ = new ComposedCast ((ATypeNameExpression)expr, (string) $2);
3309                 } else {
3310                         Error_ExpectingTypeName (expr);
3311                         $$ = TypeManager.system_object_expr;
3312                 }
3313           }
3314         ;
3316 expression_list
3317         : expression
3318           {
3319                 var list = new List<Expression> (4);
3320                 list.Add ((Expression) $1);
3321                 $$ = list;
3322           }
3323         | expression_list COMMA expression
3324           {
3325                 var list = (List<Expression>) $1;
3326                 list.Add ((Expression) $3);
3327                 $$ = list;
3328           }
3329         ;
3330         
3331 expression_list_arguments
3332         : expression_list_argument
3333           {
3334                 Arguments args = new Arguments (4);
3335                 args.Add ((Argument) $1);
3336                 $$ = args;
3337           }
3338         | expression_list_arguments COMMA expression_list_argument
3339           {
3340                 Arguments args = (Arguments) $1;
3341                 args.Add ((Argument) $3);
3342                 $$ = args;        
3343           }
3344         ;
3345         
3346 expression_list_argument
3347         : expression
3348           {
3349                 $$ = new Argument ((Expression) $1);
3350           }
3351         | named_argument
3352         ;
3354 this_access
3355         : THIS
3356           {
3357                 $$ = new This (current_block, GetLocation ($1));
3358           }
3359         ;
3361 base_access
3362         : BASE DOT IDENTIFIER opt_type_argument_list
3363           {
3364                 var lt = (Tokenizer.LocatedToken) $3;
3365                 $$ = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location);
3366           }
3367         | BASE OPEN_BRACKET expression_list_arguments CLOSE_BRACKET
3368           {
3369                 $$ = new BaseIndexerAccess ((Arguments) $3, GetLocation ($1));
3370           }
3371         | BASE error
3372           {
3373                 Error_SyntaxError (yyToken);
3374                 $$ = new BaseAccess (null, GetLocation ($2));
3375           }
3376         ;
3378 post_increment_expression
3379         : primary_expression OP_INC
3380           {
3381                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1, GetLocation ($2));
3382           }
3383         ;
3385 post_decrement_expression
3386         : primary_expression OP_DEC
3387           {
3388                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1, GetLocation ($2));
3389           }
3390         ;
3392 object_or_delegate_creation_expression
3393         : new_expr_start open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer
3394           {
3395                 if ($5 != null) {
3396                         if (RootContext.Version <= LanguageVersion.ISO_2)
3397                                 Report.FeatureIsNotAvailable (GetLocation ($1), "object initializers");
3398                                 
3399                         $$ = new NewInitialize ((Expression) $1, (Arguments) $3, (CollectionOrObjectInitializers) $5, GetLocation ($1));
3400                 }
3401                 else
3402                         $$ = new New ((Expression) $1, (Arguments) $3, GetLocation ($1));
3403           }
3404         | new_expr_start object_or_collection_initializer
3405           {
3406                 if (RootContext.Version <= LanguageVersion.ISO_2)
3407                         Report.FeatureIsNotAvailable (GetLocation ($1), "collection initializers");
3408           
3409                 $$ = new NewInitialize ((Expression) $1, null, (CollectionOrObjectInitializers) $2, GetLocation ($1));
3410           }
3411         ;
3413 array_creation_expression
3414         : new_expr_start OPEN_BRACKET expression_list CLOSE_BRACKET 
3415           opt_rank_specifier    // shift/reduce on OPEN_BRACE
3416           opt_array_initializer
3417           {
3418                 $$ = new ArrayCreation ((FullNamedExpression) $1, (List<Expression>) $3, (string) $5, (ArrayInitializer) $6, GetLocation ($1));
3419           }
3420         | new_expr_start rank_specifiers opt_array_initializer
3421           {
3422                 if ($3 == null)
3423                         Report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer");
3425                 $$ = new ArrayCreation ((FullNamedExpression) $1, (string) $2, (ArrayInitializer) $3, GetLocation ($1));
3426           }
3427         | NEW rank_specifiers array_initializer
3428           {
3429                 if (RootContext.Version <= LanguageVersion.ISO_2)
3430                         Report.FeatureIsNotAvailable (GetLocation ($1), "implicitly typed arrays");
3431           
3432                 $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayInitializer) $3, GetLocation ($1));
3433           }
3434         | new_expr_start error
3435           {
3436                 Report.Error (1526, GetLocation ($1), "A new expression requires () or [] after type");
3437                 $$ = new ArrayCreation ((FullNamedExpression) $1, "[]", null, GetLocation ($1));
3438           }
3439         ;
3441 new_expr_start
3442         : NEW
3443           {
3444                 ++lexer.parsing_type;
3445           }
3446           simple_type
3447           {
3448                 --lexer.parsing_type;
3449                 $$ = $3;
3450           }
3451         ;
3453 anonymous_type_expression
3454         : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
3455           {
3456                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
3457                         Report.FeatureIsNotSupported (GetLocation ($1), "anonymous types");
3458                 else if (RootContext.Version <= LanguageVersion.ISO_2)
3459                         Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
3461                 $$ = new NewAnonymousType ((List<AnonymousTypeParameter>) $3, current_container, GetLocation ($1));
3462           }
3463         ;
3465 anonymous_type_parameters_opt_comma
3466         : anonymous_type_parameters_opt
3467         | anonymous_type_parameters COMMA
3468         ;
3470 anonymous_type_parameters_opt
3471         : { $$ = null; }
3472         | anonymous_type_parameters
3473         ;
3475 anonymous_type_parameters
3476         : anonymous_type_parameter
3477           {
3478                 var a = new List<AnonymousTypeParameter> (4);
3479                 a.Add ((AnonymousTypeParameter) $1);
3480                 $$ = a;
3481           }
3482         | anonymous_type_parameters COMMA anonymous_type_parameter
3483           {
3484                 var a = (List<AnonymousTypeParameter>) $1;
3485                 a.Add ((AnonymousTypeParameter) $3);
3486                 $$ = a;
3487           }
3488         ;
3490 anonymous_type_parameter
3491         : IDENTIFIER ASSIGN variable_initializer
3492           {
3493                 var lt = (Tokenizer.LocatedToken)$1;
3494                 $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
3495           }
3496         | IDENTIFIER
3497           {
3498                 var lt = (Tokenizer.LocatedToken)$1;
3499                 $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
3500                         lt.Value, lt.Location);
3501           }
3502         | BASE DOT IDENTIFIER opt_type_argument_list
3503           {
3504                 var lt = (Tokenizer.LocatedToken) $3;
3505                 BaseAccess ba = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location);
3506                 $$ = new AnonymousTypeParameter (ba, lt.Value, lt.Location);            
3507           }       
3508         | member_access
3509           {
3510                 MemberAccess ma = (MemberAccess) $1;
3511                 $$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
3512           }
3513         | error
3514           {
3515                 Report.Error (746, lexer.Location,
3516                         "Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression");
3517                 $$ = null;
3518           }
3519         ;
3521 opt_rank_specifier
3522         : /* empty */
3523           {
3524                 $$ = "";
3525           }
3526         | rank_specifiers
3527           {
3528                 $$ = $1;
3529           }
3530         ;
3532 opt_rank_specifier_or_nullable
3533         : opt_nullable
3534           {
3535                 if ($1 != null)
3536                         $$ = "?";
3537                 else
3538                         $$ = string.Empty;
3539           }
3540         | opt_nullable rank_specifiers
3541           {
3542                 if ($1 != null)
3543                         $$ = "?" + (string) $2;
3544                 else
3545                         $$ = $2;
3546           }
3547         ;
3549 rank_specifiers
3550         : rank_specifier
3551         | rank_specifier rank_specifiers
3552           {
3553                 $$ = (string) $2 + (string) $1;
3554           }
3555         ;
3557 rank_specifier
3558         : OPEN_BRACKET CLOSE_BRACKET
3559           {
3560                 $$ = "[]";
3561           }
3562         | OPEN_BRACKET dim_separators CLOSE_BRACKET
3563           {
3564                 $$ = "[" + (string) $2 + "]";
3565           }
3566         | OPEN_BRACKET error
3567           {
3568                 Error_SyntaxError (178, yyToken, "Invalid rank specifier");
3569                 $$ = "[]";
3570           }
3571         ;
3573 dim_separators
3574         : COMMA
3575           {
3576                 $$ = ",";
3577           }
3578         | dim_separators COMMA
3579           {
3580                 $$ = (string) $1 + ",";
3581           }
3582         ;
3584 opt_array_initializer
3585         : /* empty */
3586           {
3587                 $$ = null;
3588           }
3589         | array_initializer
3590           {
3591                 $$ = $1;
3592           }
3593         ;
3595 array_initializer
3596         : OPEN_BRACE CLOSE_BRACE
3597           {
3598                 $$ = new ArrayInitializer (0, GetLocation ($1));
3599           }
3600         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
3601           {
3602                 $$ = new ArrayInitializer ((List<Expression>) $2, GetLocation ($1));
3603           }
3604         ;
3606 variable_initializer_list
3607         : variable_initializer
3608           {
3609                 var list = new List<Expression> (4);
3610                 list.Add ((Expression) $1);
3611                 $$ = list;
3612           }
3613         | variable_initializer_list COMMA variable_initializer
3614           {
3615                 var list = (List<Expression>) $1;
3616                 list.Add ((Expression) $3);
3617                 $$ = list;
3618           }
3619         | error
3620           {
3621                 Error_SyntaxError (yyToken);
3622                 $$ = new List<Expression> ();
3623           }
3624         ;
3626 typeof_expression
3627         : TYPEOF
3628       {
3629                 lexer.TypeOfParsing = true;
3630           }
3631           open_parens_any typeof_type_expression CLOSE_PARENS
3632           {
3633                 lexer.TypeOfParsing = false;
3634                 Expression type = (Expression)$4;
3635                 if (type == TypeManager.system_void_expr)
3636                         $$ = new TypeOfVoid (GetLocation ($1));
3637                 else
3638                         $$ = new TypeOf (type, GetLocation ($1));
3639           }
3640         ;
3641         
3642 typeof_type_expression
3643         : type_and_void
3644         | unbound_type_name
3645         | error
3646          {
3647                 Error_TypeExpected (lexer.Location);
3648                 $$ = null;
3649          }
3650         ;
3651         
3652 unbound_type_name
3653         : IDENTIFIER generic_dimension
3654           {  
3655                 var lt = (Tokenizer.LocatedToken) $1;
3657                 $$ = new SimpleName (MemberName.MakeName (lt.Value, (int)$2), lt.Location);
3658           }
3659         | qualified_alias_member IDENTIFIER generic_dimension
3660           {
3661                 var lt1 = (Tokenizer.LocatedToken) $1;
3662                 var lt2 = (Tokenizer.LocatedToken) $2;
3664                 $$ = new QualifiedAliasMember (lt1.Value, MemberName.MakeName (lt2.Value, (int) $3), lt1.Location);
3665           }
3666         | unbound_type_name DOT IDENTIFIER
3667           {
3668                 var lt = (Tokenizer.LocatedToken) $3;
3669                 
3670                 $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);         
3671           }
3672         | unbound_type_name DOT IDENTIFIER generic_dimension
3673           {
3674                 var lt = (Tokenizer.LocatedToken) $3;
3675                 
3676                 $$ = new MemberAccess ((Expression) $1, MemberName.MakeName (lt.Value, (int) $4), lt.Location);         
3677           }
3678         | namespace_or_type_name DOT IDENTIFIER generic_dimension
3679           {
3680                 var lt = (Tokenizer.LocatedToken) $3;
3681                 MemberName name = (MemberName) $1;
3683                 $$ = new MemberAccess (name.GetTypeExpression (), MemberName.MakeName (lt.Value, (int) $4), lt.Location);               
3684           }
3685         ;
3687 generic_dimension
3688         : GENERIC_DIMENSION
3689           {
3690                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
3691                         Report.FeatureIsNotSupported (GetLocation ($1), "generics");
3692                 else if (RootContext.Version < LanguageVersion.ISO_2)
3693                         Report.FeatureIsNotAvailable (GetLocation ($1), "generics");
3695                 $$ = $1;
3696           }
3697         ;
3698         
3699 qualified_alias_member
3700         : IDENTIFIER DOUBLE_COLON
3701           {
3702                 var lt = (Tokenizer.LocatedToken) $1;
3703                 if (RootContext.Version == LanguageVersion.ISO_1)
3704                         Report.FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
3706                 $$ = lt;                
3707           }
3708         ;
3710 sizeof_expression
3711         : SIZEOF open_parens_any type CLOSE_PARENS { 
3712                 $$ = new SizeOf ((Expression) $3, GetLocation ($1));
3713           }
3714         ;
3716 checked_expression
3717         : CHECKED open_parens_any expression CLOSE_PARENS
3718           {
3719                 $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
3720           }
3721         ;
3723 unchecked_expression
3724         : UNCHECKED open_parens_any expression CLOSE_PARENS
3725           {
3726                 $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
3727           }
3728         ;
3730 pointer_member_access 
3731         : primary_expression OP_PTR IDENTIFIER
3732           {
3733                 Expression deref;
3734                 var lt = (Tokenizer.LocatedToken) $3;
3736                 deref = new Indirection ((Expression) $1, lt.Location);
3737                 $$ = new MemberAccess (deref, lt.Value);
3738           }
3739         ;
3741 anonymous_method_expression
3742         : DELEGATE opt_anonymous_method_signature
3743           {
3744                 start_anonymous (false, (ParametersCompiled) $2, GetLocation ($1));
3745           }
3746           block
3747           {
3748                 $$ = end_anonymous ((ToplevelBlock) $4);
3749         }
3750         ;
3752 opt_anonymous_method_signature
3753         : 
3754           {
3755                 $$ = ParametersCompiled.Undefined;
3756           } 
3757         | anonymous_method_signature
3758         ;
3760 anonymous_method_signature
3761         : OPEN_PARENS
3762           {
3763                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
3764           }
3765           opt_formal_parameter_list CLOSE_PARENS
3766           {
3767                 valid_param_mod = 0;
3768                 $$ = $3;
3769           }
3770         ;
3772 default_value_expression
3773         : DEFAULT open_parens_any type CLOSE_PARENS
3774           {
3775                 if (RootContext.Version < LanguageVersion.ISO_2)
3776                         Report.FeatureIsNotAvailable (GetLocation ($1), "default value expression");
3778                 $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1));
3779           }
3780         ;
3782 unary_expression
3783         : primary_expression
3784         | BANG prefixed_unary_expression
3785           {
3786                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1));
3787           }
3788         | TILDE prefixed_unary_expression
3789           {
3790                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
3791           }
3792         | cast_expression
3793         ;
3795 cast_expression
3796         : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
3797           {
3798                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3799           }
3800         | OPEN_PARENS predefined_type CLOSE_PARENS prefixed_unary_expression
3801           {
3802                 $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
3803           }
3804         ;
3806         //
3807         // The idea to split this out is from Rhys' grammar
3808         // to solve the problem with casts.
3809         //
3810 prefixed_unary_expression
3811         : unary_expression
3812         | PLUS prefixed_unary_expression
3813           { 
3814                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
3815           } 
3816         | MINUS prefixed_unary_expression 
3817           { 
3818                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
3819           }
3820         | OP_INC prefixed_unary_expression 
3821           {
3822                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1));
3823           }
3824         | OP_DEC prefixed_unary_expression 
3825           {
3826                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1));
3827           }
3828         | STAR prefixed_unary_expression
3829           {
3830                 $$ = new Indirection ((Expression) $2, GetLocation ($1));
3831           }
3832         | BITWISE_AND prefixed_unary_expression
3833           {
3834                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1));
3835           }
3836         ;
3838 multiplicative_expression
3839         : prefixed_unary_expression
3840         | multiplicative_expression STAR prefixed_unary_expression
3841           {
3842                 $$ = new Binary (Binary.Operator.Multiply, 
3843                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3844           }
3845         | multiplicative_expression DIV prefixed_unary_expression
3846           {
3847                 $$ = new Binary (Binary.Operator.Division, 
3848                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3849           }
3850         | multiplicative_expression PERCENT prefixed_unary_expression 
3851           {
3852                 $$ = new Binary (Binary.Operator.Modulus, 
3853                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3854           }
3855         ;
3857 additive_expression
3858         : multiplicative_expression
3859         | additive_expression PLUS multiplicative_expression 
3860           {
3861                 $$ = new Binary (Binary.Operator.Addition, 
3862                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3863           }
3864         | additive_expression MINUS multiplicative_expression
3865           {
3866                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
3867           }
3868         | parenthesized_expression MINUS multiplicative_expression
3869           {
3870                 // Shift/Reduce conflict
3871                 $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
3872           }
3873         | additive_expression AS type
3874           {
3875                 $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
3876           }
3877         | additive_expression IS type
3878           {
3879                 $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
3880           }       
3881         ;
3883 shift_expression
3884         : additive_expression
3885         | shift_expression OP_SHIFT_LEFT additive_expression
3886           {
3887                 $$ = new Binary (Binary.Operator.LeftShift, 
3888                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3889           }
3890         | shift_expression OP_SHIFT_RIGHT additive_expression
3891           {
3892                 $$ = new Binary (Binary.Operator.RightShift, 
3893                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3894           }
3895         ; 
3897 relational_expression
3898         : shift_expression
3899         | relational_expression OP_LT shift_expression
3900           {
3901                 $$ = new Binary (Binary.Operator.LessThan, 
3902                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3903           }
3904         | relational_expression OP_GT shift_expression
3905           {
3906                 $$ = new Binary (Binary.Operator.GreaterThan, 
3907                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3908           }
3909         | relational_expression OP_LE shift_expression
3910           {
3911                 $$ = new Binary (Binary.Operator.LessThanOrEqual, 
3912                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3913           }
3914         | relational_expression OP_GE shift_expression
3915           {
3916                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
3917                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3918           }
3919         ;
3921 equality_expression
3922         : relational_expression
3923         | equality_expression OP_EQ relational_expression
3924           {
3925                 $$ = new Binary (Binary.Operator.Equality, 
3926                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3927           }
3928         | equality_expression OP_NE relational_expression
3929           {
3930                 $$ = new Binary (Binary.Operator.Inequality, 
3931                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3932           }
3933         ; 
3935 and_expression
3936         : equality_expression
3937         | and_expression BITWISE_AND equality_expression
3938           {
3939                 $$ = new Binary (Binary.Operator.BitwiseAnd, 
3940                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3941           }
3942         ;
3944 exclusive_or_expression
3945         : and_expression
3946         | exclusive_or_expression CARRET and_expression
3947           {
3948                 $$ = new Binary (Binary.Operator.ExclusiveOr, 
3949                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3950           }
3951         ;
3953 inclusive_or_expression
3954         : exclusive_or_expression
3955         | inclusive_or_expression BITWISE_OR exclusive_or_expression
3956           {
3957                 $$ = new Binary (Binary.Operator.BitwiseOr, 
3958                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3959           }
3960         ;
3962 conditional_and_expression
3963         : inclusive_or_expression
3964         | conditional_and_expression OP_AND inclusive_or_expression
3965           {
3966                 $$ = new Binary (Binary.Operator.LogicalAnd, 
3967                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3968           }
3969         ;
3971 conditional_or_expression
3972         : conditional_and_expression
3973         | conditional_or_expression OP_OR conditional_and_expression
3974           {
3975                 $$ = new Binary (Binary.Operator.LogicalOr, 
3976                                  (Expression) $1, (Expression) $3, GetLocation ($2));
3977           }
3978         ;
3979         
3980 null_coalescing_expression
3981         : conditional_or_expression
3982         | conditional_or_expression OP_COALESCING null_coalescing_expression
3983           {
3984                 if (RootContext.Version < LanguageVersion.ISO_2)
3985                         Report.FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
3986                         
3987                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, GetLocation ($2));
3988           }
3989         ;
3991 conditional_expression
3992         : null_coalescing_expression
3993         | null_coalescing_expression INTERR expression COLON expression 
3994           {
3995                 $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5);
3996           }
3997         ;
3999 assignment_expression
4000         : prefixed_unary_expression ASSIGN expression
4001           {
4002                 $$ = new SimpleAssign ((Expression) $1, (Expression) $3);
4003           }
4004         | prefixed_unary_expression OP_MULT_ASSIGN expression
4005           {
4006                 $$ = new CompoundAssign (
4007                         Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
4008           }
4009         | prefixed_unary_expression OP_DIV_ASSIGN expression
4010           {
4011                 $$ = new CompoundAssign (
4012                         Binary.Operator.Division, (Expression) $1, (Expression) $3);
4013           }
4014         | prefixed_unary_expression OP_MOD_ASSIGN expression
4015           {
4016                 $$ = new CompoundAssign (
4017                         Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
4018           }
4019         | prefixed_unary_expression OP_ADD_ASSIGN expression
4020           {
4021                 $$ = new CompoundAssign (
4022                         Binary.Operator.Addition, (Expression) $1, (Expression) $3);
4023           }
4024         | prefixed_unary_expression OP_SUB_ASSIGN expression
4025           {
4026                 $$ = new CompoundAssign (
4027                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
4028           }
4029         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
4030           {
4031                 $$ = new CompoundAssign (
4032                         Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
4033           }
4034         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
4035           {
4036                 $$ = new CompoundAssign (
4037                         Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
4038           }
4039         | prefixed_unary_expression OP_AND_ASSIGN expression
4040           {
4041                 $$ = new CompoundAssign (
4042                         Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
4043           }
4044         | prefixed_unary_expression OP_OR_ASSIGN expression
4045           {
4046                 $$ = new CompoundAssign (
4047                         Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
4048           }
4049         | prefixed_unary_expression OP_XOR_ASSIGN expression
4050           {
4051                 $$ = new CompoundAssign (
4052                         Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
4053           }
4054         ;
4056 lambda_parameter_list
4057         : lambda_parameter
4058           {
4059                 var pars = new List<Parameter> (4);
4060                 pars.Add ((Parameter) $1);
4062                 $$ = pars;
4063           }
4064         | lambda_parameter_list COMMA lambda_parameter
4065           {
4066                 var pars = (List<Parameter>) $1;
4067                 Parameter p = (Parameter)$3;
4068                 if (pars[0].GetType () != p.GetType ()) {
4069                         Report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
4070                 }
4071                 
4072                 pars.Add (p);
4073                 $$ = pars;
4074           }
4075         ;
4077 lambda_parameter
4078         : parameter_modifier parameter_type IDENTIFIER
4079           {
4080                 var lt = (Tokenizer.LocatedToken) $3;
4082                 $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
4083           }
4084         | parameter_type IDENTIFIER
4085           {
4086                 var lt = (Tokenizer.LocatedToken) $2;
4088                 $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
4089           }
4090         | IDENTIFIER
4091           {
4092                 var lt = (Tokenizer.LocatedToken) $1;
4093                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
4094           }
4095         ;
4097 opt_lambda_parameter_list
4098         : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
4099         | lambda_parameter_list         { 
4100                 var pars_list = (List<Parameter>) $1;
4101                 $$ = new ParametersCompiled (compiler, pars_list.ToArray ());
4102           }
4103         ;
4105 lambda_expression_body
4106         : {
4107                 start_block (lexer.Location);
4108           }
4109           expression 
4110           {
4111                 Block b = end_block (lexer.Location);
4112                 b.AddStatement (new ContextualReturn ((Expression) $2));
4113                 $$ = b;
4114           } 
4115         | block { 
4116                 $$ = $1; 
4117           } 
4118         ;
4120 lambda_expression
4121         : IDENTIFIER ARROW 
4122           {
4123                 var lt = (Tokenizer.LocatedToken) $1;
4124                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4125                 start_anonymous (true, new ParametersCompiled (compiler, p), GetLocation ($1));
4126           }
4127           lambda_expression_body
4128           {
4129                 $$ = end_anonymous ((ToplevelBlock) $4);
4130           }
4131         | OPEN_PARENS_LAMBDA
4132           {
4133                 if (RootContext.Version <= LanguageVersion.ISO_2)
4134                         Report.FeatureIsNotAvailable (GetLocation ($1), "lambda expressions");
4135           
4136                 valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
4137           }
4138           opt_lambda_parameter_list CLOSE_PARENS ARROW 
4139           {
4140                 valid_param_mod = 0;
4141                 start_anonymous (true, (ParametersCompiled) $3, GetLocation ($1));
4142           }
4143           lambda_expression_body 
4144           {
4145                 $$ = end_anonymous ((ToplevelBlock) $7);
4146           }
4147         ;
4149 expression
4150         : assignment_expression 
4151         | non_assignment_expression 
4152         ;
4153         
4154 non_assignment_expression
4155         : conditional_expression
4156         | lambda_expression
4157         | query_expression 
4158         ;
4160 constant_expression
4161         : expression
4162         ;
4164 boolean_expression
4165         : expression
4166           {
4167                 $$ = new BooleanExpression ((Expression) $1);
4168           }
4169         ;
4172 // 10 classes
4174 class_declaration
4175         : opt_attributes
4176           opt_modifiers
4177           opt_partial
4178           CLASS
4179           {
4180                 lexer.ConstraintsParsing = true;
4181           }
4182           type_declaration_name
4183           {
4184                 MemberName name = MakeName ((MemberName) $6);
4185                 push_current_class (new Class (current_namespace, current_class, name, (Modifiers) $2, (Attributes) $1), $3);
4186           }
4187           opt_class_base
4188           opt_type_parameter_constraints_clauses
4189           {
4190                 lexer.ConstraintsParsing = false;
4192                 current_class.SetParameterInfo ((List<Constraints>) $9);
4194                 if (RootContext.Documentation != null) {
4195                         current_container.DocComment = Lexer.consume_doc_comment ();
4196                         Lexer.doc_state = XmlCommentState.Allowed;
4197                 }
4198           }
4199           class_body
4200           {
4201                 --lexer.parsing_declaration;      
4202                 if (RootContext.Documentation != null)
4203                         Lexer.doc_state = XmlCommentState.Allowed;
4204           }
4205           opt_semicolon 
4206           {
4207                 $$ = pop_current_class ();
4208           }
4209         ;       
4211 opt_partial
4212         : /* empty */
4213           { $$ = null; }
4214         | PARTIAL
4215           { $$ = $1; } // location
4216         ;
4218 opt_modifiers
4219         : /* empty */           { $$ = (int) 0; }
4220         | modifiers
4221         ;
4223 modifiers
4224         : modifier
4225         | modifiers modifier
4226           { 
4227                 var m1 = (Modifiers) $1;
4228                 var m2 = (Modifiers) $2;
4230                 if ((m1 & m2) != 0) {
4231                         Location l = lexer.Location;
4232                         Report.Error (1004, l, "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2));
4233                 }
4234                 $$ = m1 | m2;
4235           }
4236         ;
4238 modifier
4239         : NEW
4240           {
4241                 $$ = Modifiers.NEW;
4242                 if (current_container == RootContext.ToplevelTypes)
4243                         Report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements");
4244           }
4245         | PUBLIC                { $$ = Modifiers.PUBLIC; }
4246         | PROTECTED             { $$ = Modifiers.PROTECTED; }
4247         | INTERNAL              { $$ = Modifiers.INTERNAL; }
4248         | PRIVATE               { $$ = Modifiers.PRIVATE; }
4249         | ABSTRACT              { $$ = Modifiers.ABSTRACT; }
4250         | SEALED                { $$ = Modifiers.SEALED; }
4251         | STATIC                { $$ = Modifiers.STATIC; }
4252         | READONLY              { $$ = Modifiers.READONLY; }
4253         | VIRTUAL               { $$ = Modifiers.VIRTUAL; }
4254         | OVERRIDE              { $$ = Modifiers.OVERRIDE; }
4255         | EXTERN                { $$ = Modifiers.EXTERN; }
4256         | VOLATILE              { $$ = Modifiers.VOLATILE; }
4257         | UNSAFE                { $$ = Modifiers.UNSAFE; }
4258         ;
4260 opt_class_base
4261         : /* empty */
4262         | class_base
4263         ;
4265 class_base
4266         : COLON type_list
4267          {
4268                 current_container.AddBasesForPart (current_class, (List<FullNamedExpression>) $2);
4269          }
4270         ;
4272 opt_type_parameter_constraints_clauses
4273         : /* empty */           { $$ = null; }
4274         | type_parameter_constraints_clauses 
4275           {
4276                 $$ = $1;
4277           }
4278         ;
4280 type_parameter_constraints_clauses
4281         : type_parameter_constraints_clause
4282           {
4283                 var constraints = new List<Constraints> (1);
4284                 constraints.Add ((Constraints) $1);
4285                 $$ = constraints;
4286           }
4287         | type_parameter_constraints_clauses type_parameter_constraints_clause
4288           {
4289                 var constraints = (List<Constraints>) $1;
4290                 Constraints new_constraint = (Constraints)$2;
4292                 foreach (Constraints c in constraints) {
4293                         if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) {
4294                                 Report.Error (409, new_constraint.Location,
4295                                         "A constraint clause has already been specified for type parameter `{0}'",
4296                                         new_constraint.TypeParameter.Value);
4297                         }
4298                 }
4300                 constraints.Add (new_constraint);
4301                 $$ = constraints;
4302           }
4303         ; 
4305 type_parameter_constraints_clause
4306         : WHERE IDENTIFIER COLON type_parameter_constraints
4307           {
4308                 var lt = (Tokenizer.LocatedToken) $2;
4309                 $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List<FullNamedExpression>) $4, GetLocation ($1));
4310           }
4311         ; 
4313 type_parameter_constraints
4314         : type_parameter_constraint
4315           {
4316                 var constraints = new List<FullNamedExpression> (1);
4317                 constraints.Add ((FullNamedExpression) $1);
4318                 $$ = constraints;
4319           }
4320         | type_parameter_constraints COMMA type_parameter_constraint
4321           {
4322                 var constraints = (List<FullNamedExpression>) $1;
4323                 var prev = constraints [constraints.Count - 1] as SpecialContraintExpr;
4324                 if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) {                   
4325                         Report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified");
4326                 }
4327                 
4328                 prev = $3 as SpecialContraintExpr;
4329                 if (prev != null) {
4330                         if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) {
4331                                 Report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified");                 
4332                         } else {
4333                                 prev = constraints [0] as SpecialContraintExpr;
4334                                 if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) {                        
4335                                         Report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint");
4336                                 }
4337                         }
4338                 }
4340                 constraints.Add ((FullNamedExpression) $3);
4341                 $$ = constraints;
4342           }
4343         ;
4345 type_parameter_constraint
4346         : type
4347           {
4348                 $$ = $1;
4349           }
4350         | NEW OPEN_PARENS CLOSE_PARENS
4351           {
4352                 $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1));
4353           }
4354         | CLASS
4355           {
4356                 $$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1));
4357           }
4358         | STRUCT
4359           {
4360                 $$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1));
4361           }
4362         ;
4364 opt_type_parameter_variance
4365         : /* empty */
4366           {
4367                 $$ = Variance.None;
4368           }
4369         | type_parameter_variance
4370           {
4371                 if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)        
4372                         Report.FeatureIsNotSupported (lexer.Location, "generic type variance");
4373                 else if (RootContext.Version <= LanguageVersion.V_3)
4374                         Report.FeatureIsNotAvailable (lexer.Location, "generic type variance");
4376                 $$ = $1;
4377           }
4378         ;
4380 type_parameter_variance
4381         : OUT
4382           {
4383                 $$ = Variance.Covariant;
4384           }
4385         | IN
4386           {
4387                 $$ = Variance.Contravariant;
4388           }
4389         ;
4392 // Statements (8.2)
4396 // A block is "contained" on the following places:
4397 //      method_body
4398 //      property_declaration as part of the accessor body (get/set)
4399 //      operator_declaration
4400 //      constructor_declaration
4401 //      destructor_declaration
4402 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
4403 //      
4404 block
4405         : OPEN_BRACE  
4406           {
4407                 ++lexer.parsing_block;
4408                 start_block (GetLocation ($1));
4409           } 
4410           opt_statement_list block_end
4411           {
4412                 $$ = $4;
4413           }
4414         ;
4416 block_end 
4417         : CLOSE_BRACE 
4418           {
4419                 --lexer.parsing_block;
4420                 $$ = end_block (GetLocation ($1));
4421           }
4422         | COMPLETE_COMPLETION
4423           {
4424                 --lexer.parsing_block;
4425                 $$ = end_block (lexer.Location);
4426           }
4427         ;
4430 block_prepared
4431         : OPEN_BRACE
4432           {
4433                 ++lexer.parsing_block;
4434                 current_block.StartLocation = GetLocation ($1);
4435           }
4436           opt_statement_list CLOSE_BRACE 
4437           {
4438                 --lexer.parsing_block;
4439                 $$ = end_block (GetLocation ($4));
4440           }
4441         ;
4443 opt_statement_list
4444         : /* empty */
4445         | statement_list 
4446         ;
4448 statement_list
4449         : statement
4450         | statement_list statement
4451         ;
4453 statement
4454         : declaration_statement
4455           {
4456                 if ($1 != null && (Block) $1 != current_block){
4457                         current_block.AddStatement ((Statement) $1);
4458                         current_block = (Block) $1;
4459                 }
4460           }
4461         | valid_declaration_statement
4462           {
4463                 current_block.AddStatement ((Statement) $1);
4464           }
4465         | labeled_statement
4466         ;
4469 // The interactive_statement and its derivatives are only 
4470 // used to provide a special version of `expression_statement'
4471 // that has a side effect of assigning the expression to
4472 // $retval
4474 interactive_statement_list
4475         : interactive_statement
4476         | interactive_statement_list interactive_statement
4477         ;
4479 interactive_statement
4480         : declaration_statement
4481           {
4482                 if ($1 != null && (Block) $1 != current_block){
4483                         current_block.AddStatement ((Statement) $1);
4484                         current_block = (Block) $1;
4485                 }
4486           }
4487         | interactive_valid_declaration_statement
4488           {
4489                 current_block.AddStatement ((Statement) $1);
4490           }
4491         | labeled_statement
4492         ;
4494 valid_declaration_statement
4495         : block
4496         | empty_statement
4497         | expression_statement
4498         | selection_statement
4499         | iteration_statement
4500         | jump_statement                  
4501         | try_statement
4502         | checked_statement
4503         | unchecked_statement
4504         | lock_statement
4505         | using_statement
4506         | unsafe_statement
4507         | fixed_statement
4508         ;
4510 interactive_valid_declaration_statement
4511         : block
4512         | empty_statement
4513         | interactive_expression_statement
4514         | selection_statement
4515         | iteration_statement
4516         | jump_statement                  
4517         | try_statement
4518         | checked_statement
4519         | unchecked_statement
4520         | lock_statement
4521         | using_statement
4522         | unsafe_statement
4523         | fixed_statement
4524         ;
4526 embedded_statement
4527         : valid_declaration_statement
4528         | declaration_statement
4529           {
4530                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4531                   $$ = null;
4532           }
4533         | labeled_statement
4534           {
4535                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4536                   $$ = null;
4537           }
4538         ;
4540 empty_statement
4541         : SEMICOLON
4542           {
4543                   $$ = EmptyStatement.Value;
4544           }
4545         ;
4547 labeled_statement
4548         : IDENTIFIER COLON 
4549           {
4550                 var lt = (Tokenizer.LocatedToken) $1;
4551                 LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location);
4553                 if (current_block.AddLabel (labeled))
4554                         current_block.AddStatement (labeled);
4555           }
4556           statement
4557         ;
4559 declaration_statement
4560         : local_variable_declaration SEMICOLON
4561           {
4562                 if ($1 != null){
4563                         var de = (Tuple<FullNamedExpression, List<object>>) $1;
4564                         $$ = declare_local_variables (de.Item1, de.Item2, de.Item1.Location);
4565                 }
4566           }
4568         | local_constant_declaration SEMICOLON
4569           {
4570                 if ($1 != null){
4571                         var de = (Tuple<FullNamedExpression, List<object>>) $1;
4573                         $$ = declare_local_constants (de.Item1, de.Item2);
4574                 }
4575           }
4576         ;
4578 /* 
4579  * The following is from Rhys' grammar:
4580  * > Types in local variable declarations must be recognized as 
4581  * > expressions to prevent reduce/reduce errors in the grammar.
4582  * > The expressions are converted into types during semantic analysis.
4583  */
4584 variable_type
4585         : primary_expression_no_array_creation opt_rank_specifier_or_nullable
4586           { 
4587                 // FIXME: Do something smart here regarding the composition of the type.
4589                 // Ok, the above "primary_expression" is there to get rid of
4590                 // both reduce/reduce and shift/reduces in the grammar, it should
4591                 // really just be "type_name".  If you use type_name, a reduce/reduce
4592                 // creeps up.  If you use namespace_or_type_name (which is all we need
4593                 // really) two shift/reduces appear.
4594                 // 
4596                 // So the super-trick is that primary_expression
4597                 // can only be either a SimpleName or a MemberAccess. 
4598                 // The MemberAccess case arises when you have a fully qualified type-name like :
4599                 // Foo.Bar.Blah i;
4600                 // SimpleName is when you have
4601                 // Blah i;
4602                 
4603                 Expression expr = (Expression) $1;
4604                 string rank_or_nullable = (string) $2;
4605                 
4606                 if (expr is ComposedCast){
4607                         $$ = new ComposedCast ((ComposedCast)expr, rank_or_nullable);
4608                 } else if (expr is ATypeNameExpression){
4609                         //
4610                         // So we extract the string corresponding to the SimpleName
4611                         // or MemberAccess
4612                         //
4613                         if (rank_or_nullable.Length == 0) {
4614                                 SimpleName sn = expr as SimpleName;
4615                                 if (sn != null && sn.Name == "var")
4616                                         $$ = new VarExpr (sn.Location);
4617                                 else
4618                                         $$ = $1;
4619                         } else {
4620                                 $$ = new ComposedCast ((ATypeNameExpression)expr, rank_or_nullable);
4621                         }
4622                 } else {
4623                         Error_ExpectingTypeName (expr);
4624                         $$ = TypeManager.system_object_expr;
4625                 }
4626           }
4627         | builtin_types opt_rank_specifier_or_nullable
4628           {
4629                 if ((string) $2 == "")
4630                         $$ = $1;
4631                 else
4632                         $$ = new ComposedCast ((FullNamedExpression) $1, (string) $2, lexer.Location);
4633           }
4634         | VOID opt_rank_specifier
4635           {
4636                 Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report);
4637                 $$ = TypeManager.system_void_expr;
4638           }
4639         ;
4641 local_variable_pointer_type
4642         : primary_expression_no_array_creation STAR
4643           {
4644                 ATypeNameExpression expr = $1 as ATypeNameExpression;
4646                 if (expr != null) {
4647                         $$ = new ComposedCast (expr, "*");
4648                 } else {
4649                         Error_ExpectingTypeName ((Expression)$1);
4650                         $$ = expr;
4651                 }
4652           }
4653         | builtin_types STAR
4654           {
4655                 $$ = new ComposedCast ((FullNamedExpression) $1, "*", GetLocation ($1));
4656           }
4657         | VOID STAR
4658           {
4659                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", GetLocation ($1));
4660           }
4661         | local_variable_pointer_type STAR
4662           {
4663                 $$ = new ComposedCast ((FullNamedExpression) $1, "*");
4664           }
4665         ;
4667 local_variable_type
4668         : variable_type
4669         | local_variable_pointer_type opt_rank_specifier
4670           {
4671                 if ($1 != null){
4672                         string rank = (string)$2;
4674                         if (rank == "")
4675                                 $$ = $1;
4676                         else
4677                                 $$ = new ComposedCast ((FullNamedExpression) $1, rank);
4678                 } else {
4679                         $$ = null;
4680                 }
4681           }
4682         ;
4684 local_variable_declaration
4685         : local_variable_type local_variable_declarators
4686           {
4687                 if ($1 != null) {
4688                         VarExpr ve = $1 as VarExpr;
4689                         if (ve != null) {
4690                                 if (!((VariableDeclaration) ((List<object>)$2) [0]).HasInitializer)
4691                                         ve.VariableInitializersCount = 0;
4692                                 else
4693                                         ve.VariableInitializersCount = ((List<object>)$2).Count;
4694                         }
4695                                 
4696                         $$ = new Tuple<FullNamedExpression, List<object>> ((FullNamedExpression) $1, (List<object>) $2);
4697                 } else
4698                         $$ = null;
4699           }
4700         ;
4702 local_constant_declaration
4703         : CONST variable_type constant_declarators
4704           {
4705                 if ($2 != null)
4706                         $$ = new Tuple<FullNamedExpression, List<object>> ((FullNamedExpression) $2, (List<object>) $3);
4707                 else
4708                         $$ = null;
4709           }
4710         ;
4712 expression_statement
4713         : statement_expression SEMICOLON { $$ = $1; }
4714         | statement_expression COMPLETE_COMPLETION { $$ = $1; }
4715         ;
4717 interactive_expression_statement
4718         : interactive_statement_expression SEMICOLON { $$ = $1; }
4719         | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; }
4720         ;
4722         //
4723         // We have to do the wrapping here and not in the case above,
4724         // because statement_expression is used for example in for_statement
4725         //
4726 statement_expression
4727         : expression
4728           {
4729                 ExpressionStatement s = $1 as ExpressionStatement;
4730                 if (s == null) {
4731                         Expression.Error_InvalidExpressionStatement (Report, GetLocation ($1));
4732                         s = EmptyExpressionStatement.Instance;
4733                 }
4735                 $$ = new StatementExpression (s);
4736           }
4737         | error
4738           {
4739                 Error_SyntaxError (yyToken);
4740                 $$ = null;
4741           }
4742         ;
4744 interactive_statement_expression
4745         : expression
4746           {
4747                 Expression expr = (Expression) $1;
4748                 ExpressionStatement s;
4750                 s = new OptionalAssign (new SimpleName ("$retval", lexer.Location), expr, lexer.Location);
4751                 $$ = new StatementExpression (s);
4752           }
4753         | error
4754           {
4755                 Error_SyntaxError (yyToken);
4756                 $$ = EmptyStatement.Value;
4757           }
4758         ;
4759         
4760 selection_statement
4761         : if_statement
4762         | switch_statement
4763         ; 
4765 if_statement
4766         : IF open_parens_any boolean_expression CLOSE_PARENS 
4767           embedded_statement
4768           { 
4769                 Location l = GetLocation ($1);
4771                 $$ = new If ((BooleanExpression) $3, (Statement) $5, l);
4773                 // FIXME: location for warning should be loc property of $5.
4774                 if ($5 == EmptyStatement.Value)
4775                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4777           }
4778         | IF open_parens_any boolean_expression CLOSE_PARENS
4779           embedded_statement ELSE embedded_statement
4780           {
4781                 Location l = GetLocation ($1);
4783                 $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, l);
4785                 // FIXME: location for warning should be loc property of $5 and $7.
4786                 if ($5 == EmptyStatement.Value)
4787                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4788                 if ($7 == EmptyStatement.Value)
4789                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4790           }
4791         ;
4793 switch_statement
4794         : SWITCH open_parens_any
4795           { 
4796                 if (switch_stack == null)
4797                         switch_stack = new Stack<Block> (2);
4798                 switch_stack.Push (current_block);
4799           }
4800           expression CLOSE_PARENS 
4801           switch_block
4802           {
4803                 $$ = new Switch ((Expression) $4, (List<SwitchSection>) $6, GetLocation ($1));
4804                 current_block = (Block) switch_stack.Pop ();
4805           }
4806         ;
4808 switch_block
4809         : OPEN_BRACE
4810           opt_switch_sections
4811           CLOSE_BRACE
4812           {
4813                 $$ = $2;
4814           }
4815         ;
4817 opt_switch_sections
4818         : /* empty */           
4819           {
4820                 Report.Warning (1522, 1, lexer.Location, "Empty switch block"); 
4821                 $$ = new List<SwitchSection> ();
4822           }
4823         | switch_sections
4824         ;
4826 switch_sections
4827         : switch_section 
4828           {
4829                 var sections = new List<SwitchSection> (4);
4831                 sections.Add ((SwitchSection) $1);
4832                 $$ = sections;
4833           }
4834         | switch_sections switch_section
4835           {
4836                 var sections = (List<SwitchSection>) $1;
4838                 sections.Add ((SwitchSection) $2);
4839                 $$ = sections;
4840           }
4841         ;
4843 switch_section
4844         : switch_labels
4845           {
4846                 current_block = current_block.CreateSwitchBlock (lexer.Location);
4847           }
4848           statement_list 
4849           {
4850                 $$ = new SwitchSection ((List<SwitchLabel>) $1, current_block.Explicit);
4851           }
4852         ;
4854 switch_labels
4855         : switch_label 
4856           {
4857                 var labels = new List<SwitchLabel> (4);
4859                 labels.Add ((SwitchLabel) $1);
4860                 $$ = labels;
4861           }
4862         | switch_labels switch_label 
4863           {
4864                 var labels = (List<SwitchLabel>) ($1);
4865                 labels.Add ((SwitchLabel) $2);
4867                 $$ = labels;
4868           }
4869         ;
4871 switch_label
4872         : CASE constant_expression COLON
4873          {
4874                 $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
4875          }
4876         | DEFAULT_COLON
4877           {
4878                 $$ = new SwitchLabel (null, GetLocation ($1));
4879           }
4880         ;
4882 iteration_statement
4883         : while_statement
4884         | do_statement
4885         | for_statement
4886         | foreach_statement
4887         ;
4889 while_statement
4890         : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement
4891           {
4892                 Location l = GetLocation ($1);
4893                 $$ = new While ((BooleanExpression) $3, (Statement) $5, l);
4894           }
4895         ;
4897 do_statement
4898         : DO embedded_statement 
4899           WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
4900           {
4901                 Location l = GetLocation ($1);
4903                 $$ = new Do ((Statement) $2, (BooleanExpression) $5, l);
4904           }
4905         ;
4907 for_statement
4908         : FOR open_parens_any opt_for_initializer SEMICOLON
4909           {
4910                 Location l = lexer.Location;
4911                 start_block (l);  
4912                 Block assign_block = current_block;
4914                 if ($3 is Tuple<FullNamedExpression, List<object>>){
4915                         var de = (Tuple<FullNamedExpression, List<object>>) $3;
4916                         
4917                         var type = de.Item1;
4919                         foreach (VariableDeclaration decl in de.Item2){
4921                                 LocalInfo vi;
4923                                 vi = current_block.AddVariable (type, decl.identifier, decl.Location);
4924                                 if (vi == null)
4925                                         continue;
4927                                 Expression expr = decl.GetInitializer (type);
4928                                         
4929                                 LocalVariableReference var;
4930                                 var = new LocalVariableReference (assign_block, decl.identifier, l);
4932                                 if (expr != null) {
4933                                         Assign a = new SimpleAssign (var, expr, decl.Location);
4934                                         
4935                                         assign_block.AddStatement (new StatementExpression (a));
4936                                 }
4937                         }
4938                         
4939                         // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal.
4940                         // This can be referred to as $5 below.
4941                         $$ = null;
4942                 } else {
4943                         $$ = $3;
4944                 }
4945           } 
4946           opt_for_condition SEMICOLON
4947           opt_for_iterator CLOSE_PARENS 
4948           embedded_statement
4949           {
4950                 Location l = GetLocation ($1);
4952                 For f = new For ((Statement) $5, (BooleanExpression) $6, (Statement) $8, (Statement) $10, l);
4954                 current_block.AddStatement (f);
4956                 $$ = end_block (lexer.Location);
4957           }
4958         ;
4960 opt_for_initializer
4961         : /* empty */           { $$ = EmptyStatement.Value; }
4962         | for_initializer       
4963         ;
4965 for_initializer
4966         : local_variable_declaration
4967         | statement_expression_list
4968         ;
4970 opt_for_condition
4971         : /* empty */           { $$ = null; }
4972         | boolean_expression
4973         ;
4975 opt_for_iterator
4976         : /* empty */           { $$ = EmptyStatement.Value; }
4977         | for_iterator
4978         ;
4980 for_iterator
4981         : statement_expression_list
4982         ;
4984 statement_expression_list
4985         : statement_expression  
4986           {
4987                 // CHANGE: was `null'
4988                 Statement s = (Statement) $1;
4989                 Block b = new Block (current_block, s.loc, lexer.Location);   
4991                 b.AddStatement (s);
4992                 $$ = b;
4993           }
4994         | statement_expression_list COMMA statement_expression
4995           {
4996                 Block b = (Block) $1;
4998                 b.AddStatement ((Statement) $3);
4999                 $$ = $1;
5000           }
5001         ;
5003 foreach_statement
5004         : FOREACH open_parens_any type IN expression CLOSE_PARENS
5005           {
5006                 Report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement");
5007                 $$ = null;
5008           }
5009         | FOREACH open_parens_any type IDENTIFIER IN
5010           expression CLOSE_PARENS 
5011           {
5012                 start_block (lexer.Location);
5013                 Block foreach_block = current_block;
5015                 var lt = (Tokenizer.LocatedToken) $4;
5016                 Location l = lt.Location;
5017                 LocalInfo vi = foreach_block.AddVariable ((Expression) $3, lt.Value, l);
5018                 if (vi != null) {
5019                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach);
5021                         // Get a writable reference to this read-only variable.
5022                         //
5023                         // Note that the $$ here refers to the value of _this_ code block,
5024                         // not the value of the LHS non-terminal.  This can be referred to as $8 below.
5025                         $$ = new LocalVariableReference (foreach_block, lt.Value, l, vi, false);
5026                 } else {
5027                         $$ = null;
5028                 }
5029           } 
5030           embedded_statement 
5031           {
5032                 LocalVariableReference v = (LocalVariableReference) $8;
5033                 Location l = GetLocation ($1);
5035                 if (v != null) {
5036                         Foreach f = new Foreach ((Expression) $3, v, (Expression) $6, (Statement) $9, l);
5037                         current_block.AddStatement (f);
5038                 }
5040                 $$ = end_block (lexer.Location);
5041           }
5042         ;
5044 jump_statement
5045         : break_statement
5046         | continue_statement
5047         | goto_statement
5048         | return_statement
5049         | throw_statement
5050         | yield_statement
5051         ;
5053 break_statement
5054         : BREAK SEMICOLON
5055           {
5056                 $$ = new Break (GetLocation ($1));
5057           }
5058         ;
5060 continue_statement
5061         : CONTINUE SEMICOLON
5062           {
5063                 $$ = new Continue (GetLocation ($1));
5064           }
5065         ;
5067 goto_statement
5068         : GOTO IDENTIFIER SEMICOLON 
5069           {
5070                 var lt = (Tokenizer.LocatedToken) $2;
5071                 $$ = new Goto (lt.Value, lt.Location);
5072           }
5073         | GOTO CASE constant_expression SEMICOLON
5074           {
5075                 $$ = new GotoCase ((Expression) $3, GetLocation ($1));
5076           }
5077         | GOTO DEFAULT SEMICOLON 
5078           {
5079                 $$ = new GotoDefault (GetLocation ($1));
5080           }
5081         ; 
5083 return_statement
5084         : RETURN opt_expression SEMICOLON
5085           {
5086                 $$ = new Return ((Expression) $2, GetLocation ($1));
5087           }
5088         ;
5090 throw_statement
5091         : THROW opt_expression SEMICOLON
5092           {
5093                 $$ = new Throw ((Expression) $2, GetLocation ($1));
5094           }
5095         ;
5097 yield_statement 
5098         : IDENTIFIER RETURN expression SEMICOLON
5099           {
5100                 var lt = (Tokenizer.LocatedToken) $1;
5101                 string s = lt.Value;
5102                 if (s != "yield"){
5103                         Report.Error (1003, lt.Location, "; expected");
5104                         $$ = null;
5105                 }
5106                 if (RootContext.Version == LanguageVersion.ISO_1){
5107                         Report.FeatureIsNotAvailable (lt.Location, "yield statement");
5108                         $$ = null;
5109                 }
5110                 current_block.Toplevel.IsIterator = true;
5111                 $$ = new Yield ((Expression) $3, lt.Location); 
5112           }
5113         | IDENTIFIER RETURN SEMICOLON
5114           {
5115                 Report.Error (1627, GetLocation ($2), "Expression expected after yield return");
5116                 $$ = null;
5117           }
5118         | IDENTIFIER BREAK SEMICOLON
5119           {
5120                 var lt = (Tokenizer.LocatedToken) $1;
5121                 string s = lt.Value;
5122                 if (s != "yield"){
5123                         Report.Error (1003, lt.Location, "; expected");
5124                         $$ = null;
5125                 }
5126                 if (RootContext.Version == LanguageVersion.ISO_1){
5127                         Report.FeatureIsNotAvailable (lt.Location, "yield statement");
5128                         $$ = null;
5129                 }
5130                 
5131                 current_block.Toplevel.IsIterator = true;
5132                 $$ = new YieldBreak (lt.Location);
5133           }
5134         ;
5136 opt_expression
5137         : /* empty */
5138         | expression
5139         ;
5141 try_statement
5142         : TRY block catch_clauses
5143           {
5144                 $$ = new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), false);
5145           }
5146         | TRY block FINALLY block
5147           {
5148                 $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1));
5149           }
5150         | TRY block catch_clauses FINALLY block
5151           {
5152                 $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), true), (Block) $5, GetLocation ($1));
5153           }
5154         | TRY block error 
5155           {
5156                 Report.Error (1524, GetLocation ($1), "Expected catch or finally");
5157                 $$ = null;
5158           }
5159         ;
5161 catch_clauses
5162         : catch_clause 
5163           {
5164                 var l = new List<Catch> (2);
5166                 l.Add ((Catch) $1);
5167                 $$ = l;
5168           }
5169         | catch_clauses catch_clause
5170           {
5171                 var l = (List<Catch>) $1;
5172                 
5173                 Catch c = (Catch) $2;
5174                 if (l [0].IsGeneral) {
5175                         Report.Error (1017, c.loc, "Try statement already has an empty catch block");
5176                 } else {
5177                         if (c.IsGeneral)
5178                                 l.Insert (0, c);
5179                         else
5180                                 l.Add (c);
5181                 }
5182                 
5183                 $$ = l;
5184           }
5185         ;
5187 opt_identifier
5188         : /* empty */   { $$ = null; }
5189         | IDENTIFIER
5190         ;
5192 catch_clause 
5193         : CATCH opt_catch_args 
5194           {
5195                 if ($2 != null) {
5196                         var cc = (Tuple<FullNamedExpression, Tokenizer.LocatedToken>) $2;
5197                         var lt = cc.Item2;
5199                         if (lt != null){
5200                                 List<object> one = new List<object> (1);
5202                                 one.Add (new VariableDeclaration (lt, null));
5204                                 start_block (lexer.Location);
5205                                 current_block = declare_local_variables (cc.Item1, one, lt.Location);
5206                         }
5207                 }
5208           } block {
5209                 Expression type = null;
5210                 string id = null;
5211                 Block var_block = null;
5213                 if ($2 != null){
5214                         var cc = (Tuple<FullNamedExpression, Tokenizer.LocatedToken>) $2;
5215                         type = cc.Item1;
5216                         var lt = cc.Item2;
5218                         if (lt != null){
5219                                 id = lt.Value;
5220                                 var_block = end_block (lexer.Location);
5221                         }
5222                 }
5224                 $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc);
5225           }
5226         ;
5228 opt_catch_args
5229         : /* empty */ { $$ = null; }
5230         | catch_args
5231         ;         
5233 catch_args 
5234         : open_parens_any type opt_identifier CLOSE_PARENS 
5235           {
5236                 $$ = new Tuple<FullNamedExpression, Tokenizer.LocatedToken> ((FullNamedExpression)$2, (Tokenizer.LocatedToken) $3);
5237           }
5238         | open_parens_any CLOSE_PARENS 
5239           {
5240                 Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected");
5241                 $$ = null;
5242           }
5243         ;
5245 checked_statement
5246         : CHECKED block
5247           {
5248                 $$ = new Checked ((Block) $2);
5249           }
5250         ;
5252 unchecked_statement
5253         : UNCHECKED block
5254           {
5255                 $$ = new Unchecked ((Block) $2);
5256           }
5257         ;
5259 unsafe_statement
5260         : UNSAFE 
5261           {
5262                 RootContext.CheckUnsafeOption (GetLocation ($1), Report);
5263           } block {
5264                 $$ = new Unsafe ((Block) $3);
5265           }
5266         ;
5268 fixed_statement
5269         : FIXED open_parens_any 
5270           type_and_void fixed_pointer_declarators 
5271           CLOSE_PARENS
5272           {
5273                 start_block (lexer.Location);
5274           }
5275           embedded_statement 
5276           {
5277                 Expression type = (Expression) $3;
5278                 var list = (List<KeyValuePair<Tokenizer.LocatedToken, Expression>>) $4;
5279                 Fixed f = new Fixed (type,
5280                         list.ConvertAll (i => {
5281                                 var v = new KeyValuePair<LocalInfo, Expression> (current_block.AddVariable (type, i.Key.Value, i.Key.Location), i.Value);
5282                                 if (v.Key != null) {
5283                                         v.Key.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
5284                                         v.Key.Pinned = true;
5285                                 }
5286                                 return v;
5287                         }), (Statement) $7, GetLocation ($1));
5289                 current_block.AddStatement (f);
5291                 $$ = end_block (lexer.Location);
5292           }
5293         ;
5295 fixed_pointer_declarators
5296         : fixed_pointer_declarator      { 
5297                 var declarators = new List<KeyValuePair<Tokenizer.LocatedToken, Expression>> (2);
5298                 if ($1 != null)
5299                         declarators.Add ((KeyValuePair<Tokenizer.LocatedToken, Expression>)$1);
5300                 $$ = declarators;
5301           }
5302         | fixed_pointer_declarators COMMA fixed_pointer_declarator
5303           {
5304                 var declarators = (List<KeyValuePair<Tokenizer.LocatedToken, Expression>>) $1;
5305                 if ($3 != null)
5306                         declarators.Add ((KeyValuePair<Tokenizer.LocatedToken, Expression>)$3);
5307                 $$ = declarators;
5308           }
5309         ;
5311 fixed_pointer_declarator
5312         : IDENTIFIER ASSIGN expression
5313           {
5314                 var lt = (Tokenizer.LocatedToken) $1;
5315                 $$ = new KeyValuePair<Tokenizer.LocatedToken, Expression> (lt, (Expression) $3);
5316           }
5317         | IDENTIFIER
5318           {
5319                 Report.Error (210, ((Tokenizer.LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration");
5320                 $$ = null;
5321           }
5322         ;
5324 lock_statement
5325         : LOCK open_parens_any expression CLOSE_PARENS 
5326           {
5327                 //
5328           } 
5329           embedded_statement
5330           {
5331                 $$ = new Lock ((Expression) $3, (Statement) $6, GetLocation ($1));
5332           }
5333         ;
5335 using_statement
5336         : USING open_parens_any local_variable_declaration CLOSE_PARENS
5337           {
5338                 start_block (lexer.Location);
5339                 Block assign_block = current_block;
5341                 var de = (Tuple<FullNamedExpression, List<object>>) $3;
5342                 Location l = GetLocation ($1);
5344                 var vars = new Stack<Tuple<LocalVariableReference, Expression>> ();
5346                 foreach (VariableDeclaration decl in de.Item2) {
5347                         LocalInfo vi = current_block.AddVariable (de.Item1, decl.identifier, decl.Location);
5348                         if (vi == null)
5349                                 continue;
5350                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
5352                         Expression expr = decl.GetInitializer (de.Item1);
5353                         if (expr == null) {
5354                                 Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
5355                                 continue;
5356                         }
5357                         LocalVariableReference var;
5359                         // Get a writable reference to this read-only variable.
5360                         var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
5362                         // This is so that it is not a warning on using variables
5363                         vi.Used = true;
5365                         vars.Push (new Tuple<LocalVariableReference, Expression> (var, expr));
5367                         // Assign a = new SimpleAssign (var, expr, decl.Location);
5368                         // assign_block.AddStatement (new StatementExpression (a));
5369                 }
5371                 // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
5372                 // It can be referred to as $5 below.
5373                 $$ = vars;
5374           }
5375           embedded_statement
5376           {
5377                 Statement stmt = (Statement) $6;
5378                 var vars = (Stack<Tuple<LocalVariableReference, Expression>>) $5;
5379                 Location l = GetLocation ($1);
5381                 while (vars.Count > 0) {
5382                           var de = vars.Pop ();
5383                           stmt = new Using (de.Item1, de.Item2, stmt, l);
5384                 }
5385                 current_block.AddStatement (stmt);
5386                 $$ = end_block (lexer.Location);
5387           }
5388         | USING open_parens_any expression CLOSE_PARENS
5389           {
5390                 start_block (lexer.Location);
5391           }
5392           embedded_statement
5393           {
5394                 current_block.AddStatement (new UsingTemporary ((Expression) $3, (Statement) $6, GetLocation ($1)));
5395                 $$ = end_block (lexer.Location);
5396           }
5397         ; 
5400 // LINQ
5402 query_expression
5403         : first_from_clause query_body 
5404           {
5405                 lexer.query_parsing = false;
5406                         
5407                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5408                         
5409                 from.Tail.Next = (Linq.AQueryClause)$2;
5410                 $$ = from;
5411                 
5412                 current_block.SetEndLocation (lexer.Location);
5413                 current_block = current_block.Parent;
5414           }
5415         | nested_from_clause query_body
5416           {
5417                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5418                         
5419                 from.Tail.Next = (Linq.AQueryClause)$2;
5420                 $$ = from;
5421                 
5422                 current_block.SetEndLocation (lexer.Location);
5423                 current_block = current_block.Parent;
5424           }     
5426         // Bubble up COMPLETE_COMPLETION productions
5427         | first_from_clause COMPLETE_COMPLETION {
5428                 lexer.query_parsing = false;
5429                 $$ = $1;
5431                 current_block.SetEndLocation (lexer.Location);
5432                 current_block = current_block.Parent;
5433           }
5434         | nested_from_clause COMPLETE_COMPLETION {
5435                 $$ = $1;
5436                 current_block.SetEndLocation (lexer.Location);
5437                 current_block = current_block.Parent;
5438           }
5439         ;
5440         
5441 first_from_clause
5442         : FROM_FIRST IDENTIFIER IN expression
5443           {
5444                 $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4));
5445                 var lt = (Tokenizer.LocatedToken) $2;
5446                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5447           }
5448         | FROM_FIRST type IDENTIFIER IN expression
5449           {
5450                 var lt = (Tokenizer.LocatedToken) $3;
5451                 $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5));
5452                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5453           }
5454         ;
5456 nested_from_clause
5457         : FROM IDENTIFIER IN expression
5458           {
5459                 $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4));
5460                 var lt = (Tokenizer.LocatedToken) $2;
5461                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5462           }
5463         | FROM type IDENTIFIER IN expression
5464           {
5465                 $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5));
5466                 var lt = (Tokenizer.LocatedToken) $3;
5467                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5468           }
5469         ;
5470         
5471 from_clause
5472         : FROM IDENTIFIER IN
5473           {
5474                 current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1));
5475           }
5476           expression
5477           {
5478                 var lt = (Tokenizer.LocatedToken) $2;
5479                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5480                 $$ = new Linq.SelectMany (current_block.Toplevel, sn, (Expression)$5);
5481                 
5482                 current_block.SetEndLocation (lexer.Location);
5483                 current_block = current_block.Parent;
5484                 
5485                 ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5486           }       
5487         | FROM type IDENTIFIER IN
5488           {
5489                 current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1));
5490           }
5491           expression
5492           {
5493                 var lt = (Tokenizer.LocatedToken) $3;
5494                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5496                 FullNamedExpression type = (FullNamedExpression)$2;
5497                 
5498                 $$ = new Linq.SelectMany (current_block.Toplevel, sn, new Linq.Cast (type, (FullNamedExpression)$6));
5499                 
5500                 current_block.SetEndLocation (lexer.Location);
5501                 current_block = current_block.Parent;
5502                 
5503                 ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5504           }
5505         ;       
5507 query_body
5508         : opt_query_body_clauses select_or_group_clause opt_query_continuation 
5509           {
5510                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5511                 
5512                 if ($3 != null)
5513                         head.Next = (Linq.AQueryClause)$3;
5514                                 
5515                 if ($1 != null) {
5516                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5517                         clause.Tail.Next = head;
5518                         head = clause;
5519                 }
5520                 
5521                 $$ = head;
5522           }
5523         | opt_query_body_clauses COMPLETE_COMPLETION
5524         ;
5525         
5526 select_or_group_clause
5527         : SELECT
5528           {
5529                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5530           }
5531           expression
5532           {
5533                 $$ = new Linq.Select (current_block.Toplevel, (Expression)$3, GetLocation ($1));
5535                 current_block.SetEndLocation (lexer.Location);
5536                 current_block = current_block.Parent;
5537           }
5538         | GROUP
5539           {
5540                 if (linq_clause_blocks == null)
5541                         linq_clause_blocks = new Stack<Block> ();
5542                         
5543                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5544                 linq_clause_blocks.Push (current_block);
5545           }
5546           expression
5547           {
5548                 current_block.SetEndLocation (lexer.Location);
5549                 current_block = current_block.Parent;
5550           
5551                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5552           }
5553           BY expression
5554           {
5555                 $$ = new Linq.GroupBy (current_block.Toplevel, (Expression)$3, (ToplevelBlock) linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1));
5556                 
5557                 current_block.SetEndLocation (lexer.Location);
5558                 current_block = current_block.Parent;
5559           }
5560         ;
5561         
5562 opt_query_body_clauses
5563         : /* empty */
5564         | query_body_clauses
5565         ;
5566         
5567 query_body_clauses
5568         : query_body_clause
5569         | query_body_clauses query_body_clause
5570           {
5571                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
5572                 $$ = $1;
5573           }
5574         ;
5575         
5576 query_body_clause
5577         : from_clause
5578         | let_clause 
5579         | where_clause
5580         | join_clause
5581         | orderby_clause
5582         ;
5583         
5584 let_clause
5585         : LET IDENTIFIER ASSIGN 
5586           {
5587                 current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1));
5588           }
5589           expression
5590           {
5591                 var lt = (Tokenizer.LocatedToken) $2;
5592                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5593                 $$ = new Linq.Let (current_block.Toplevel, current_container, sn, (Expression)$5);
5594                 
5595                 current_block.SetEndLocation (lexer.Location);
5596                 current_block = current_block.Parent;
5597                 
5598                 ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5599           }
5600         ;
5602 where_clause
5603         : WHERE
5604           {
5605                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5606           }
5607           boolean_expression
5608           {
5609                 $$ = new Linq.Where (current_block.Toplevel, (BooleanExpression)$3, GetLocation ($1));
5611                 current_block.SetEndLocation (lexer.Location);
5612                 current_block = current_block.Parent;
5613           }
5614         ;
5615         
5616 join_clause
5617         : JOIN IDENTIFIER IN
5618           {
5619                 if (linq_clause_blocks == null)
5620                         linq_clause_blocks = new Stack<Block> ();
5621                         
5622                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5623                 linq_clause_blocks.Push (current_block);
5624           }
5625           expression ON
5626           {
5627                 current_block.SetEndLocation (lexer.Location);
5628                 current_block = current_block.Parent;
5630                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5631                 linq_clause_blocks.Push (current_block);
5632           }
5633           expression EQUALS
5634           {
5635                 current_block.AddStatement (new ContextualReturn ((Expression) $8));
5636                 current_block.SetEndLocation (lexer.Location);
5637                 current_block = current_block.Parent;
5639                 var lt = (Tokenizer.LocatedToken) $2;
5640                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), lexer.Location);
5641           }
5642           expression opt_join_into
5643           {
5644                 var lt = (Tokenizer.LocatedToken) $2;
5645                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5646                 SimpleMemberName sn2 = null;
5647                 
5648                 ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop ();
5649                 ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop ();
5651                 if ($12 == null) {
5652                         $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, current_block.Toplevel, GetLocation ($1));
5653                 } else {
5654                         var lt2 = (Tokenizer.LocatedToken) $12;
5655                         sn2 = new SimpleMemberName (lt2.Value, lt2.Location);
5656                         $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, current_block.Toplevel,
5657                                 sn2, GetLocation ($1));
5658                 }
5660                 current_block.AddStatement (new ContextualReturn ((Expression) $11));
5661                 current_block.SetEndLocation (lexer.Location);
5662                 current_block = current_block.Parent;
5663                         
5664                 if (sn2 == null)
5665                         ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5666                 else
5667                         ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2);
5668           }
5669         | JOIN type IDENTIFIER IN
5670           {
5671                 if (linq_clause_blocks == null)
5672                         linq_clause_blocks = new Stack<Block> ();
5673                         
5674                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5675                 linq_clause_blocks.Push (current_block);
5676           }
5677           expression ON
5678           {
5679                 current_block.SetEndLocation (lexer.Location);
5680                 current_block = current_block.Parent;
5682                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5683                 linq_clause_blocks.Push (current_block);
5684           }
5685           expression EQUALS
5686           {
5687                 current_block.AddStatement (new ContextualReturn ((Expression) $9));
5688                 current_block.SetEndLocation (lexer.Location);
5689                 current_block = current_block.Parent;
5691                 var lt = (Tokenizer.LocatedToken) $3;
5692                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), lexer.Location);
5693           }
5694           expression opt_join_into
5695           {
5696                 var lt = (Tokenizer.LocatedToken) $3;
5697                 var sn = new SimpleMemberName (lt.Value, lt.Location);
5698                 SimpleMemberName sn2 = null;
5699                 ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop ();
5700                 ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop ();
5701                 
5702                 Linq.Cast cast = new Linq.Cast ((FullNamedExpression)$2, (Expression)$6);
5703                 if ($13 == null) {
5704                         $$ = new Linq.Join (block, sn, cast, outer_selector, current_block.Toplevel, GetLocation ($1));
5705                 } else {
5706                         var lt2 = (Tokenizer.LocatedToken) $13;
5707                         sn2 = new SimpleMemberName (lt2.Value, lt2.Location);
5708                         $$ = new Linq.GroupJoin (block, sn, cast, outer_selector, current_block.Toplevel,
5709                                 sn2, GetLocation ($1));
5710                 }
5711                 
5712                 current_block.AddStatement (new ContextualReturn ((Expression) $12));
5713                 current_block.SetEndLocation (lexer.Location);
5714                 current_block = current_block.Parent;
5715                         
5716                 if (sn2 == null)
5717                         ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn);
5718                 else
5719                         ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2);
5720           }
5721         ;
5722         
5723 opt_join_into
5724         : /* empty */
5725         | INTO IDENTIFIER
5726           {
5727                 $$ = $2;
5728           }
5729         ;
5730         
5731 orderby_clause
5732         : ORDERBY
5733           {
5734                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5735           }
5736           orderings
5737           {
5738                 current_block.SetEndLocation (lexer.Location);
5739                 current_block = current_block.Parent;
5740           
5741                 $$ = $3;
5742           }
5743         ;
5744         
5745 orderings
5746         : order_by
5747         | order_by COMMA
5748           {
5749                 current_block.SetEndLocation (lexer.Location);
5750                 current_block = current_block.Parent;
5751           
5752                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);
5753           }
5754           orderings_then_by
5755           {
5756                 ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4;
5757                 $$ = $1;
5758           }
5759         ;
5760         
5761 orderings_then_by
5762         : then_by
5763         | orderings_then_by COMMA
5764          {
5765                 current_block.SetEndLocation (lexer.Location);
5766                 current_block = current_block.Parent;
5767           
5768                 current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location);   
5769          }
5770          then_by
5771          {
5772                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$3;
5773                 $$ = $1;
5774          }
5775         ;       
5776         
5777 order_by
5778         : expression
5779           {
5780                 $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1);        
5781           }
5782         | expression ASCENDING
5783           {
5784                 $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1);        
5785           }
5786         | expression DESCENDING
5787           {
5788                 $$ = new Linq.OrderByDescending (current_block.Toplevel, (Expression)$1);       
5789           }
5790         ;
5792 then_by
5793         : expression
5794           {
5795                 $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); 
5796           }
5797         | expression ASCENDING
5798           {
5799                 $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); 
5800           }
5801         | expression DESCENDING
5802           {
5803                 $$ = new Linq.ThenByDescending (current_block.Toplevel, (Expression)$1);        
5804           }     
5805         ;
5808 opt_query_continuation
5809         : /* empty */
5810         | INTO IDENTIFIER
5811           {
5812                 // query continuation block is not linked with query block but with block
5813                 // before. This means each query can use same range variable names for
5814                 // different identifiers.
5816                 current_block.SetEndLocation (GetLocation ($1));
5817                 current_block = current_block.Parent;
5819                 var lt = (Tokenizer.LocatedToken) $2;
5820                 
5821                 current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
5822           }
5823           query_body
5824           {
5825                 $$ = new Linq.QueryExpression (current_block, (Linq.AQueryClause)$4);
5826           }
5827         ;
5828         
5830 // Support for using the compiler as an interactive parser
5832 // The INTERACTIVE_PARSER token is first sent to parse our
5833 // productions;  If the result is a Statement, the parsing
5834 // is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
5835 // to setup the blocks in advance.
5837 // This setup is here so that in the future we can add 
5838 // support for other constructs (type parsing, namespaces, etc)
5839 // that do not require a block to be setup in advance
5842 interactive_parsing
5843         : EVAL_STATEMENT_PARSER EOF 
5844         | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives 
5845         | EVAL_STATEMENT_PARSER { 
5846                 Evaluator.LoadAliases (current_namespace);
5848                 push_current_class (new Class (current_namespace, current_class, new MemberName ("Class" + class_count++),
5849                         Modifiers.PUBLIC, null), null);
5851                 var baseclass_list = new List<FullNamedExpression> ();
5852                 baseclass_list.Add (new TypeExpression (Evaluator.InteractiveBaseClass, lexer.Location));
5853                 current_container.AddBasesForPart (current_class, baseclass_list);
5855                 // (ref object retval)
5856                 Parameter [] mpar = new Parameter [1];
5857                 mpar [0] = new Parameter (TypeManager.system_object_expr, "$retval", Parameter.Modifier.REF, null, Location.Null);
5859                 ParametersCompiled pars = new ParametersCompiled (compiler, mpar);
5860                 current_local_parameters = pars;
5861                 Method method = new Method (
5862                         current_class,
5863                         null, // generic
5864                         TypeManager.system_void_expr,
5865                         Modifiers.PUBLIC | Modifiers.STATIC,
5866                         new MemberName ("Host"),
5867                         pars,
5868                         null /* attributes */);
5870                 oob_stack.Push (method);
5871                 ++lexer.parsing_block;
5872                 start_block (lexer.Location);
5873           }             
5874           interactive_statement_list opt_COMPLETE_COMPLETION
5875           {
5876                 --lexer.parsing_block;
5877                 Method method = (Method) oob_stack.Pop ();
5879                 method.Block = (ToplevelBlock) end_block(lexer.Location);
5880                 current_container.AddMethod (method);
5882                 --lexer.parsing_declaration;
5883                 InteractiveResult = pop_current_class ();
5884                 current_local_parameters = null;
5885           } 
5886         | EVAL_COMPILATION_UNIT_PARSER {
5887                 Evaluator.LoadAliases (current_namespace);
5888           }
5889           interactive_compilation_unit
5890         ;
5892 interactive_compilation_unit
5893         : outer_declarations 
5894         | outer_declarations global_attributes 
5895         | global_attributes 
5896         | /* nothing */
5897         ;
5899 opt_COMPLETE_COMPLETION
5900         : /* nothing */
5901         | COMPLETE_COMPLETION
5902         ;
5904 close_brace_or_complete_completion
5905         : CLOSE_BRACE
5906         | COMPLETE_COMPLETION
5907         ;
5910 // <summary>
5911 //   A class used to pass around variable declarations and constants
5912 // </summary>
5913 class VariableDeclaration {
5914         public string identifier;
5915         Expression initializer;
5916         public Location Location;
5917         public Attributes OptAttributes;
5918         public string DocComment;
5920         public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer, Attributes opt_attrs)
5921         {
5922                 this.identifier = lt.Value;
5923                 this.initializer = initializer;
5924                 this.Location = lt.Location;
5925                 this.OptAttributes = opt_attrs;
5926         }
5928         public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer)
5929                 : this (lt, initializer, null)
5930         {
5931         }
5933         public Expression GetInitializer (FullNamedExpression type)
5934         {
5935                 if (initializer is ArrayInitializer)
5936                         return new ArrayCreation (type, "", (ArrayInitializer)initializer, Location);
5938                 return initializer;
5939         }
5941         public bool HasInitializer {
5942                 get { return initializer != null; }
5943         }
5946 class VariableMemberDeclaration
5948         public readonly MemberName MemberName;
5949         Expression initializer;
5950         
5951         public VariableMemberDeclaration (MemberName mn, Expression initializer)
5952         {
5953                 MemberName = mn;
5954                 this.initializer = initializer;
5955         }
5957         public Expression GetInitializer (FullNamedExpression type)
5958         {
5959                 if (initializer is ArrayInitializer)
5960                         return new ArrayCreation (type, "", (ArrayInitializer)initializer, MemberName.Location);
5962                 return initializer;
5963         }
5967 // <summary>
5968 //  A class used to hold info about an operator declarator
5969 // </summary>
5970 struct OperatorDeclaration {
5971         public readonly Operator.OpType optype;
5972         public readonly FullNamedExpression ret_type;
5973         public readonly Location location;
5975         public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
5976         {
5977                 optype = op;
5978                 this.ret_type = ret_type;
5979                 this.location = location;
5980         }
5983 void Error_ExpectingTypeName (Expression expr)
5985         if (expr is Invocation){
5986                 Report.Error (1002, expr.Location, "Expecting `;'");
5987         } else {
5988                 Expression.Error_InvalidExpressionStatement (Report, expr.Location);
5989         }
5992 void Error_ParameterModifierNotValid (string modifier, Location loc)
5994         Report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
5995                                       modifier);
5998 void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
6000         Report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
6001                 Parameter.GetModifierSignature (mod));
6004 void Error_TypeExpected (Location loc)
6006         Report.Error (1031, loc, "Type expected");
6009 void Error_NamedArgumentExpected (NamedArgument a)
6011         Report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
6014 void push_current_class (TypeContainer tc, object partial_token)
6016         if (RootContext.EvalMode){
6017                 tc.ModFlags = (tc.ModFlags & ~(Modifiers.PRIVATE|Modifiers.INTERNAL)) | Modifiers.PUBLIC;
6018                 undo.AddTypeContainer (current_container, tc);
6019         }
6021         if (partial_token != null)
6022                 current_container = current_container.AddPartial (tc);
6023         else
6024                 current_container = current_container.AddTypeContainer (tc);
6026         ++lexer.parsing_declaration;
6027         current_class = tc;
6030 DeclSpace pop_current_class ()
6032         DeclSpace retval = current_class;
6034         current_class = current_class.Parent;
6035         current_container = current_class.PartialContainer;
6037         return retval;
6040 // <summary>
6041 //   Given the @class_name name, it creates a fully qualified name
6042 //   based on the containing declaration space
6043 // </summary>
6044 MemberName
6045 MakeName (MemberName class_name)
6047         Namespace ns = current_namespace.NS;
6049         if (current_container == RootContext.ToplevelTypes) {
6050                 if (ns.Name.Length != 0)
6051                         return new MemberName (ns.MemberName, class_name);
6052                 else
6053                         return class_name;
6054         } else {
6055                 return new MemberName (current_container.MemberName, class_name);
6056         }
6059 Block declare_local_variables (FullNamedExpression type, List<object> variable_declarators, Location loc)
6061         Block implicit_block;
6063         //
6064         // If we are doing interactive editing, we want variable declarations
6065         // that are in the top block to be added instead to the class as 
6066         // static variables
6067         //
6068         if (RootContext.StatementMode){
6069                 bool hoist = true;
6071                 for (Block b = current_block; b != null; b = b.Parent){
6072                         if (b is ExplicitBlock && !(b is ToplevelBlock)){
6073                                 // There has been an explicit block, we cant add to the class
6074                                 hoist = false;
6075                                 break;
6076                         }
6077                 }               
6078                 if (hoist){
6079                         //
6080                         // We can use "current_block" since we know there are no explicit blocks
6081                         //
6082                         foreach (VariableDeclaration decl in variable_declarators){
6083                                 // We can not use the super-handy f.Initializer, because
6084                                 // multiple lines would force code to be executed out of sync
6085                                 var init = decl.GetInitializer (type);
6086                                 if (init != null){
6087                                         string id = "$" + decl.identifier;
6088                                         LocalInfo vi = current_block.AddVariable (type, id, decl.Location);                                     
6090                                         // Avoid warning about this variable not being used.
6091                                         vi.Used = true;
6093                                         LocalVariableReference var;
6094                                         var = new LocalVariableReferenceWithClassSideEffect (current_container, decl.identifier, current_block, id, vi, decl.Location);
6095                                         Assign assign = new SimpleAssign (var, init, decl.Location);
6096                                         current_block.AddStatement (new StatementExpression (assign));
6097                                         assign = new SimpleAssign (new SimpleName (decl.identifier, decl.Location), var);
6098                                         current_block.AddStatement (new StatementExpression (assign));
6099                                 } else {
6100                                         Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.PUBLIC | Modifiers.STATIC,
6101                                                 new MemberName (decl.identifier, loc), null);
6102                                         current_container.AddField (f);
6104                                         // Register the field to be visible later as a global variable
6105                                         Evaluator.QueueField (f);
6106                                 }
6107                         }
6109                         return current_block;
6110                 }
6111         }
6113         //
6114         // We use the `Used' property to check whether statements
6115         // have been added to the current block.  If so, we need
6116         // to create another block to contain the new declaration
6117         // otherwise, as an optimization, we use the same block to
6118         // add the declaration.
6119         //
6120         // FIXME: A further optimization is to check if the statements
6121         // that were added were added as part of the initialization
6122         // below.  In which case, no other statements have been executed
6123         // and we might be able to reduce the number of blocks for
6124         // situations like this:
6125         //
6126         // int j = 1;  int k = j + 1;
6127         //
6128         if (current_block.Used)
6129                 implicit_block = new Block (current_block, loc, lexer.Location);
6130         else
6131                 implicit_block = current_block;
6133         foreach (VariableDeclaration decl in variable_declarators){
6135                 if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) {
6136                         if (decl.HasInitializer){
6137                                 Assign assign;
6138                                 
6139                                 var lvr = new LocalVariableReference (implicit_block, decl.identifier, loc);
6141                                 assign = new SimpleAssign (lvr, decl.GetInitializer (type), decl.Location);
6143                                 implicit_block.AddStatement (new StatementExpression (assign));
6144                         }
6145                 }
6146         }
6147         
6148         return implicit_block;
6151 Block declare_local_constants (FullNamedExpression type, List<object> declarators)
6153         Block implicit_block;
6155         if (current_block.Used)
6156                 implicit_block = new Block (current_block);
6157         else
6158                 implicit_block = current_block;
6160         foreach (VariableDeclaration decl in declarators){
6161                 implicit_block.AddConstant (type, decl.identifier, decl.GetInitializer (type), decl.Location);
6162         }
6163         
6164         return implicit_block;
6167 string CheckAttributeTarget (string a, Location l)
6169         switch (a) {
6170         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
6171                         return a;
6172         }
6174         Report.Warning (658, 1, l,
6175                  "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
6176         return string.Empty;
6179 static bool IsUnaryOperator (Operator.OpType op)
6181         switch (op) {
6182                 
6183         case Operator.OpType.LogicalNot: 
6184         case Operator.OpType.OnesComplement: 
6185         case Operator.OpType.Increment:
6186         case Operator.OpType.Decrement:
6187         case Operator.OpType.True: 
6188         case Operator.OpType.False: 
6189         case Operator.OpType.UnaryPlus: 
6190         case Operator.OpType.UnaryNegation:
6191                 return true;
6192         }
6193         return false;
6196 void syntax_error (Location l, string msg)
6198         Report.Error (1003, l, "Syntax error, " + msg);
6201 Tokenizer lexer;
6203 public Tokenizer Lexer {
6204         get {
6205                 return lexer;
6206         }
6207 }                  
6209 static CSharpParser ()
6211         oob_stack = new Stack<object> ();
6214 public CSharpParser (SeekableStreamReader reader, CompilationUnit file, CompilerContext ctx)
6216         if (RootContext.EvalMode)
6217                 undo = new Undo ();
6219         this.file = file;
6220         this.compiler = ctx;
6221         current_namespace = new NamespaceEntry (null, file, null);
6222         current_class = current_namespace.SlaveDeclSpace;
6223         current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
6224         oob_stack.Clear ();
6225         lexer = new Tokenizer (reader, file, ctx);
6226         
6227         use_global_stacks = true;
6230 public void parse ()
6232         eof_token = Token.EOF;
6233         Tokenizer.LocatedToken.Initialize ();
6234         
6235         try {
6236                 if (yacc_verbose_flag > 1)
6237                         yyparse (lexer, new yydebug.yyDebugSimple ());
6238                 else
6239                         yyparse (lexer);
6240                         
6241                 Tokenizer tokenizer = lexer as Tokenizer;
6242                 tokenizer.cleanup ();           
6243         } catch (Exception e){
6244                 if (e is yyParser.yyUnexpectedEof)
6245                         UnexpectedEOF = true;
6247                 if (e is yyParser.yyException)
6248                         Report.Error (-25, lexer.Location, "Parsing error");
6249                 else if (yacc_verbose_flag > 0)
6250                         throw;  // Used by compiler-tester to test internal errors
6251                 else 
6252                         Report.Error (589, lexer.Location, "Internal compiler error during parsing");
6253         }
6255         if (RootContext.ToplevelTypes.NamespaceEntry != null)
6256                 throw new InternalErrorException ("who set it?");
6259 void CheckToken (int error, int yyToken, string msg, Location loc)
6261         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
6262                 Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken));
6263         else
6264                 Report.Error (error, loc, msg);
6267 void CheckIdentifierToken (int yyToken, Location loc)
6269         CheckToken (1041, yyToken, "Identifier expected", loc);
6272 string ConsumeStoredComment ()
6274         string s = tmpComment;
6275         tmpComment = null;
6276         Lexer.doc_state = XmlCommentState.Allowed;
6277         return s;
6280 Location GetLocation (object obj)
6282         if (obj is Tokenizer.LocatedToken)
6283                 return ((Tokenizer.LocatedToken) obj).Location;
6284         if (obj is MemberName)
6285                 return ((MemberName) obj).Location;
6287         return lexer.Location;
6290 Report Report {
6291         get { return compiler.Report; }
6294 void start_block (Location loc)
6296         if (current_block == null || parsing_anonymous_method) {
6297                 current_block = new ToplevelBlock (compiler, current_block, current_local_parameters, current_generic_method, loc);
6298                 parsing_anonymous_method = false;
6299         } else {
6300                 current_block = new ExplicitBlock (current_block, loc, Location.Null);
6301         }
6304 Block
6305 end_block (Location loc)
6307         Block retval = current_block.Explicit;
6308         retval.SetEndLocation (loc);
6309         current_block = retval.Parent;
6310         return retval;
6313 void
6314 start_anonymous (bool lambda, ParametersCompiled parameters, Location loc)
6316         if (RootContext.Version == LanguageVersion.ISO_1){
6317                 Report.FeatureIsNotAvailable (loc, "anonymous methods");
6318         }
6320         oob_stack.Push (current_anonymous_method);
6321         oob_stack.Push (current_local_parameters);
6323         current_local_parameters = parameters;
6325         current_anonymous_method = lambda 
6326                 ? new LambdaExpression (loc) 
6327                 : new AnonymousMethodExpression (loc);
6329         // Force the next block to be created as a ToplevelBlock
6330         parsing_anonymous_method = true;
6334  * Completes the anonymous method processing, if lambda_expr is null, this
6335  * means that we have a Statement instead of an Expression embedded 
6336  */
6337 AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block)
6339         AnonymousMethodExpression retval;
6341         current_anonymous_method.Block = anon_block;
6342         retval = current_anonymous_method;
6344         current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
6345         current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
6347         return retval;
6350 public NamespaceEntry CurrentNamespace {
6351        get { 
6352            return current_namespace;
6353        }
6357 void Error_SyntaxError (int token)
6359         Error_SyntaxError (0, token, "Unexpected symbol");
6362 void Error_SyntaxError (int error_code, int token, string msg)
6364         string symbol = GetSymbolName (token);
6365         string expecting = GetExpecting ();
6366         
6367         if (error_code == 0) {
6368                 if (expecting == "`)'")
6369                         error_code = 1026;
6370                 else
6371                         error_code = 1525;
6372         }
6373         
6374         if (expecting != null)
6375                 Report.Error (error_code, lexer.Location, "{2} `{0}', expecting {1}", 
6376                         symbol, expecting, msg);          
6377         else
6378                 Report.Error (error_code, lexer.Location, "{1} `{0}'", symbol, msg);
6381 string GetExpecting ()
6383         int [] tokens = yyExpectingTokens (yyExpectingState);
6384         var names = new List<string> (tokens.Length);
6385         bool has_type = false;
6386         bool has_identifier = false;
6387         for (int i = 0; i < tokens.Length; i++){
6388                 int token = tokens [i];
6389                 has_identifier |= token == Token.IDENTIFIER;
6390                 
6391                 string name = GetTokenName (token);
6392                 if (name == "<internal>")
6393                         continue;
6394                         
6395                 has_type |= name == "type";
6396                 if (names.Contains (name))
6397                         continue;
6398                 
6399                 names.Add (name);
6400         }
6402         //
6403         // Too many tokens to enumerate
6404         //
6405         if (names.Count > 8)
6406                 return null;
6408         if (has_type && has_identifier)
6409                 names.Remove ("identifier");
6411         if (names.Count == 1)
6412                 return "`" + GetTokenName (tokens [0]) + "'";
6413         
6414         StringBuilder sb = new StringBuilder ();
6415         names.Sort ();
6416         int count = names.Count;
6417         for (int i = 0; i < count; i++){
6418                 bool last = i + 1 == count;
6419                 if (last)
6420                         sb.Append ("or ");
6421                 sb.Append ('`');
6422                 sb.Append (names [i]);
6423                 sb.Append (last ? "'" : count < 3 ? "' " : "', ");
6424         }
6425         return sb.ToString ();
6429 string GetSymbolName (int token)
6431         switch (token){
6432         case Token.LITERAL:
6433                 return ((Constant)lexer.Value).GetValue ().ToString ();
6434         case Token.IDENTIFIER:
6435                 return ((Tokenizer.LocatedToken)lexer.Value).Value;
6437         case Token.BOOL:
6438                 return "bool";
6439         case Token.BYTE:
6440                 return "byte";
6441         case Token.CHAR:
6442                 return "char";
6443         case Token.VOID:
6444                 return "void";
6445         case Token.DECIMAL:
6446                 return "decimal";
6447         case Token.DOUBLE:
6448                 return "double";
6449         case Token.FLOAT:
6450                 return "float";
6451         case Token.INT:
6452                 return "int";
6453         case Token.LONG:
6454                 return "long";
6455         case Token.SBYTE:
6456                 return "sbyte";
6457         case Token.SHORT:
6458                 return "short";
6459         case Token.STRING:
6460                 return "string";
6461         case Token.UINT:
6462                 return "uint";
6463         case Token.ULONG:
6464                 return "ulong";
6465         case Token.USHORT:
6466                 return "ushort";
6467         case Token.OBJECT:
6468                 return "object";
6469                 
6470         case Token.PLUS:
6471                 return "+";
6472         case Token.UMINUS:
6473         case Token.MINUS:
6474                 return "-";
6475         case Token.BANG:
6476                 return "!";
6477         case Token.BITWISE_AND:
6478                 return "&";
6479         case Token.BITWISE_OR:
6480                 return "|";
6481         case Token.STAR:
6482                 return "*";
6483         case Token.PERCENT:
6484                 return "%";
6485         case Token.DIV:
6486                 return "/";
6487         case Token.CARRET:
6488                 return "^";
6489         case Token.OP_INC:
6490                 return "++";
6491         case Token.OP_DEC:
6492                 return "--";
6493         case Token.OP_SHIFT_LEFT:
6494                 return "<<";
6495         case Token.OP_SHIFT_RIGHT:
6496                 return ">>";
6497         case Token.OP_LT:
6498                 return "<";
6499         case Token.OP_GT:
6500                 return ">";
6501         case Token.OP_LE:
6502                 return "<=";
6503         case Token.OP_GE:
6504                 return ">=";
6505         case Token.OP_EQ:
6506                 return "==";
6507         case Token.OP_NE:
6508                 return "!=";
6509         case Token.OP_AND:
6510                 return "&&";
6511         case Token.OP_OR:
6512                 return "||";
6513         case Token.OP_PTR:
6514                 return "->";
6515         case Token.OP_COALESCING:       
6516                 return "??";
6517         case Token.OP_MULT_ASSIGN:
6518                 return "*=";
6519         case Token.OP_DIV_ASSIGN:
6520                 return "/=";
6521         case Token.OP_MOD_ASSIGN:
6522                 return "%=";
6523         case Token.OP_ADD_ASSIGN:
6524                 return "+=";
6525         case Token.OP_SUB_ASSIGN:
6526                 return "-=";
6527         case Token.OP_SHIFT_LEFT_ASSIGN:
6528                 return "<<=";
6529         case Token.OP_SHIFT_RIGHT_ASSIGN:
6530                 return ">>=";
6531         case Token.OP_AND_ASSIGN:
6532                 return "&=";
6533         case Token.OP_XOR_ASSIGN:
6534                 return "^=";
6535         case Token.OP_OR_ASSIGN:
6536                 return "|=";
6537         }
6539         return GetTokenName (token);
6542 static string GetTokenName (int token)
6544         switch (token){
6545         case Token.ABSTRACT:
6546                 return "abstract";
6547         case Token.AS:
6548                 return "as";
6549         case Token.ADD:
6550                 return "add";
6551         case Token.BASE:
6552                 return "base";
6553         case Token.BREAK:
6554                 return "break";
6555         case Token.CASE:
6556                 return "case";
6557         case Token.CATCH:
6558                 return "catch";
6559         case Token.CHECKED:
6560                 return "checked";
6561         case Token.CLASS:
6562                 return "class";
6563         case Token.CONST:
6564                 return "const";
6565         case Token.CONTINUE:
6566                 return "continue";
6567         case Token.DEFAULT:
6568                 return "default";
6569         case Token.DELEGATE:
6570                 return "delegate";
6571         case Token.DO:
6572                 return "do";
6573         case Token.ELSE:
6574                 return "else";
6575         case Token.ENUM:
6576                 return "enum";
6577         case Token.EVENT:
6578                 return "event";
6579         case Token.EXPLICIT:
6580                 return "explicit";
6581         case Token.EXTERN:
6582                 return "extern";
6583         case Token.FALSE:
6584                 return "false";
6585         case Token.FINALLY:
6586                 return "finally";
6587         case Token.FIXED:
6588                 return "fixed";
6589         case Token.FOR:
6590                 return "for";
6591         case Token.FOREACH:
6592                 return "foreach";
6593         case Token.GOTO:
6594                 return "goto";
6595         case Token.IF:
6596                 return "if";
6597         case Token.IMPLICIT:
6598                 return "implicit";
6599         case Token.IN:
6600                 return "in";
6601         case Token.INTERFACE:
6602                 return "interface";
6603         case Token.INTERNAL:
6604                 return "internal";
6605         case Token.IS:
6606                 return "is";
6607         case Token.LOCK:
6608                 return "lock";
6609         case Token.NAMESPACE:
6610                 return "namespace";
6611         case Token.NEW:
6612                 return "new";
6613         case Token.NULL:
6614                 return "null";
6615         case Token.OPERATOR:
6616                 return "operator";
6617         case Token.OUT:
6618                 return "out";
6619         case Token.OVERRIDE:
6620                 return "override";
6621         case Token.PARAMS:
6622                 return "params";
6623         case Token.PRIVATE:
6624                 return "private";
6625         case Token.PROTECTED:
6626                 return "protected";
6627         case Token.PUBLIC:
6628                 return "public";
6629         case Token.READONLY:
6630                 return "readonly";
6631         case Token.REF:
6632                 return "ref";
6633         case Token.RETURN:
6634                 return "return";
6635         case Token.REMOVE:
6636                 return "remove";
6637         case Token.SEALED:
6638                 return "sealed";
6639         case Token.SIZEOF:
6640                 return "sizeof";
6641         case Token.STACKALLOC:
6642                 return "stackalloc";
6643         case Token.STATIC:
6644                 return "static";
6645         case Token.STRUCT:
6646                 return "struct";
6647         case Token.SWITCH:
6648                 return "switch";
6649         case Token.THIS:
6650                 return "this";
6651         case Token.THROW:
6652                 return "throw";
6653         case Token.TRUE:
6654                 return "true";
6655         case Token.TRY:
6656                 return "try";
6657         case Token.TYPEOF:
6658                 return "typeof";
6659         case Token.UNCHECKED:
6660                 return "unchecked";
6661         case Token.UNSAFE:
6662                 return "unsafe";
6663         case Token.USING:
6664                 return "using";
6665         case Token.VIRTUAL:
6666                 return "virtual";
6667         case Token.VOLATILE:
6668                 return "volatile";
6669         case Token.WHERE:
6670                 return "where";
6671         case Token.WHILE:
6672                 return "while";
6673         case Token.ARGLIST:
6674                 return "__arglist";
6675         case Token.PARTIAL:
6676                 return "partial";
6677         case Token.ARROW:
6678                 return "=>";
6679         case Token.FROM:
6680         case Token.FROM_FIRST:
6681                 return "from";
6682         case Token.JOIN:
6683                 return "join";
6684         case Token.ON:
6685                 return "on";
6686         case Token.EQUALS:
6687                 return "equals";
6688         case Token.SELECT:
6689                 return "select";
6690         case Token.GROUP:
6691                 return "group";
6692         case Token.BY:
6693                 return "by";
6694         case Token.LET:
6695                 return "let";
6696         case Token.ORDERBY:
6697                 return "orderby";
6698         case Token.ASCENDING:
6699                 return "ascending";
6700         case Token.DESCENDING:
6701                 return "descending";
6702         case Token.INTO:
6703                 return "into";
6704         case Token.GET:
6705                 return "get";
6706         case Token.SET:
6707                 return "set";
6708         case Token.OPEN_BRACE:
6709                 return "{";
6710         case Token.CLOSE_BRACE:
6711                 return "}";
6712         case Token.OPEN_BRACKET:
6713                 return "[";
6714         case Token.CLOSE_BRACKET:
6715                 return "]";
6716         case Token.OPEN_PARENS_CAST:
6717         case Token.OPEN_PARENS_LAMBDA:
6718         case Token.OPEN_PARENS:
6719                 return "(";
6720         case Token.CLOSE_PARENS:
6721                 return ")";
6722         case Token.DOT:
6723                 return ".";
6724         case Token.COMMA:
6725                 return ",";
6726         case Token.DEFAULT_COLON:
6727                 return "default:";
6728         case Token.COLON:
6729                 return ":";
6730         case Token.SEMICOLON:
6731                 return ";";
6732         case Token.TILDE:
6733                 return "~";
6734                 
6735         case Token.PLUS:
6736         case Token.UMINUS:
6737         case Token.MINUS:
6738         case Token.BANG:
6739         case Token.OP_LT:
6740         case Token.OP_GT:
6741         case Token.BITWISE_AND:
6742         case Token.BITWISE_OR:
6743         case Token.STAR:
6744         case Token.PERCENT:
6745         case Token.DIV:
6746         case Token.CARRET:
6747         case Token.OP_INC:
6748         case Token.OP_DEC:
6749         case Token.OP_SHIFT_LEFT:
6750         case Token.OP_SHIFT_RIGHT:
6751         case Token.OP_LE:
6752         case Token.OP_GE:
6753         case Token.OP_EQ:
6754         case Token.OP_NE:
6755         case Token.OP_AND:
6756         case Token.OP_OR:
6757         case Token.OP_PTR:
6758         case Token.OP_COALESCING:       
6759         case Token.OP_MULT_ASSIGN:
6760         case Token.OP_DIV_ASSIGN:
6761         case Token.OP_MOD_ASSIGN:
6762         case Token.OP_ADD_ASSIGN:
6763         case Token.OP_SUB_ASSIGN:
6764         case Token.OP_SHIFT_LEFT_ASSIGN:
6765         case Token.OP_SHIFT_RIGHT_ASSIGN:
6766         case Token.OP_AND_ASSIGN:
6767         case Token.OP_XOR_ASSIGN:
6768         case Token.OP_OR_ASSIGN:
6769                 return "<operator>";
6771         case Token.BOOL:
6772         case Token.BYTE:
6773         case Token.CHAR:
6774         case Token.VOID:
6775         case Token.DECIMAL:
6776         case Token.DOUBLE:
6777         case Token.FLOAT:
6778         case Token.INT:
6779         case Token.LONG:
6780         case Token.SBYTE:
6781         case Token.SHORT:
6782         case Token.STRING:
6783         case Token.UINT:
6784         case Token.ULONG:
6785         case Token.USHORT:
6786         case Token.OBJECT:
6787                 return "type";
6788         
6789         case Token.ASSIGN:
6790                 return "=";
6791         case Token.OP_GENERICS_LT:
6792         case Token.GENERIC_DIMENSION:
6793                 return "<";
6794         case Token.OP_GENERICS_GT:
6795                 return ">";
6796         case Token.INTERR:
6797         case Token.INTERR_NULLABLE:
6798                 return "?";
6799         case Token.DOUBLE_COLON:
6800                 return "::";
6801         case Token.LITERAL:
6802                 return "value";
6803         case Token.IDENTIFIER:
6804                 return "identifier";
6806                 // All of these are internal.
6807         case Token.NONE:
6808         case Token.ERROR:
6809         case Token.FIRST_KEYWORD:
6810         case Token.EOF:
6811         case Token.EVAL_COMPILATION_UNIT_PARSER:
6812         case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER:
6813         case Token.EVAL_STATEMENT_PARSER:
6814         case Token.LAST_KEYWORD:
6815         case Token.GENERATE_COMPLETION:
6816         case Token.COMPLETE_COMPLETION:
6817                 return "<internal>";
6819                 // A bit more robust.
6820         default:
6821                 return yyNames [token];
6822         }
6825 /* end end end */