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