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