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