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