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