2007-01-11 Jonathan Chambers <joncham@gmail.com>
[mcs.git] / gmcs / cs-parser.jay
blob4ced6699acb52aa28d6b2e6e0d2b485f3d7e120d
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 //
8 // Licensed under the terms of the GNU GPL
9 //
10 // (C) 2001 Ximian, Inc (http://www.ximian.com)
11 // (C) 2004 Novell, Inc
13 // TODO:
14 //   (1) Figure out why error productions dont work.  `type-declaration' is a
15 //       great spot to put an `error' because you can reproduce it with this input:
16 //       "public X { }"
18 // Possible optimization:
19 //   Run memory profiler with parsing only, and consider dropping 
20 //   arraylists where not needed.   Some pieces can use linked lists.
22 using System.Text;
23 using System.IO;
24 using System;
26 namespace Mono.CSharp
28         using System.Collections;
30         /// <summary>
31         ///    The C# Parser
32         /// </summary>
33         public class CSharpParser {
34                 NamespaceEntry  current_namespace;
35                 TypeContainer   current_container;
36                 DeclSpace       current_class;
37         
38                 IAnonymousHost anonymous_host;
40                 /// <summary>
41                 ///   Current block is used to add statements as we find
42                 ///   them.  
43                 /// </summary>
44                 Block      current_block, top_current_block;
46                 Delegate   current_delegate;
48                 GenericMethod current_generic_method;
49                 AnonymousMethodExpression current_anonymous_method;
51                 /// <summary>
52                 ///   This is used by the unary_expression code to resolve
53                 ///   a name against a parameter.  
54                 /// </summary>
55                 Parameters current_local_parameters;
57                 /// <summary>
58                 ///   Using during property parsing to describe the implicit
59                 ///   value parameter that is passed to the "set" and "get"accesor
60                 ///   methods (properties and indexers).
61                 /// </summary>
62                 Expression implicit_value_parameter_type;
63                 Parameters indexer_parameters;
65                 /// <summary>
66                 ///   Hack to help create non-typed array initializer
67                 /// </summary>
68                 public static Expression current_array_type;
69                 Expression pushed_current_array_type;
71                 /// <summary>
72                 ///   Used to determine if we are parsing the get/set pair
73                 ///   of an indexer or a property
74                 /// </summmary>
75                 bool parsing_indexer;
77                 bool parsing_anonymous_method;
79                 ///
80                 /// An out-of-band stack.
81                 ///
82                 Stack oob_stack;
84                 ///
85                 /// Switch stack.
86                 ///
87                 Stack switch_stack;
89                 static public int yacc_verbose_flag;
91                 // Name of the file we are parsing
92                 public string name;
94                 ///
95                 /// The current file.
96                 ///
97                 SourceFile file;
99                 ///
100                 /// Temporary Xml documentation cache.
101                 /// For enum types, we need one more temporary store.
102                 ///
103                 string tmpComment;
104                 string enumTypeComment;
105                         
106                 /// Current attribute target
107                 string current_attr_target;
108                 
109                 /// assembly and module attribute definitions are enabled
110                 bool global_attrs_enabled = true;
111                 bool has_get, has_set;
115 %token EOF
116 %token NONE   /* This token is never returned by our lexer */
117 %token ERROR            // This is used not by the parser, but by the tokenizer.
118                         // do not remove.
121  *These are the C# keywords
122  */
123 %token FIRST_KEYWORD
124 %token ABSTRACT 
125 %token AS
126 %token ADD
127 %token ASSEMBLY
128 %token BASE     
129 %token BOOL     
130 %token BREAK    
131 %token BYTE     
132 %token CASE     
133 %token CATCH    
134 %token CHAR     
135 %token CHECKED  
136 %token CLASS    
137 %token CONST    
138 %token CONTINUE 
139 %token DECIMAL  
140 %token DEFAULT  
141 %token DELEGATE 
142 %token DO       
143 %token DOUBLE   
144 %token ELSE     
145 %token ENUM     
146 %token EVENT    
147 %token EXPLICIT 
148 %token EXTERN   
149 %token FALSE    
150 %token FINALLY  
151 %token FIXED    
152 %token FLOAT    
153 %token FOR      
154 %token FOREACH  
155 %token GOTO     
156 %token IF       
157 %token IMPLICIT 
158 %token IN       
159 %token INT      
160 %token INTERFACE
161 %token INTERNAL 
162 %token IS       
163 %token LOCK     
164 %token LONG     
165 %token NAMESPACE
166 %token NEW      
167 %token NULL     
168 %token OBJECT   
169 %token OPERATOR 
170 %token OUT      
171 %token OVERRIDE 
172 %token PARAMS   
173 %token PRIVATE  
174 %token PROTECTED
175 %token PUBLIC   
176 %token READONLY 
177 %token REF      
178 %token RETURN   
179 %token REMOVE
180 %token SBYTE    
181 %token SEALED   
182 %token SHORT    
183 %token SIZEOF   
184 %token STACKALLOC
185 %token STATIC   
186 %token STRING   
187 %token STRUCT   
188 %token SWITCH   
189 %token THIS     
190 %token THROW    
191 %token TRUE     
192 %token TRY      
193 %token TYPEOF   
194 %token UINT     
195 %token ULONG    
196 %token UNCHECKED
197 %token UNSAFE   
198 %token USHORT   
199 %token USING    
200 %token VIRTUAL  
201 %token VOID     
202 %token VOLATILE
203 %token WHERE
204 %token WHILE    
205 %token ARGLIST
206 %token PARTIAL
208 /* C# keywords which are not really keywords */
209 %token GET           "get"
210 %token SET           "set"
212 %left LAST_KEYWORD
214 /* C# single character operators/punctuation. */
215 %token OPEN_BRACE    "{"
216 %token CLOSE_BRACE   "}"
217 %token OPEN_BRACKET  "["
218 %token CLOSE_BRACKET "]"
219 %token OPEN_PARENS   "("
220 %token CLOSE_PARENS  ")"
221 %token DOT           "."
222 %token COMMA         ","
223 %token COLON         ":"
224 %token SEMICOLON     ";"
225 %token TILDE         "~"
227 %token PLUS           "+"
228 %token MINUS          "-"
229 %token BANG           "!"
230 %token ASSIGN         "="
231 %token OP_LT          "<"
232 %token OP_GENERICS_LT "<"
233 %token OP_GT          ">"
234 %token OP_GENERICS_GT ">"
235 %token BITWISE_AND    "&"
236 %token BITWISE_OR     "|"
237 %token STAR           "*"
238 %token PERCENT        "%"
239 %token DIV            "/"
240 %token CARRET         "^"
241 %token INTERR         "?"
243 /* C# multi-character operators. */
244 %token DOUBLE_COLON           "::"
245 %token OP_INC                 "++"
246 %token OP_DEC                 "--"
247 %token OP_SHIFT_LEFT          "<<"
248 %token OP_SHIFT_RIGHT         ">>"
249 %token OP_LE                  "<="
250 %token OP_GE                  ">="
251 %token OP_EQ                  "=="
252 %token OP_NE                  "!="
253 %token OP_AND                 "&&"
254 %token OP_OR                  "||"
255 %token OP_MULT_ASSIGN         "*="
256 %token OP_DIV_ASSIGN          "/="
257 %token OP_MOD_ASSIGN          "%="
258 %token OP_ADD_ASSIGN          "+="
259 %token OP_SUB_ASSIGN          "-="
260 %token OP_SHIFT_LEFT_ASSIGN   "<<="
261 %token OP_SHIFT_RIGHT_ASSIGN  ">>="
262 %token OP_AND_ASSIGN          "&="
263 %token OP_XOR_ASSIGN          "^="
264 %token OP_OR_ASSIGN           "|="
265 %token OP_PTR                 "->"
267 /* Numbers */
268 %token LITERAL_INTEGER           "int literal"
269 %token LITERAL_FLOAT             "float literal"
270 %token LITERAL_DOUBLE            "double literal"
271 %token LITERAL_DECIMAL           "decimal literal"
272 %token LITERAL_CHARACTER         "character literal"
273 %token LITERAL_STRING            "string literal"
275 %token IDENTIFIER
276 %token CLOSE_PARENS_CAST
277 %token CLOSE_PARENS_NO_CAST
278 %token CLOSE_PARENS_OPEN_PARENS
279 %token CLOSE_PARENS_MINUS
280 %token DEFAULT_OPEN_PARENS
281 %token GENERIC_DIMENSION
282 %token DEFAULT_COLON
284 /* Add precedence rules to solve dangling else s/r conflict */
285 %nonassoc LOWPREC
286 %nonassoc IF
287 %nonassoc ELSE
288 %right ASSIGN
289 %left OP_OR
290 %left OP_AND
291 %left BITWISE_OR
292 %left BITWISE_AND
293 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
294 %left PLUS MINUS
295 %left STAR DIV PERCENT
296 %right BANG CARRET UMINUS
297 %nonassoc OP_INC OP_DEC
298 %left OPEN_PARENS
299 %left OPEN_BRACKET OPEN_BRACE
300 %left DOT
301 %nonassoc HIGHPREC
303 %start compilation_unit
306 compilation_unit
307         : outer_declarations opt_EOF
308         | outer_declarations global_attributes opt_EOF
309         | global_attributes opt_EOF
310         | opt_EOF /* allow empty files */
311         ;
312         
313 opt_EOF
314         : /* empty */
315           {
316                 Lexer.check_incorrect_doc_comment ();
317           }
318         | EOF
319           {
320                 Lexer.check_incorrect_doc_comment ();
321           }
322         ;
324 outer_declarations
325         : outer_declaration
326         | outer_declarations outer_declaration
327         ;
329 outer_declaration
330         : extern_alias_directive
331         | using_directive 
332         | namespace_member_declaration
333         ;
335 extern_alias_directives
336         : extern_alias_directive
337         | extern_alias_directives extern_alias_directive;
339 extern_alias_directive
340         : EXTERN IDENTIFIER IDENTIFIER SEMICOLON
341           {
342                 LocatedToken lt = (LocatedToken) $2;
343                 string s = lt.Value;
344                 if (s != "alias"){
345                         Report.Error (1003, lt.Location, "'alias' expected");
346                 } else if (RootContext.Version == LanguageVersion.ISO_1) {
347                         Report.FeatureIsNotStandardized (lt.Location, "external alias");
348                 } else {
349                         lt = (LocatedToken) $3; 
350                         current_namespace.UsingExternalAlias (lt.Value, lt.Location);
351                 }
352           }
353         ;
355 using_directives
356         : using_directive 
357         | using_directives using_directive
358         ;
360 using_directive
361         : using_alias_directive
362           {
363                 if (RootContext.Documentation != null)
364                         Lexer.doc_state = XmlCommentState.Allowed;
365           }
366         | using_namespace_directive
367           {
368                 if (RootContext.Documentation != null)
369                         Lexer.doc_state = XmlCommentState.Allowed;
370           }
371         ;
373 using_alias_directive
374         : USING IDENTIFIER ASSIGN 
375           namespace_or_type_name SEMICOLON
376           {
377                 LocatedToken lt = (LocatedToken) $2;
378                 current_namespace.UsingAlias (lt.Value, (MemberName) $4, (Location) $1);
379           }
380         | USING error {
381                 CheckIdentifierToken (yyToken, GetLocation ($2));
382           }
383         ;
385 using_namespace_directive
386         : USING namespace_name SEMICOLON 
387           {
388                 current_namespace.Using ((MemberName) $2, (Location) $1);
389           }
390         ;
393 // Strictly speaking, namespaces don't have attributes but
394 // we parse global attributes along with namespace declarations and then
395 // detach them
396 // 
397 namespace_declaration
398         : opt_attributes NAMESPACE namespace_or_type_name
399           {
400                 MemberName name = (MemberName) $3;
402                 if ($1 != null) {
403                         Report.Error(1671, name.Location, "A namespace declaration cannot have modifiers or attributes");
404                 }
406                 if (name.TypeArguments != null)
407                         syntax_error (lexer.Location, "namespace name expected");
409                 current_namespace = new NamespaceEntry (
410                         current_namespace, file, name.GetName ());
411                 current_class = current_namespace.SlaveDeclSpace;
412                 current_container = current_class.PartialContainer;
413           } 
414           namespace_body opt_semicolon
415           { 
416                 current_namespace = current_namespace.Parent;
417                 current_class = current_namespace.SlaveDeclSpace;
418                 current_container = current_class.PartialContainer;
419           }
420         ;
422 opt_semicolon
423         : /* empty */
424         | SEMICOLON
425         ;
427 opt_comma
428         : /* empty */
429         | COMMA
430         ;
432 namespace_name
433         : namespace_or_type_name {
434                 MemberName name = (MemberName) $1;
436                 if (name.TypeArguments != null)
437                         syntax_error (lexer.Location, "namespace name expected");
439                 $$ = name;
440           }
441         ;
443 namespace_body
444         : OPEN_BRACE
445           {
446                 if (RootContext.Documentation != null)
447                         Lexer.doc_state = XmlCommentState.Allowed;
448           }
449           namespace_body_body
450         ;
451         
452 namespace_body_body
453         : opt_extern_alias_directives
454           opt_using_directives
455           opt_namespace_member_declarations
456           CLOSE_BRACE
457         | error
458           {
459                 Report.Error (1518, lexer.Location, "Expected `class', `delegate', `enum', `interface', or `struct'");
460           }
461           CLOSE_BRACE
462         | opt_extern_alias_directives
463           opt_using_directives
464           opt_namespace_member_declarations
465           EOF
466           {
467                 Report.Error (1513, lexer.Location, "} expected");
468           }
469         ;
471 opt_using_directives
472         : /* empty */
473         | using_directives
474         ;
476 opt_extern_alias_directives
477         : /* empty */
478         | extern_alias_directives
479         ;
481 opt_namespace_member_declarations
482         : /* empty */
483         | namespace_member_declarations
484         ;
486 namespace_member_declarations
487         : namespace_member_declaration
488         | namespace_member_declarations namespace_member_declaration
489         ;
491 namespace_member_declaration
492         : type_declaration
493           {
494                 if ($1 != null) {
495                         DeclSpace ds = (DeclSpace)$1;
497                         if ((ds.ModFlags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
498                                 Report.Error (1527, ds.Location, 
499                                 "Namespace elements cannot be explicitly declared as private, protected or protected internal");
500                         }
501                 }
502                 current_namespace.DeclarationFound = true;
503           }
504         | namespace_declaration {
505                 current_namespace.DeclarationFound = true;
506           }
508         | field_declaration {
509                 Report.Error (116, ((MemberCore) $1).Location, "A namespace can only contain types and namespace declarations");
510           }
511         | method_declaration {
512                 Report.Error (116, ((MemberCore) $1).Location, "A namespace can only contain types and namespace declarations");
513           }
514         ;
516 type_declaration
517         : class_declaration             
518         | struct_declaration            
519         | interface_declaration         
520         | enum_declaration              
521         | delegate_declaration
523 // Enable this when we have handled all errors, because this acts as a generic fallback
525 //      | error {
526 //              Console.WriteLine ("Token=" + yyToken);
527 //              Report.Error (1518, GetLocation ($1), "Expected class, struct, interface, enum or delegate");
528 //        }
529         ;
532 // Attributes 17.2
535 global_attributes
536         : attribute_sections
538         if ($1 != null)
539                 CodeGen.Assembly.AddAttributes (((Attributes)$1).Attrs);
541         $$ = $1;
544 opt_attributes
545         : /* empty */ 
546           {
547                 global_attrs_enabled = false;
548                 $$ = null;
549       }
550         | attribute_sections
551           { 
552                 global_attrs_enabled = false;
553                 $$ = $1;
554           }
555     ;
558 attribute_sections
559         : attribute_section
560           {
561                 ArrayList sect = (ArrayList) $1;
563                 if (global_attrs_enabled) {
564                         if (current_attr_target == "module") {
565                                 CodeGen.Module.AddAttributes (sect);
566                                 $$ = null;
567                         } else if (current_attr_target != null && current_attr_target.Length > 0) {
568                                 CodeGen.Assembly.AddAttributes (sect);
569                                 $$ = null;
570                         } else {
571                                 $$ = new Attributes (sect);
572                         }
573                         if ($$ == null) {
574                                 if (RootContext.Documentation != null) {
575                                         Lexer.check_incorrect_doc_comment ();
576                                         Lexer.doc_state =
577                                                 XmlCommentState.Allowed;
578                                 }
579                         }
580                 } else {
581                         $$ = new Attributes (sect);
582                 }               
583                 current_attr_target = null;
584       }
585         | attribute_sections attribute_section
586           {
587                 Attributes attrs = $1 as Attributes;
588                 ArrayList sect = (ArrayList) $2;
590                 if (global_attrs_enabled) {
591                         if (current_attr_target == "module") {
592                                 CodeGen.Module.AddAttributes (sect);
593                                 $$ = null;
594                         } else if (current_attr_target == "assembly") {
595                                 CodeGen.Assembly.AddAttributes (sect);
596                                 $$ = null;
597                         } else {
598                                 if (attrs == null)
599                                         attrs = new Attributes (sect);
600                                 else
601                                         attrs.AddAttributes (sect);                     
602                         }
603                 } else {
604                         if (attrs == null)
605                                 attrs = new Attributes (sect);
606                         else
607                                 attrs.AddAttributes (sect);
608                 }               
609                 $$ = attrs;
610                 current_attr_target = null;
611           }
612         ;
614 attribute_section
615         : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
616           {
617                 $$ = $3;
618           }
619         | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
620           {
621                 $$ = $2;
622           }
623         ;
625 attribute_target_specifier
626         : attribute_target COLON
627           {
628                 current_attr_target = (string)$1;
629                 $$ = $1;
630           }
631         ;
633 attribute_target
634         : IDENTIFIER
635           {
636                 LocatedToken lt = (LocatedToken) $1;
637                 CheckAttributeTarget (lt.Value, lt.Location);
638                 $$ = lt.Value; // Location won't be required anymore.
639           }
640         | EVENT  { $$ = "event"; }        
641         | RETURN { $$ = "return"; }
642         ;
644 attribute_list
645         : attribute
646           {
647                 ArrayList attrs = new ArrayList (4);
648                 attrs.Add ($1);
650                 $$ = attrs;
651                
652           }
653         | attribute_list COMMA attribute
654           {
655                 ArrayList attrs = (ArrayList) $1;
656                 attrs.Add ($3);
658                 $$ = attrs;
659           }
660         ;
662 attribute
663         : attribute_name opt_attribute_arguments
664           {
665                 MemberName mname = (MemberName) $1;
666                 if (mname.IsGeneric) {
667                         Report.Error (404, lexer.Location,
668                                       "'<' unexpected: attributes cannot be generic");
669                 }
671                 object [] arguments = (object []) $2;
672                 MemberName left = mname.Left;
673                 string identifier = mname.Name;
675                 Expression left_expr = left == null ? null : left.GetTypeExpression ();
677                 if (current_attr_target == "assembly" || current_attr_target == "module")
678                         // FIXME: supply "nameEscaped" parameter here.
679                         $$ = new GlobalAttribute (current_namespace, current_attr_target,
680                                                   left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location));
681                 else
682                         $$ = new Attribute (current_attr_target, left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location));
683           }
684         ;
686 attribute_name
687         : namespace_or_type_name  { /* reserved attribute name or identifier: 17.4 */ }
688         ;
690 opt_attribute_arguments
691         : /* empty */   { $$ = null; }
692         | OPEN_PARENS attribute_arguments CLOSE_PARENS
693           {
694                 $$ = $2;
695           }
696         ;
699 attribute_arguments
700         : opt_positional_argument_list
701           {
702                 if ($1 == null)
703                         $$ = null;
704                 else {
705                         $$ = new object [] { $1, null };
706                 }
707           }
708     | positional_argument_list COMMA named_argument_list
709           {
710                 $$ = new object[] { $1, $3 };
711           }
712     | named_argument_list
713           {
714                 $$ = new object [] { null, $1 };
715           }
716     ;
719 opt_positional_argument_list
720         : /* empty */           { $$ = null; } 
721         | positional_argument_list
722         ;
724 positional_argument_list
725         : expression
726           {
727                 ArrayList args = new ArrayList (4);
728                 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
730                 $$ = args;
731           }
732         | positional_argument_list COMMA expression
733          {
734                 ArrayList args = (ArrayList) $1;
735                 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
737                 $$ = args;
738          }
739         ;
741 named_argument_list
742         : named_argument
743           {
744                 ArrayList args = new ArrayList (4);
745                 args.Add ($1);
747                 $$ = args;
748           }
749         | named_argument_list COMMA named_argument
750           {       
751                 ArrayList args = (ArrayList) $1;
752                 args.Add ($3);
754                 $$ = args;
755           }
756           | named_argument_list COMMA expression
757             {
758                   Report.Error (1016, ((Expression) $3).Location, "Named attribute argument expected");
759                   $$ = null;
760                 }
761         ;
763 named_argument
764         : IDENTIFIER ASSIGN expression
765           {
766                 // FIXME: keep location
767                 $$ = new DictionaryEntry (
768                         ((LocatedToken) $1).Value, 
769                         new Argument ((Expression) $3, Argument.AType.Expression));
770           }
771         ;
773                   
774 class_body
775         :  OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
776         ;
778 opt_class_member_declarations
779         : /* empty */
780         | class_member_declarations
781         ;
783 class_member_declarations
784         : class_member_declaration
785         | class_member_declarations 
786           class_member_declaration
787         ;
789 class_member_declaration
790         : constant_declaration                  // done
791         | field_declaration                     // done
792         | method_declaration                    // done
793         | property_declaration                  // done
794         | event_declaration                     // done
795         | indexer_declaration                   // done
796         | operator_declaration                  // done
797         | constructor_declaration               // done
798         | destructor_declaration                // done
799         | type_declaration
800         ;
802 struct_declaration
803         : opt_attributes
804           opt_modifiers
805           opt_partial
806           STRUCT
807           {
808                 lexer.ConstraintsParsing = true;
809           }
810           member_name
811           { 
812                 MemberName name = MakeName ((MemberName) $6);
813                 push_current_class (new Struct (
814                         current_namespace, current_class, name, (int) $2,
815                         (Attributes) $1), false, $3);
816           }
817           opt_class_base
818           opt_type_parameter_constraints_clauses
819           {
820                 lexer.ConstraintsParsing = false;
822                 if ($8 != null)
823                         current_container.AddBasesForPart (current_class, (ArrayList) $8);
825                 current_class.SetParameterInfo ((ArrayList) $9);
827                 if (RootContext.Documentation != null)
828                         current_container.DocComment = Lexer.consume_doc_comment ();
829           }
830           struct_body
831           {
832                 if (RootContext.Documentation != null)
833                         Lexer.doc_state = XmlCommentState.Allowed;
834           }
835           opt_semicolon
836           {
837                 $$ = pop_current_class ();
838           }
839         | opt_attributes opt_modifiers opt_partial STRUCT error {
840                 CheckIdentifierToken (yyToken, GetLocation ($5));
841           }
842         ;
844 struct_body
845         : OPEN_BRACE
846           {
847                 if (RootContext.Documentation != null)
848                         Lexer.doc_state = XmlCommentState.Allowed;
849           }
850           opt_struct_member_declarations CLOSE_BRACE
851         ;
853 opt_struct_member_declarations
854         : /* empty */
855         | struct_member_declarations
856         ;
858 struct_member_declarations
859         : struct_member_declaration
860         | struct_member_declarations struct_member_declaration
861         ;
863 struct_member_declaration
864         : constant_declaration
865         | field_declaration
866         | method_declaration
867         | property_declaration
868         | event_declaration
869         | indexer_declaration
870         | operator_declaration
871         | constructor_declaration
872         | type_declaration
874         /*
875          * This is only included so we can flag error 575: 
876          * destructors only allowed on class types
877          */
878         | destructor_declaration 
879         ;
881 constant_declaration
882         : opt_attributes 
883           opt_modifiers
884           CONST
885           type
886           constant_declarators
887           SEMICOLON
888           {
889                 int modflags = (int) $2;
890                 foreach (VariableDeclaration constant in (ArrayList) $5){
891                         Location l = constant.Location;
892                         if ((modflags & Modifiers.STATIC) != 0) {
893                                 Report.Error (504, l, "The constant `{0}' cannot be marked static", current_container.GetSignatureForError () + '.' + (string) constant.identifier);
894                                 continue;
895                         }
897                         Const c = new Const (
898                                 current_class, (Expression) $4, (string) constant.identifier, 
899                                 (Expression) constant.expression_or_array_initializer, modflags, 
900                                 (Attributes) $1, l);
902                         if (RootContext.Documentation != null) {
903                                 c.DocComment = Lexer.consume_doc_comment ();
904                                 Lexer.doc_state = XmlCommentState.Allowed;
905                         }
906                         current_container.AddConstant (c);
907                 }
908           }
909         ;
911 constant_declarators
912         : constant_declarator 
913           {
914                 ArrayList constants = new ArrayList (4);
915                 if ($1 != null)
916                         constants.Add ($1);
917                 $$ = constants;
918           }
919         | constant_declarators COMMA constant_declarator
920           {
921                 if ($3 != null) {
922                         ArrayList constants = (ArrayList) $1;
923                         constants.Add ($3);
924                 }
925           }
926         ;
928 constant_declarator
929         : IDENTIFIER ASSIGN constant_expression
930           {
931                 $$ = new VariableDeclaration ((LocatedToken) $1, $3);
932           }
933         | IDENTIFIER
934           {
935                 // A const field requires a value to be provided
936                 Report.Error (145, ((LocatedToken) $1).Location, "A const field requires a value to be provided");
937                 $$ = null;
938           }
939         ;
941 field_declaration
942         : opt_attributes
943           opt_modifiers
944           type 
945           variable_declarators
946           SEMICOLON
947           { 
948                 Expression type = (Expression) $3;
949                 int mod = (int) $2;
951                 current_array_type = null;
953                 foreach (VariableDeclaration var in (ArrayList) $4){
954                         Field field = new Field (current_class, type, mod, var.identifier, 
955                                                  (Attributes) $1, var.Location);
957                         field.Initializer = var.expression_or_array_initializer;
959                         if (RootContext.Documentation != null) {
960                                 field.DocComment = Lexer.consume_doc_comment ();
961                                 Lexer.doc_state = XmlCommentState.Allowed;
962                         }
963                         current_container.AddField (field);
964                         $$ = field; // FIXME: might be better if it points to the top item
965                 }
966           }
967         | opt_attributes
968           opt_modifiers
969           FIXED
970           type 
971           fixed_variable_declarators
972           SEMICOLON
973           { 
974                         Expression type = (Expression) $4;
975                         int mod = (int) $2;
977                         current_array_type = null;
979                         foreach (VariableDeclaration var in (ArrayList) $5) {
980                                 FixedField field = new FixedField (current_class, type, mod, var.identifier,
981                                         (Expression)var.expression_or_array_initializer, (Attributes) $1, var.Location);
983                                 if (RootContext.Documentation != null) {
984                                         field.DocComment = Lexer.consume_doc_comment ();
985                                         Lexer.doc_state = XmlCommentState.Allowed;
986                                 }
987                                 current_container.AddField (field);
988                                 $$ = field; // FIXME: might be better if it points to the top item
989                         }
990           }
991         | opt_attributes
992           opt_modifiers
993           FIXED
994           type 
995           error
996           {
997                 Report.Error (1641, GetLocation ($4), "A fixed size buffer field must have the array size specifier after the field name");
998           }
999         | opt_attributes
1000           opt_modifiers
1001           VOID  
1002           variable_declarators
1003           SEMICOLON {
1004                 current_array_type = null;
1005                 Report.Error (670, (Location) $3, "Fields cannot have void type");
1006           }
1007         ;
1009 fixed_variable_declarators
1010         : fixed_variable_declarator
1011           {
1012                 ArrayList decl = new ArrayList (2);
1013                 decl.Add ($1);
1014                 $$ = decl;
1015           }
1016         | fixed_variable_declarators COMMA fixed_variable_declarator
1017           {
1018                 ArrayList decls = (ArrayList) $1;
1019                 decls.Add ($3);
1020                 $$ = $1;
1021           }
1022         ;
1024 fixed_variable_declarator
1025         : IDENTIFIER OPEN_BRACKET expression CLOSE_BRACKET
1026           {
1027                 $$ = new VariableDeclaration ((LocatedToken) $1, $3);
1028           }
1029         | IDENTIFIER OPEN_BRACKET CLOSE_BRACKET
1030           {
1031                 Report.Error (443, lexer.Location, "Value or constant expected");
1032                 $$ = new VariableDeclaration ((LocatedToken) $1, null);
1033           }
1034         ;
1036 variable_declarators
1037         : variable_declarator 
1038           {
1039                 ArrayList decl = new ArrayList (4);
1040                 if ($1 != null)
1041                         decl.Add ($1);
1042                 $$ = decl;
1043           }
1044         | variable_declarators COMMA variable_declarator
1045           {
1046                 ArrayList decls = (ArrayList) $1;
1047                 decls.Add ($3);
1048                 $$ = $1;
1049           }
1050         ;
1052 variable_declarator
1053         : IDENTIFIER ASSIGN variable_initializer
1054           {
1055                 $$ = new VariableDeclaration ((LocatedToken) $1, $3);
1056           }
1057         | IDENTIFIER
1058           {
1059                 $$ = new VariableDeclaration ((LocatedToken) $1, null);
1060           }
1061         | IDENTIFIER OPEN_BRACKET opt_expression CLOSE_BRACKET
1062           {
1063                 Report.Error (650, ((LocatedToken) $1).Location, "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. " +
1064                         "To declare a fixed size buffer field, use the fixed keyword before the field type");
1065                 $$ = null;
1066           }
1067         ;
1069 variable_initializer
1070         : expression
1071           {
1072                 $$ = $1;
1073           }
1074         | array_initializer
1075           {
1076                 $$ = $1;
1077           }
1078         | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
1079           {
1080                 $$ = new StackAlloc ((Expression) $2, (Expression) $4, (Location) $1);
1081           }
1082         | ARGLIST
1083           {
1084                 $$ = new ArglistAccess ((Location) $1);
1085           }
1086         | STACKALLOC type
1087           {
1088                 Report.Error (1575, (Location) $1, "A stackalloc expression requires [] after type");
1089                 $$ = null;
1090           }
1091         ;
1093 method_declaration
1094         : method_header {
1095                 anonymous_host = (IAnonymousHost) $1;
1096                 if (RootContext.Documentation != null)
1097                         Lexer.doc_state = XmlCommentState.NotAllowed;
1098           }
1099           method_body
1100           {
1101                 Method method = (Method) $1;
1102                 method.Block = (ToplevelBlock) $3;
1103                 current_container.AddMethod (method);
1105                 anonymous_host = null;
1106                 current_generic_method = null;
1107                 current_local_parameters = null;
1109                 if (RootContext.Documentation != null)
1110                         Lexer.doc_state = XmlCommentState.Allowed;
1111           }
1112         ;
1114 opt_error_modifier
1115         : /* empty */
1116         | modifiers 
1117           {
1118                 int m = (int) $1;
1119                 int i = 1;
1121                 while (m != 0){
1122                         if ((i & m) != 0){
1123                                 Report.Error (1585, lexer.Location,
1124                                         "Member modifier `{0}' must precede the member type and name",
1125                                         Modifiers.Name (i));
1126                         }
1127                         m &= ~i;
1128                         i = i << 1;
1129                 }
1130           }
1131         ;
1133 method_header
1134         : opt_attributes
1135           opt_modifiers
1136           type namespace_or_type_name
1137           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
1138           {
1139                 lexer.ConstraintsParsing = true;
1140           }
1141           opt_type_parameter_constraints_clauses
1142           {
1143                 lexer.ConstraintsParsing = false;
1145                 MemberName name = (MemberName) $4;
1147                 if ($9 != null && name.TypeArguments == null)
1148                         Report.Error (80, lexer.Location,
1149                                       "Constraints are not allowed on non-generic declarations");
1151                 Method method;
1153                 GenericMethod generic = null;
1154                 if (name.TypeArguments != null) {
1155                         generic = new GenericMethod (current_namespace, current_class, name,
1156                                                      (Expression) $3, (Parameters) $6);
1158                         generic.SetParameterInfo ((ArrayList) $9);
1159                 }
1161                 method = new Method (current_class, generic, (Expression) $3, (int) $2, false,
1162                                      name, (Parameters) $6, (Attributes) $1);
1164                 anonymous_host = method;
1165                 current_local_parameters = (Parameters) $6;
1166                 current_generic_method = generic;
1168                 if (RootContext.Documentation != null)
1169                         method.DocComment = Lexer.consume_doc_comment ();
1171                 $$ = method;
1172           }
1173         | opt_attributes
1174           opt_modifiers
1175           VOID namespace_or_type_name
1176           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
1177           {
1178                 lexer.ConstraintsParsing = true;
1179           }
1180           opt_type_parameter_constraints_clauses
1181           {
1182                 lexer.ConstraintsParsing = false;
1184                 MemberName name = (MemberName) $4;
1186                 if ($9 != null && name.TypeArguments == null)
1187                         Report.Error (80, lexer.Location,
1188                                       "Constraints are not allowed on non-generic declarations");
1190                 Method method;
1191                 GenericMethod generic = null;
1192                 if (name.TypeArguments != null) {
1193                         generic = new GenericMethod (current_namespace, current_class, name,
1194                                                      TypeManager.system_void_expr, (Parameters) $6);
1196                         generic.SetParameterInfo ((ArrayList) $9);
1197                 }
1199                 method = new Method (current_class, generic, TypeManager.system_void_expr,
1200                                      (int) $2, false, name, (Parameters) $6, (Attributes) $1);
1202                 anonymous_host = method;
1203                 current_local_parameters = (Parameters) $6;
1204                 current_generic_method = generic;
1206                 if (RootContext.Documentation != null)
1207                         method.DocComment = Lexer.consume_doc_comment ();
1209                 $$ = method;
1210           }
1211         | opt_attributes
1212           opt_modifiers
1213           type 
1214           modifiers namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1215           {
1216                 MemberName name = (MemberName) $5;
1217                 Report.Error (1585, name.Location, 
1218                         "Member modifier `{0}' must precede the member type and name", Modifiers.Name ((int) $4));
1220                 Method method = new Method (current_class, null, TypeManager.system_void_expr,
1221                                             0, false, name, (Parameters) $6, (Attributes) $1);
1223                 current_local_parameters = (Parameters) $6;
1225                 if (RootContext.Documentation != null)
1226                         method.DocComment = Lexer.consume_doc_comment ();
1228                 $$ = null;
1229           }
1230         ;
1232 method_body
1233         : block
1234         | SEMICOLON             { $$ = null; }
1235         ;
1237 opt_formal_parameter_list
1238         : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
1239         | formal_parameter_list
1240         ;
1242 formal_parameter_list
1243         : fixed_parameters              
1244           { 
1245                 ArrayList pars_list = (ArrayList) $1;
1247                 Parameter [] pars = new Parameter [pars_list.Count];
1248                 pars_list.CopyTo (pars);
1250                 $$ = new Parameters (pars); 
1251           } 
1252         | fixed_parameters COMMA parameter_array
1253           {
1254                 ArrayList pars_list = (ArrayList) $1;
1255                 pars_list.Add ($3);
1257                 Parameter [] pars = new Parameter [pars_list.Count];
1258                 pars_list.CopyTo (pars);
1260                 $$ = new Parameters (pars); 
1261           }
1262         | fixed_parameters COMMA ARGLIST
1263           {
1264                 ArrayList pars_list = (ArrayList) $1;
1265                 //pars_list.Add (new ArglistParameter (GetLocation ($3)));
1267                 Parameter [] pars = new Parameter [pars_list.Count];
1268                 pars_list.CopyTo (pars);
1270                 $$ = new Parameters (pars, true);
1271           }
1272         | parameter_array COMMA error
1273           {
1274                 if ($1 != null)
1275                         Report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list");
1276                 $$ = null;
1277           }
1278         | fixed_parameters COMMA parameter_array COMMA error
1279           {
1280                 if ($3 != null)
1281                         Report.Error (231, ((Parameter) $3).Location, "A params parameter must be the last parameter in a formal parameter list");
1282                 $$ = null;
1283           }
1284         | ARGLIST COMMA error
1285           {
1286                 Report.Error (257, (Location) $1, "An __arglist parameter must be the last parameter in a formal parameter list");
1287                 $$ = null;
1288           }
1289         | fixed_parameters COMMA ARGLIST COMMA error 
1290           {
1291                 Report.Error (257, (Location) $3, "An __arglist parameter must be the last parameter in a formal parameter list");
1292                 $$ = null;
1293           }
1294         | parameter_array 
1295           {
1296                 $$ = new Parameters (new Parameter[] { (Parameter) $1 } );
1297           }
1298         | ARGLIST
1299           {
1300                 $$ = new Parameters (new Parameter[0], true);
1301           }
1302         ;
1304 fixed_parameters
1305         : fixed_parameter       
1306           {
1307                 ArrayList pars = new ArrayList (4);
1309                 pars.Add ($1);
1310                 $$ = pars;
1311           }
1312         | fixed_parameters COMMA fixed_parameter
1313           {
1314                 ArrayList pars = (ArrayList) $1;
1316                 pars.Add ($3);
1317                 $$ = $1;
1318           }
1319         ;
1321 fixed_parameter
1322         : opt_attributes
1323           opt_parameter_modifier
1324           type
1325           IDENTIFIER
1326           {
1327                 LocatedToken lt = (LocatedToken) $4;
1328                 $$ = new Parameter ((Expression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
1329           }
1330         | opt_attributes
1331           opt_parameter_modifier
1332           type
1333           IDENTIFIER OPEN_BRACKET CLOSE_BRACKET
1334           {
1335                 LocatedToken lt = (LocatedToken) $4;
1336                 Report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name");
1337                 $$ = null;
1338           }
1339         | opt_attributes
1340           opt_parameter_modifier
1341           type
1342           {
1343                 Report.Error (1001, GetLocation ($3), "Identifier expected");
1344                 $$ = null;
1345           }
1346         | opt_attributes
1347           opt_parameter_modifier
1348           type
1349           error {
1350                 CheckIdentifierToken (yyToken, GetLocation ($4));
1351                 $$ = null;
1352           }
1353         | opt_attributes
1354           opt_parameter_modifier
1355           type
1356           IDENTIFIER
1357           ASSIGN
1358           constant_expression
1359            {
1360                 LocatedToken lt = (LocatedToken) $4;
1361                 Report.Error (241, lt.Location, "Default parameter specifiers are not permitted");
1362                  $$ = null;
1363            }
1364         ;
1366 opt_parameter_modifier
1367         : /* empty */           { $$ = Parameter.Modifier.NONE; }
1368         | parameter_modifier
1369         ;
1371 parameter_modifier
1372         : REF                   { $$ = Parameter.Modifier.REF; }
1373         | OUT                   { $$ = Parameter.Modifier.OUT; }
1374         ;
1376 parameter_array
1377         : opt_attributes PARAMS type IDENTIFIER
1378           { 
1379                 LocatedToken lt = (LocatedToken) $4;
1380                 $$ = new ParamsParameter ((Expression) $3, lt.Value, (Attributes) $1, lt.Location);
1381                 note ("type must be a single-dimension array type"); 
1382           }
1383         | opt_attributes PARAMS parameter_modifier type IDENTIFIER 
1384           {
1385                 Report.Error (1611, (Location) $2, "The params parameter cannot be declared as ref or out");
1386                 $$ = null;
1387           }
1388         | opt_attributes PARAMS type error {
1389                 CheckIdentifierToken (yyToken, GetLocation ($4));
1390                 $$ = null;
1391           }
1392         ;
1394 property_declaration
1395         : opt_attributes
1396           opt_modifiers
1397           type
1398           namespace_or_type_name
1399           {
1400                 if (RootContext.Documentation != null)
1401                         tmpComment = Lexer.consume_doc_comment ();
1402           }
1403           OPEN_BRACE 
1404           {
1405                 implicit_value_parameter_type = (Expression) $3;
1407                 lexer.PropertyParsing = true;
1408           }
1409           accessor_declarations 
1410           {
1411                 lexer.PropertyParsing = false;
1412                 has_get = has_set = false;
1413           }
1414           CLOSE_BRACE
1415           { 
1416                 if ($8 == null)
1417                         break;
1419                 Property prop;
1420                 Pair pair = (Pair) $8;
1421                 Accessor get_block = (Accessor) pair.First;
1422                 Accessor set_block = (Accessor) pair.Second;
1424                 MemberName name = (MemberName) $4;
1426                 if (name.TypeArguments != null)
1427                         syntax_error (lexer.Location, "a property can't have type arguments");
1429                 prop = new Property (current_class, (Expression) $3, (int) $2, false,
1430                                      name, (Attributes) $1, get_block, set_block);
1431                 
1432                 current_container.AddProperty (prop);
1433                 implicit_value_parameter_type = null;
1435                 if (RootContext.Documentation != null)
1436                         prop.DocComment = ConsumeStoredComment ();
1438           }
1439         ;
1441 accessor_declarations
1442         : get_accessor_declaration
1443          {
1444                 $$ = new Pair ($1, null);
1445          }
1446         | get_accessor_declaration accessor_declarations
1447          { 
1448                 Pair pair = (Pair) $2;
1449                 pair.First = $1;
1450                 $$ = pair;
1451          }
1452         | set_accessor_declaration
1453          {
1454                 $$ = new Pair (null, $1);
1455          }
1456         | set_accessor_declaration accessor_declarations
1457          { 
1458                 Pair pair = (Pair) $2;
1459                 pair.Second = $1;
1460                 $$ = pair;
1461          }
1462         | error
1463           {
1464                 Report.Error (1014, GetLocation ($1), "A get or set accessor expected");
1465                 $$ = null;
1466           }
1467         ;
1469 get_accessor_declaration
1470         : opt_attributes opt_modifiers GET
1471           {
1472                 // If this is not the case, then current_local_parameters has already
1473                 // been set in indexer_declaration
1474                 if (parsing_indexer == false)
1475                         current_local_parameters = null;
1476                 else 
1477                         current_local_parameters = indexer_parameters;
1478                 lexer.PropertyParsing = false;
1480                 anonymous_host = SimpleAnonymousHost.GetSimple ();
1481           }
1482           accessor_body
1483           {
1484                 if (has_get) {
1485                         Report.Error (1007, (Location) $3, "Property accessor already defined");
1486                         break;
1487                 }
1488                 Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, (Location) $3);
1489                 has_get = true;
1490                 current_local_parameters = null;
1491                 lexer.PropertyParsing = true;
1493                 SimpleAnonymousHost.Simple.Propagate (accessor);
1494                 anonymous_host = null;
1496                 if (RootContext.Documentation != null)
1497                         if (Lexer.doc_state == XmlCommentState.Error)
1498                                 Lexer.doc_state = XmlCommentState.NotAllowed;
1500                 $$ = accessor;
1501           }
1502         ;
1504 set_accessor_declaration
1505         : opt_attributes opt_modifiers SET 
1506           {
1507                 Parameter [] args;
1508                 Parameter implicit_value_parameter = new Parameter (
1509                         implicit_value_parameter_type, "value", 
1510                         Parameter.Modifier.NONE, null, (Location) $3);
1512                 if (parsing_indexer == false) {
1513                         args  = new Parameter [1];
1514                         args [0] = implicit_value_parameter;
1515                         current_local_parameters = new Parameters (args);
1516                 } else {
1517                         Parameter [] fpars = indexer_parameters.FixedParameters;
1519                         if (fpars != null){
1520                                 int count = fpars.Length;
1522                                 args = new Parameter [count + 1];
1523                                 fpars.CopyTo (args, 0);
1524                                 args [count] = implicit_value_parameter;
1525                         } else 
1526                                 args = null;
1527                         current_local_parameters = new Parameters (
1528                                 args);
1529                 }
1530                 
1531                 lexer.PropertyParsing = false;
1533                 anonymous_host = SimpleAnonymousHost.GetSimple ();
1534           }
1535           accessor_body
1536           {
1537                 if (has_set) {
1538                         Report.Error (1007, ((LocatedToken) $3).Location, "Property accessor already defined");
1539                         break;
1540                 }
1541                 Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, (Location) $3);
1542                 has_set = true;
1543                 current_local_parameters = null;
1544                 lexer.PropertyParsing = true;
1546                 SimpleAnonymousHost.Simple.Propagate (accessor);
1547                 anonymous_host = null;
1549                 if (RootContext.Documentation != null
1550                         && Lexer.doc_state == XmlCommentState.Error)
1551                         Lexer.doc_state = XmlCommentState.NotAllowed;
1553                 $$ = accessor;
1554           }
1555         ;
1557 accessor_body
1558         : block 
1559         | SEMICOLON             { $$ = null; }
1560         ;
1562 interface_declaration
1563         : opt_attributes
1564           opt_modifiers
1565           opt_partial
1566           INTERFACE
1567           {
1568                 lexer.ConstraintsParsing = true;
1569           }
1570           member_name
1571           {
1572                 MemberName name = MakeName ((MemberName) $6);
1574                 push_current_class (new Interface (
1575                         current_namespace, current_class, name, (int) $2,
1576                         (Attributes) $1), true, $3);
1577           }
1578           opt_class_base
1579           opt_type_parameter_constraints_clauses
1580           {
1581                 lexer.ConstraintsParsing = false;
1583                 if ($8 != null)
1584                         current_container.AddBasesForPart (current_class, (ArrayList) $8);
1586                 current_class.SetParameterInfo ((ArrayList) $9);
1588                 if (RootContext.Documentation != null) {
1589                         current_container.DocComment = Lexer.consume_doc_comment ();
1590                         Lexer.doc_state = XmlCommentState.Allowed;
1591                 }
1592           }
1593           interface_body
1594           { 
1595                 if (RootContext.Documentation != null)
1596                         Lexer.doc_state = XmlCommentState.Allowed;
1597           }
1598           opt_semicolon 
1599           {
1600                 $$ = pop_current_class ();
1601           }
1602         | opt_attributes opt_modifiers opt_partial INTERFACE error {
1603                 CheckIdentifierToken (yyToken, GetLocation ($5));
1604           }
1605         ;
1607 interface_body
1608         : OPEN_BRACE
1609           opt_interface_member_declarations
1610           CLOSE_BRACE
1611         ;
1613 opt_interface_member_declarations
1614         : /* empty */
1615         | interface_member_declarations
1616         ;
1618 interface_member_declarations
1619         : interface_member_declaration
1620         | interface_member_declarations interface_member_declaration
1621         ;
1623 interface_member_declaration
1624         : interface_method_declaration          
1625           { 
1626                 if ($1 == null)
1627                         break;
1629                 Method m = (Method) $1;
1631                 if (m.IsExplicitImpl)
1632                         Report.Error (541, m.Location, "`{0}': explicit interface declaration can only be declared in a class or struct",
1633                                 m.GetSignatureForError ());
1635                 current_container.AddMethod (m);
1637                 if (RootContext.Documentation != null)
1638                         Lexer.doc_state = XmlCommentState.Allowed;
1639           }
1640         | interface_property_declaration        
1641           { 
1642                 if ($1 == null)
1643                         break;
1645                 Property p = (Property) $1;
1647                 if (p.IsExplicitImpl)
1648                         Report.Error (541, p.Location, "`{0}': explicit interface declaration can only be declared in a class or struct",
1649                                 p.GetSignatureForError ());
1651                 current_container.AddProperty (p);
1653                 if (RootContext.Documentation != null)
1654                         Lexer.doc_state = XmlCommentState.Allowed;
1655           }
1656         | interface_event_declaration 
1657           { 
1658                 if ($1 != null){
1659                         Event e = (Event) $1;
1661                         if (e.IsExplicitImpl)
1662                         Report.Error (541, e.Location, "`{0}': explicit interface declaration can only be declared in a class or struct",
1663                                 e.GetSignatureForError ());
1664                         
1665                         current_container.AddEvent (e);
1666                 }
1668                 if (RootContext.Documentation != null)
1669                         Lexer.doc_state = XmlCommentState.Allowed;
1670           }
1671         | interface_indexer_declaration
1672           { 
1673                 if ($1 == null)
1674                         break;
1676                 Indexer i = (Indexer) $1;
1678                 if (i.IsExplicitImpl)
1679                         Report.Error (541, i.Location, "`{0}': explicit interface declaration can only be declared in a class or struct",
1680                                 i.GetSignatureForError ());
1682                 current_container.AddIndexer (i);
1684                 if (RootContext.Documentation != null)
1685                         Lexer.doc_state = XmlCommentState.Allowed;
1686           }
1687         | delegate_declaration
1688           {
1689                 if ($1 != null) {
1690                         Report.Error (524, GetLocation ($1), "`{0}': Interfaces cannot declare classes, structs, interfaces, delegates, enumerations or constants",
1691                                 ((MemberCore)$1).GetSignatureForError ());
1692                 }
1693           }
1694         | class_declaration
1695           {
1696                 if ($1 != null) {
1697                         Report.Error (524, GetLocation ($1), "`{0}': Interfaces cannot declare classes, structs, interfaces, delegates, enumerations or constants",
1698                                 ((MemberCore)$1).GetSignatureForError ());
1699                 }
1700           }
1701         | struct_declaration
1702           {
1703                 if ($1 != null) {
1704                         Report.Error (524, GetLocation ($1), "`{0}': Interfaces cannot declare classes, structs, interfaces, delegates, enumerations or constants",
1705                                 ((MemberCore)$1).GetSignatureForError ());
1706                 }
1707           }
1708         | enum_declaration 
1709           {
1710                 if ($1 != null) {
1711                         Report.Error (524, GetLocation ($1), "`{0}': Interfaces cannot declare classes, structs, interfaces, delegates, enumerations or constants",
1712                                 ((MemberCore)$1).GetSignatureForError ());
1713                 }
1714           }
1715         | interface_declaration 
1716           {
1717                 if ($1 != null) {
1718                         Report.Error (524, GetLocation ($1), "`{0}': Interfaces cannot declare classes, structs, interfaces, delegates, enumerations or constants",
1719                                 ((MemberCore)$1).GetSignatureForError ());
1720                 }
1721           } 
1722         | constant_declaration
1723           {
1724                 Report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
1725           }
1726         ;
1728 opt_new
1729         : opt_modifiers 
1730           {
1731                 int val = (int) $1;
1732                 val = Modifiers.Check (Modifiers.NEW | Modifiers.UNSAFE, val, 0, GetLocation ($1));
1733                 $$ = val;
1734           }
1735         ;
1737 interface_method_declaration_body
1738         : OPEN_BRACE
1739           {
1740                 lexer.ConstraintsParsing = false;
1741           }
1742           opt_statement_list CLOSE_BRACE
1743           {
1744                 Report.Error (531, lexer.Location,
1745                               "'{0}': interface members cannot have a definition", ((MemberName) $-1).ToString ());
1746                 $$ = null;
1747           }
1748         | SEMICOLON
1749         ;
1751 interface_method_declaration
1752         : opt_attributes opt_new type namespace_or_type_name
1753           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1754           {
1755                 lexer.ConstraintsParsing = true;
1756           }
1757           opt_type_parameter_constraints_clauses
1758           {
1759                 // Refer to the name as $-1 in interface_method_declaration_body          
1760                 $$ = $4;
1761           }
1762           interface_method_declaration_body
1763           {
1764                 lexer.ConstraintsParsing = false;
1766                 MemberName name = (MemberName) $4;
1768                 if ($9 != null && name.TypeArguments == null)
1769                         Report.Error (80, lexer.Location,
1770                                       "Constraints are not allowed on non-generic declarations");
1772                 GenericMethod generic = null;
1773                 if (name.TypeArguments != null) {
1774                         generic = new GenericMethod (current_namespace, current_class, name,
1775                                                      (Expression) $3, (Parameters) $6);
1777                         generic.SetParameterInfo ((ArrayList) $9);
1778                 }
1780                 $$ = new Method (current_class, generic, (Expression) $3, (int) $2, true, name,
1781                                  (Parameters) $6, (Attributes) $1);
1782                 if (RootContext.Documentation != null)
1783                         ((Method) $$).DocComment = Lexer.consume_doc_comment ();
1784           }
1785         | opt_attributes opt_new VOID namespace_or_type_name
1786           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1787           {
1788                 lexer.ConstraintsParsing = true;
1789           }
1790           opt_type_parameter_constraints_clauses
1791           {
1792                 $$ = $4;
1793           }
1794           interface_method_declaration_body
1795           {
1796                 lexer.ConstraintsParsing = false;
1798                 MemberName name = (MemberName) $4;
1800                 if ($9 != null && name.TypeArguments == null)
1801                         Report.Error (80, lexer.Location,
1802                                       "Constraints are not allowed on non-generic declarations");
1804                 GenericMethod generic = null;
1805                 if (name.TypeArguments != null) {
1806                         generic = new GenericMethod (current_namespace, current_class, name,
1807                                                      TypeManager.system_void_expr, (Parameters) $6);
1809                         generic.SetParameterInfo ((ArrayList) $9);
1810                 }
1812                 $$ = new Method (current_class, generic, TypeManager.system_void_expr, (int) $2,
1813                                  true, name, (Parameters) $6, (Attributes) $1);
1814                 if (RootContext.Documentation != null)
1815                         ((Method) $$).DocComment = Lexer.consume_doc_comment ();
1816           }
1817         ;
1819 interface_property_declaration
1820         : opt_attributes
1821           opt_new
1822           type IDENTIFIER 
1823           OPEN_BRACE 
1824           { lexer.PropertyParsing = true; }
1825           accessor_declarations 
1826           {
1827                 has_get = has_set = false; 
1828                 lexer.PropertyParsing = false;
1829           }
1830           CLOSE_BRACE
1831           {
1832                 LocatedToken lt = (LocatedToken) $4;
1833                 MemberName name = new MemberName (lt.Value, lt.Location);
1835                 if ($3 == TypeManager.system_void_expr) {
1836                         Report.Error (547, lt.Location, "`{0}': property or indexer cannot have void type", lt.Value);
1837                         break;
1838                 }
1840                 Property p = null;
1841                 if ($7 == null) {
1842                         p = new Property (current_class, (Expression) $3, (int) $2, true,
1843                                    name, (Attributes) $1,
1844                                    null, null);
1846                         Report.Error (548, p.Location, "`{0}': property or indexer must have at least one accessor", p.GetSignatureForError ());
1847                         break;
1848                 }
1850                 Pair pair = (Pair) $7;
1851                 p = new Property (current_class, (Expression) $3, (int) $2, true,
1852                                    name, (Attributes) $1,
1853                                    (Accessor)pair.First, (Accessor)pair.Second);
1855                 if (pair.First != null && ((Accessor)(pair.First)).Block != null) {
1856                         Report.Error (531, p.Location, "`{0}.get': interface members cannot have a definition", p.GetSignatureForError ());
1857                         $$ = null;
1858                         break;
1859                 }
1861                 if (pair.Second != null && ((Accessor)(pair.Second)).Block != null) {
1862                         Report.Error (531, p.Location, "`{0}.set': interface members cannot have a definition", p.GetSignatureForError ());
1863                         $$ = null;
1864                         break;
1865                 }
1867                 if (RootContext.Documentation != null)
1868                         p.DocComment = Lexer.consume_doc_comment ();
1870                 $$ = p;
1871           }
1872         | opt_attributes
1873           opt_new
1874           type error {
1875                 CheckIdentifierToken (yyToken, GetLocation ($4));
1876                 $$ = null;
1877           }
1878         ;
1881 interface_event_declaration
1882         : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
1883           {
1884                 LocatedToken lt = (LocatedToken) $5;
1885                 $$ = new EventField (current_class, (Expression) $4, (int) $2, true,
1886                                      new MemberName (lt.Value, lt.Location),
1887                                      (Attributes) $1);
1888                 if (RootContext.Documentation != null)
1889                         ((EventField) $$).DocComment = Lexer.consume_doc_comment ();
1890           }
1891         | opt_attributes opt_new EVENT type error {
1892                 CheckIdentifierToken (yyToken, GetLocation ($5));
1893                 $$ = null;
1894           }
1895         | opt_attributes opt_new EVENT type IDENTIFIER ASSIGN  {
1896                 LocatedToken lt = (LocatedToken) $5;
1897                 Report.Error (68, lt.Location, "`{0}.{1}': event in interface cannot have initializer", current_container.Name, lt.Value);
1898                 $$ = null;
1899           }
1900         | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE
1901           {
1902                 lexer.EventParsing = true;
1903           }
1904           event_accessor_declarations
1905           {
1906                 lexer.EventParsing = false;
1907           }
1908           CLOSE_BRACE {
1909                 Report.Error (69, (Location) $3, "Event in interface cannot have add or remove accessors");
1910                 $$ = null;
1911           }
1912         ;
1914 interface_indexer_declaration 
1915         : opt_attributes opt_new type THIS 
1916           OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
1917           OPEN_BRACE 
1918           { lexer.PropertyParsing = true; }
1919           accessor_declarations 
1920           { 
1921                 has_get = has_set = false;
1922                 lexer.PropertyParsing = false;
1923           }
1924           CLOSE_BRACE
1925           {
1926                 Indexer i = null;
1927                 if ($10 == null) {
1928                         i = new Indexer (current_class, (Expression) $3,
1929                                   new MemberName (TypeContainer.DefaultIndexerName, (Location) $4),
1930                                   (int) $2, true, (Parameters) $6, (Attributes) $1,
1931                                   null, null);
1933                         Report.Error (548, i.Location, "`{0}': property or indexer must have at least one accessor", i.GetSignatureForError ());
1934                         break;
1935                 }
1937                 Pair pair = (Pair) $10;
1938                 i = new Indexer (current_class, (Expression) $3,
1939                                   new MemberName (TypeContainer.DefaultIndexerName, (Location) $4),
1940                                   (int) $2, true, (Parameters) $6, (Attributes) $1,
1941                                    (Accessor)pair.First, (Accessor)pair.Second);
1943                 if (pair.First != null && ((Accessor)(pair.First)).Block != null) {
1944                         Report.Error (531, i.Location, "`{0}.get': interface members cannot have a definition", i.GetSignatureForError ());
1945                         $$ = null;
1946                         break;
1947                 }
1949                 if (pair.Second != null && ((Accessor)(pair.Second)).Block != null) {
1950                         Report.Error (531, i.Location, "`{0}.set': interface members cannot have a definition", i.GetSignatureForError ());
1951                         $$ = null;
1952                         break;
1953                 }
1955                 if (RootContext.Documentation != null)
1956                         i.DocComment = ConsumeStoredComment ();
1958                 $$ = i;
1959           }
1960         ;
1962 operator_declaration
1963         : opt_attributes opt_modifiers operator_declarator 
1964           {
1965                 anonymous_host = SimpleAnonymousHost.GetSimple ();
1966           }
1967           operator_body
1968           {
1969                 if ($3 == null)
1970                         break;
1972                 OperatorDeclaration decl = (OperatorDeclaration) $3;
1973                 
1974                 Parameter [] param_list = new Parameter [decl.arg2type != null ? 2 : 1];
1976                 param_list[0] = new Parameter (decl.arg1type, decl.arg1name, Parameter.Modifier.NONE, null, decl.location);
1977                 if (decl.arg2type != null)
1978                         param_list[1] = new Parameter (decl.arg2type, decl.arg2name, Parameter.Modifier.NONE, null, decl.location);
1980                 Operator op = new Operator (
1981                         current_class, decl.optype, decl.ret_type, (int) $2, 
1982                         new Parameters (param_list),
1983                         (ToplevelBlock) $5, (Attributes) $1, decl.location);
1985                 if (RootContext.Documentation != null) {
1986                         op.DocComment = tmpComment;
1987                         Lexer.doc_state = XmlCommentState.Allowed;
1988                 }
1990                 SimpleAnonymousHost.Simple.Propagate (op);
1991                 anonymous_host = null;
1993                 // Note again, checking is done in semantic analysis
1994                 current_container.AddOperator (op);
1996                 current_local_parameters = null;
1997           }
1998         ;
2000 operator_body 
2001         : block
2002         | SEMICOLON { $$ = null; }
2003         ; 
2004 operator_declarator
2005         : type OPERATOR overloadable_operator 
2006           OPEN_PARENS opt_parameter_modifier type IDENTIFIER CLOSE_PARENS
2007           {
2008                 // TODO: wrong location
2009                 if ((Parameter.Modifier)$5 != Parameter.Modifier.NONE)
2010                         Error_ParameterModifierNotValid ((Location) $2);
2011           
2012                 LocatedToken lt = (LocatedToken) $7;
2013                 Operator.OpType op = (Operator.OpType) $3;
2014                 CheckUnaryOperator (op, lt.Location);
2016                 if (op == Operator.OpType.Addition)
2017                         op = Operator.OpType.UnaryPlus;
2019                 if (op == Operator.OpType.Subtraction)
2020                         op = Operator.OpType.UnaryNegation;
2022                 Parameter [] pars = new Parameter [1];
2023                 Expression type = (Expression) $6;
2025                 pars [0] = new Parameter (type, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
2027                 current_local_parameters = new Parameters (pars);
2029                 if (RootContext.Documentation != null) {
2030                         tmpComment = Lexer.consume_doc_comment ();
2031                         Lexer.doc_state = XmlCommentState.NotAllowed;
2032                 }
2034                 $$ = new OperatorDeclaration (op, (Expression) $1, type, lt.Value,
2035                                               null, null, (Location) $2);
2036           }
2037         | type OPERATOR overloadable_operator
2038           OPEN_PARENS 
2039                 opt_parameter_modifier type IDENTIFIER COMMA
2040                 opt_parameter_modifier type IDENTIFIER 
2041           CLOSE_PARENS
2042           {
2043                 // TODO: wrong location
2044                 if ((Parameter.Modifier)$5 != Parameter.Modifier.NONE || (Parameter.Modifier)$9 != Parameter.Modifier.NONE)
2045                         Error_ParameterModifierNotValid ((Location) $2);
2047                 LocatedToken ltParam1 = (LocatedToken) $7;
2048                 LocatedToken ltParam2 = (LocatedToken) $11;
2049                 CheckBinaryOperator ((Operator.OpType) $3, (Location) $2);
2051                 Parameter [] pars = new Parameter [2];
2053                 Expression typeL = (Expression) $6;
2054                 Expression typeR = (Expression) $10;
2056                pars [0] = new Parameter (typeL, ltParam1.Value, Parameter.Modifier.NONE, null, ltParam1.Location);
2057                pars [1] = new Parameter (typeR, ltParam2.Value, Parameter.Modifier.NONE, null, ltParam2.Location);
2059                current_local_parameters = new Parameters (pars);
2061                 if (RootContext.Documentation != null) {
2062                         tmpComment = Lexer.consume_doc_comment ();
2063                         Lexer.doc_state = XmlCommentState.NotAllowed;
2064                 }
2065                
2066                $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1, 
2067                                              typeL, ltParam1.Value,
2068                                              typeR, ltParam2.Value, (Location) $2);
2069           }
2070         | conversion_operator_declarator
2071         | type OPERATOR overloadable_operator
2072           OPEN_PARENS 
2073                 opt_parameter_modifier type IDENTIFIER COMMA
2074                 opt_parameter_modifier type IDENTIFIER COMMA
2075                 opt_parameter_modifier type IDENTIFIER
2076           CLOSE_PARENS
2077           {
2078                 Report.Error (1534, (Location) $2, "Overloaded binary operator `{0}' takes two parameters",
2079                         Operator.GetName ((Operator.OpType) $3));
2080                 $$ = null;
2081           }
2082         | type OPERATOR overloadable_operator 
2083           OPEN_PARENS CLOSE_PARENS
2084           {
2085                 Report.Error (1535, (Location) $2, "Overloaded unary operator `{0}' takes one parameter",
2086                         Operator.GetName ((Operator.OpType) $3));
2087                 $$ = null;
2088           }
2089         ;
2091 overloadable_operator
2092 // Unary operators:
2093         : BANG   { $$ = Operator.OpType.LogicalNot; }
2094         | TILDE  { $$ = Operator.OpType.OnesComplement; }  
2095         | OP_INC { $$ = Operator.OpType.Increment; }
2096         | OP_DEC { $$ = Operator.OpType.Decrement; }
2097         | TRUE   { $$ = Operator.OpType.True; }
2098         | FALSE  { $$ = Operator.OpType.False; }
2099 // Unary and binary:
2100         | PLUS { $$ = Operator.OpType.Addition; }
2101         | MINUS { $$ = Operator.OpType.Subtraction; }
2102 // Binary:
2103         | STAR { $$ = Operator.OpType.Multiply; }
2104         | DIV {  $$ = Operator.OpType.Division; }
2105         | PERCENT { $$ = Operator.OpType.Modulus; }
2106         | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
2107         | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
2108         | CARRET { $$ = Operator.OpType.ExclusiveOr; }
2109         | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
2110         | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
2111         | OP_EQ { $$ = Operator.OpType.Equality; }
2112         | OP_NE { $$ = Operator.OpType.Inequality; }
2113         | OP_GT { $$ = Operator.OpType.GreaterThan; }
2114         | OP_LT { $$ = Operator.OpType.LessThan; }
2115         | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
2116         | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
2117         ;
2119 conversion_operator_declarator
2120         : IMPLICIT OPERATOR type OPEN_PARENS opt_parameter_modifier type IDENTIFIER CLOSE_PARENS
2121           {
2122                 // TODO: wrong location
2123                 if ((Parameter.Modifier)$5 != Parameter.Modifier.NONE)
2124                         Error_ParameterModifierNotValid (GetLocation ($4));
2126                 LocatedToken lt = (LocatedToken) $7;
2127                 Parameter [] pars = new Parameter [1];
2129                 pars [0] = new Parameter ((Expression) $6, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
2131                 current_local_parameters = new Parameters (pars);  
2132                   
2133                 if (RootContext.Documentation != null) {
2134                         tmpComment = Lexer.consume_doc_comment ();
2135                         Lexer.doc_state = XmlCommentState.NotAllowed;
2136                 }
2138                 $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, (Expression) $6, lt.Value,
2139                                               null, null, (Location) $2);
2140           }
2141         | EXPLICIT OPERATOR type OPEN_PARENS opt_parameter_modifier type IDENTIFIER CLOSE_PARENS
2142           {
2143                 // TODO: wrong location
2144                 if ((Parameter.Modifier)$5 != Parameter.Modifier.NONE)
2145                         Error_ParameterModifierNotValid (GetLocation ($4));
2146           
2147                 LocatedToken lt = (LocatedToken) $7;
2148                 Parameter [] pars = new Parameter [1];
2150                 pars [0] = new Parameter ((Expression) $6, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
2152                 current_local_parameters = new Parameters (pars);  
2153                   
2154                 if (RootContext.Documentation != null) {
2155                         tmpComment = Lexer.consume_doc_comment ();
2156                         Lexer.doc_state = XmlCommentState.NotAllowed;
2157                 }
2159                 $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, (Expression) $6, lt.Value,
2160                                               null, null, (Location) $2);
2161           }
2162         | IMPLICIT error 
2163           {
2164                 syntax_error ((Location) $1, "'operator' expected");
2165           }
2166         | EXPLICIT error 
2167           {
2168                 syntax_error ((Location) $1, "'operator' expected");
2169           }
2170         ;
2172 constructor_declaration
2173         : opt_attributes
2174           opt_modifiers
2175           constructor_declarator
2176           constructor_body
2177           { 
2178                 Constructor c = (Constructor) $3;
2179                 c.Block = (ToplevelBlock) $4;
2180                 c.OptAttributes = (Attributes) $1;
2181                 c.ModFlags = (int) $2;
2182         
2183                 if (RootContext.Documentation != null)
2184                         c.DocComment = ConsumeStoredComment ();
2186                 if (c.Name == current_container.Basename){
2187                         if ((c.ModFlags & Modifiers.STATIC) != 0){
2188                                 if ((c.ModFlags & Modifiers.Accessibility) != 0){
2189                                         Report.Error (515, c.Location,
2190                                                 "`{0}': access modifiers are not allowed on static constructors",
2191                                                 c.GetSignatureForError ());
2192                                 }
2193         
2194                                 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);   
2195         
2196                                 if (c.Initializer != null){
2197                                         Report.Error (514, c.Location,
2198                                                 "`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
2199                                                 c.GetSignatureForError ());
2200                                 }
2201                         } else {
2202                                 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
2203                         }
2204                 } else {
2205                         // We let another layer check the validity of the constructor.
2206                         //Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename);
2207                 }
2209                 current_container.AddConstructor (c);
2211                 current_local_parameters = null;
2212                 if (RootContext.Documentation != null)
2213                         Lexer.doc_state = XmlCommentState.Allowed;
2214           }
2215         ;
2217 constructor_declarator
2218         : IDENTIFIER
2219           {
2220                 if (RootContext.Documentation != null) {
2221                         tmpComment = Lexer.consume_doc_comment ();
2222                         Lexer.doc_state = XmlCommentState.Allowed;
2223                 }
2224           }
2225           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2226           {
2227                 current_local_parameters = (Parameters) $4;
2228           }
2229           opt_constructor_initializer
2230           {
2231                 LocatedToken lt = (LocatedToken) $1;
2232                 $$ = new Constructor (current_class, lt.Value, 0, (Parameters) $4,
2233                                       (ConstructorInitializer) $7, lt.Location);
2235                 anonymous_host = (IAnonymousHost) $$;
2236           }
2237         ;
2239 constructor_body
2240         : block
2241         | SEMICOLON             { $$ = null; }
2242         ;
2244 opt_constructor_initializer
2245         : /* empty */                   { $$ = null; }
2246         | constructor_initializer
2247         ;
2249 constructor_initializer
2250         : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
2251           {
2252                 $$ = new ConstructorBaseInitializer ((ArrayList) $4, (Location) $2);
2253           }
2254         | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
2255           {
2256                 $$ = new ConstructorThisInitializer ((ArrayList) $4, (Location) $2);
2257           }
2258         | COLON error {
2259                 Report.Error (1018, (Location) $1, "Keyword this or base expected");
2260                 $$ = null;
2261           }
2262         ;
2264 opt_finalizer
2265         : /* EMPTY */           { $$ = 0; }
2266         | UNSAFE                { $$ = Modifiers.UNSAFE; }
2267         | EXTERN                { $$ = Modifiers.EXTERN; }
2268         ;
2269         
2270 destructor_declaration
2271         : opt_attributes opt_finalizer TILDE 
2272           {
2273                 if (RootContext.Documentation != null) {
2274                         tmpComment = Lexer.consume_doc_comment ();
2275                         Lexer.doc_state = XmlCommentState.NotAllowed;
2276                 }
2277           }
2278           IDENTIFIER OPEN_PARENS CLOSE_PARENS block
2279           {
2280                 LocatedToken lt = (LocatedToken) $5;
2281                 if (lt.Value != current_container.MemberName.Name){
2282                         Report.Error (574, lt.Location, "Name of destructor must match name of class");
2283                 } else if (current_container.Kind != Kind.Class){
2284                         Report.Error (575, lt.Location, "Only class types can contain destructor");
2285                 } else {
2286                         Location l = lt.Location;
2288                         int m = (int) $2;
2289                         if (!RootContext.StdLib && current_container.Name == "System.Object")
2290                                 m |= Modifiers.PROTECTED | Modifiers.VIRTUAL;
2291                         else
2292                                 m |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
2293                         
2294                         Method d = new Destructor (
2295                                 current_class, TypeManager.system_void_expr, m, "Finalize", 
2296                                 Parameters.EmptyReadOnlyParameters, (Attributes) $1, l);
2297                         if (RootContext.Documentation != null)
2298                                 d.DocComment = ConsumeStoredComment ();
2299                   
2300                         d.Block = (ToplevelBlock) $8;
2301                         current_container.AddMethod (d);
2302                 }
2303           }
2304         ;
2306 event_declaration
2307         : opt_attributes
2308           opt_modifiers
2309           EVENT type variable_declarators SEMICOLON
2310           {
2311                 current_array_type = null;
2312                 foreach (VariableDeclaration var in (ArrayList) $5) {
2314                         MemberName name = new MemberName (var.identifier,
2315                                 var.Location);
2317                         EventField e = new EventField (
2318                                 current_class, (Expression) $4, (int) $2, false, name,
2319                                 (Attributes) $1);
2321                         e.Initializer = var.expression_or_array_initializer;
2323                         current_container.AddEvent (e);
2325                         if (RootContext.Documentation != null) {
2326                                 e.DocComment = Lexer.consume_doc_comment ();
2327                                 Lexer.doc_state = XmlCommentState.Allowed;
2328                         }
2329                 }
2330           }
2331         | opt_attributes
2332           opt_modifiers
2333           EVENT type namespace_or_type_name
2334           OPEN_BRACE
2335           {
2336                 implicit_value_parameter_type = (Expression) $4;  
2337                 lexer.EventParsing = true;
2338           }
2339           event_accessor_declarations
2340           {
2341                 lexer.EventParsing = false;  
2342           }
2343           CLOSE_BRACE
2344           {
2345                 MemberName name = (MemberName) $5;
2347                 if ($8 == null){
2348                         Report.Error (65, (Location) $3, "`{0}.{1}': event property must have both add and remove accessors",
2349                                 current_container.Name, name.ToString ());
2350                         $$ = null;
2351                 } else {
2352                         Pair pair = (Pair) $8;
2353                         
2354                         if (name.TypeArguments != null)
2355                                 syntax_error (lexer.Location, "an event can't have type arguments");
2357                         if (pair.First == null || pair.Second == null)
2358                                 // CS0073 is already reported, so no CS0065 here.
2359                                 $$ = null;
2360                         else {
2361                                 Event e = new EventProperty (
2362                                         current_class, (Expression) $4, (int) $2, false, name,
2363                                         (Attributes) $1, (Accessor) pair.First, (Accessor) pair.Second);
2364                                 if (RootContext.Documentation != null) {
2365                                         e.DocComment = Lexer.consume_doc_comment ();
2366                                         Lexer.doc_state = XmlCommentState.Allowed;
2367                                 }
2369                                 current_container.AddEvent (e);
2370                                 implicit_value_parameter_type = null;
2371                         }
2372                 }
2373           }
2374         | opt_attributes opt_modifiers EVENT type namespace_or_type_name error {
2375                 MemberName mn = (MemberName) $5;
2377                 if (mn.Left != null)
2378                         Report.Error (71, mn.Location, "An explicit interface implementation of an event must use property syntax");
2379                 else 
2380                         Report.Error (71, mn.Location, "Event declaration should use property syntax");
2382                 if (RootContext.Documentation != null)
2383                         Lexer.doc_state = XmlCommentState.Allowed;
2384           }
2385         ;
2387 event_accessor_declarations
2388         : add_accessor_declaration remove_accessor_declaration
2389           {
2390                 $$ = new Pair ($1, $2);
2391           }
2392         | remove_accessor_declaration add_accessor_declaration
2393           {
2394                 $$ = new Pair ($2, $1);
2395           }     
2396         | add_accessor_declaration  { $$ = null; } 
2397         | remove_accessor_declaration { $$ = null; } 
2398         | error
2399           { 
2400                 Report.Error (1055, GetLocation ($1), "An add or remove accessor expected");
2401                 $$ = null;
2402           }
2403         | { $$ = null; }
2404         ;
2406 add_accessor_declaration
2407         : opt_attributes ADD
2408           {
2409                 Parameter [] args = new Parameter [1];
2410                 Parameter implicit_value_parameter = new Parameter (
2411                         implicit_value_parameter_type, "value", 
2412                         Parameter.Modifier.NONE, null, (Location) $2);
2414                 args [0] = implicit_value_parameter;
2415                 
2416                 current_local_parameters = new Parameters (args);  
2417                 lexer.EventParsing = false;
2418           }
2419           block
2420           {
2421                 $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, (Location) $2);
2422                 lexer.EventParsing = true;
2423           }
2424         | opt_attributes ADD error {
2425                 Report.Error (73, (Location) $2, "An add or remove accessor must have a body");
2426                 $$ = null;
2427           }
2428         | opt_attributes modifiers ADD {
2429                 Report.Error (1609, (Location) $3, "Modifiers cannot be placed on event accessor declarations");
2430                 $$ = null;
2431           }
2432         ;
2434 remove_accessor_declaration
2435         : opt_attributes REMOVE
2436           {
2437                 Parameter [] args = new Parameter [1];
2438                 Parameter implicit_value_parameter = new Parameter (
2439                         implicit_value_parameter_type, "value", 
2440                         Parameter.Modifier.NONE, null, (Location) $2);
2442                 args [0] = implicit_value_parameter;
2443                 
2444                 current_local_parameters = new Parameters (args);  
2445                 lexer.EventParsing = false;
2446           }
2447           block
2448           {
2449                 $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, (Location) $2);
2450                 lexer.EventParsing = true;
2451           }
2452         | opt_attributes REMOVE error {
2453                 Report.Error (73, (Location) $2, "An add or remove accessor must have a body");
2454                 $$ = null;
2455           }
2456         | opt_attributes modifiers REMOVE {
2457                 Report.Error (1609, (Location) $3, "Modifiers cannot be placed on event accessor declarations");
2458                 $$ = null;
2459           }
2460         ;
2462 indexer_declaration
2463         : opt_attributes opt_modifiers indexer_declarator 
2464           OPEN_BRACE
2465           {
2466                 IndexerDeclaration decl = (IndexerDeclaration) $3;
2468                 implicit_value_parameter_type = decl.type;
2469                 
2470                 lexer.PropertyParsing = true;
2471                 parsing_indexer  = true;
2472                 
2473                 indexer_parameters = decl.param_list;
2474                 anonymous_host = SimpleAnonymousHost.GetSimple ();
2475           }
2476           accessor_declarations 
2477           {
2478                   lexer.PropertyParsing = false;
2479                   has_get = has_set = false;
2480                   parsing_indexer  = false;
2481           }
2482           CLOSE_BRACE
2483           { 
2484                 if ($6 == null)
2485                         break;
2487                 // The signature is computed from the signature of the indexer.  Look
2488                 // at section 3.6 on the spec
2489                 Indexer indexer;
2490                 IndexerDeclaration decl = (IndexerDeclaration) $3;
2491                 Pair pair = (Pair) $6;
2492                 Accessor get_block = (Accessor) pair.First;
2493                 Accessor set_block = (Accessor) pair.Second;
2495                 MemberName name;
2496                 if (decl.interface_type != null)
2497                         name = new MemberName (
2498                                 decl.interface_type, TypeContainer.DefaultIndexerName, decl.location);
2499                 else
2500                         name = new MemberName (TypeContainer.DefaultIndexerName, decl.location);
2502                 indexer = new Indexer (current_class, decl.type, name,
2503                                        (int) $2, false, decl.param_list, (Attributes) $1,
2504                                        get_block, set_block);
2506                 if (RootContext.Documentation != null)
2507                         indexer.DocComment = ConsumeStoredComment ();
2509                 current_container.AddIndexer (indexer);
2510                 
2511                 current_local_parameters = null;
2512                 implicit_value_parameter_type = null;
2513                 indexer_parameters = null;
2514           }
2515         ;
2517 indexer_declarator
2518         : type THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
2519           {
2520                 Parameters pars = (Parameters) $4;
2521                 if (pars.HasArglist) {
2522                         // "__arglist is not valid in this context"
2523                         Report.Error (1669, (Location) $2, "__arglist is not valid in this context");
2524                 } else if (pars.Empty){
2525                         Report.Error (1551, (Location) $2, "Indexers must have at least one parameter");
2526                 }
2527                 if (RootContext.Documentation != null) {
2528                         tmpComment = Lexer.consume_doc_comment ();
2529                         Lexer.doc_state = XmlCommentState.Allowed;
2530                 }
2532                 $$ = new IndexerDeclaration ((Expression) $1, null, pars, (Location) $2);
2533           }
2534         | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
2535           {
2536                 Parameters pars = (Parameters) $6;
2538                 if (pars.HasArglist) {
2539                         // "__arglist is not valid in this context"
2540                         Report.Error (1669, (Location) $4, "__arglist is not valid in this context");
2541                 } else if (pars.Empty){
2542                         Report.Error (1551, (Location) $4, "Indexers must have at least one parameter");
2543                 }
2545                 MemberName name = (MemberName) $2;
2546                 $$ = new IndexerDeclaration ((Expression) $1, name, pars, (Location) $4);
2548                 if (RootContext.Documentation != null) {
2549                         tmpComment = Lexer.consume_doc_comment ();
2550                         Lexer.doc_state = XmlCommentState.Allowed;
2551                 }
2552           }
2553         ;
2555 enum_declaration
2556         : opt_attributes
2557           opt_modifiers
2558           ENUM IDENTIFIER 
2559           opt_enum_base {
2560                 if (RootContext.Documentation != null)
2561                         enumTypeComment = Lexer.consume_doc_comment ();
2562           }
2563           enum_body
2564           opt_semicolon
2565           {
2566                 LocatedToken lt = (LocatedToken) $4;
2567                 Location enum_location = lt.Location;
2569                 MemberName name = MakeName (new MemberName (lt.Value, enum_location));
2570                 Enum e = new Enum (current_namespace, current_class, (Expression) $5, (int) $2,
2571                                    name, (Attributes) $1);
2572                 
2573                 if (RootContext.Documentation != null)
2574                         e.DocComment = enumTypeComment;
2577                 EnumMember em = null;
2578                 foreach (VariableDeclaration ev in (ArrayList) $7) {
2579                         em = new EnumMember (e, em, (Expression) ev.expression_or_array_initializer,
2580                                 new MemberName (ev.identifier, ev.Location), ev.OptAttributes);
2582 //                      if (RootContext.Documentation != null)
2583                                 em.DocComment = ev.DocComment;
2585                         e.AddEnumMember (em);
2586                 }
2588                 current_container.AddEnum (e);
2589                 $$ = e;
2591           }
2592         ;
2594 opt_enum_base
2595         : /* empty */           { $$ = TypeManager.system_int32_expr; }
2596         | COLON type            { $$ = $2;   }
2597         ;
2599 enum_body
2600         : OPEN_BRACE
2601           {
2602                 if (RootContext.Documentation != null)
2603                         Lexer.doc_state = XmlCommentState.Allowed;
2604           }
2605           opt_enum_member_declarations
2606           {
2607                 // here will be evaluated after CLOSE_BLACE is consumed.
2608                 if (RootContext.Documentation != null)
2609                         Lexer.doc_state = XmlCommentState.Allowed;
2610           }
2611           CLOSE_BRACE
2612           {
2613                 $$ = $3;
2614           }
2615         ;
2617 opt_enum_member_declarations
2618         : /* empty */                   { $$ = new ArrayList (4); }
2619         | enum_member_declarations opt_comma { $$ = $1; }
2620         ;
2622 enum_member_declarations
2623         : enum_member_declaration 
2624           {
2625                 ArrayList l = new ArrayList (4);
2627                 l.Add ($1);
2628                 $$ = l;
2629           }
2630         | enum_member_declarations COMMA enum_member_declaration
2631           {
2632                 ArrayList l = (ArrayList) $1;
2634                 l.Add ($3);
2636                 $$ = l;
2637           }
2638         ;
2640 enum_member_declaration
2641         : opt_attributes IDENTIFIER 
2642           {
2643                 VariableDeclaration vd = new VariableDeclaration (
2644                         (LocatedToken) $2, null, (Attributes) $1);
2646                 if (RootContext.Documentation != null) {
2647                         vd.DocComment = Lexer.consume_doc_comment ();
2648                         Lexer.doc_state = XmlCommentState.Allowed;
2649                 }
2651                 $$ = vd;
2652           }
2653         | opt_attributes IDENTIFIER
2654           {
2655                 if (RootContext.Documentation != null) {
2656                         tmpComment = Lexer.consume_doc_comment ();
2657                         Lexer.doc_state = XmlCommentState.NotAllowed;
2658                 }
2659           }
2660           ASSIGN expression
2661           { 
2662                 VariableDeclaration vd = new VariableDeclaration (
2663                         (LocatedToken) $2, $5, (Attributes) $1);
2665                 if (RootContext.Documentation != null)
2666                         vd.DocComment = ConsumeStoredComment ();
2668                 $$ = vd;
2669           }
2670         ;
2672 delegate_declaration
2673         : opt_attributes
2674           opt_modifiers
2675           DELEGATE
2676           {
2677                 lexer.ConstraintsParsing = true;
2678           }
2679           type member_name
2680           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2681           {
2682                 MemberName name = MakeName ((MemberName) $6);
2683                 Parameters p = (Parameters) $8;
2684                 if (p.HasArglist) {
2685                         // TODO: wrong location
2686                         Report.Error (1669, name.Location, "__arglist is not valid in this context");
2687                 }
2689                 Delegate del = new Delegate (current_namespace, current_class, (Expression) $5,
2690                                              (int) $2, name, p, (Attributes) $1);
2692                 if (RootContext.Documentation != null) {
2693                         del.DocComment = Lexer.consume_doc_comment ();
2694                         Lexer.doc_state = XmlCommentState.Allowed;
2695                 }
2697                 current_container.AddDelegate (del);
2698                 current_delegate = del;
2699           }
2700           opt_type_parameter_constraints_clauses
2701           {
2702                 lexer.ConstraintsParsing = false;
2703           }
2704           SEMICOLON
2705           {
2706                 current_delegate.SetParameterInfo ((ArrayList) $11);
2707                 $$ = current_delegate;
2709                 current_delegate = null;
2710           }
2711         ;
2713 opt_nullable
2714         : /* empty */
2715           {
2716                 lexer.CheckNullable (false);
2717                 $$ = false;
2718           }
2719         | INTERR
2720           {
2721                 lexer.CheckNullable (true);
2722                 $$ = true;
2723           }
2724         ;
2726 namespace_or_type_name
2727         : member_name
2728         | IDENTIFIER DOUBLE_COLON IDENTIFIER {
2729                 LocatedToken lt1 = (LocatedToken) $1;
2730                 LocatedToken lt2 = (LocatedToken) $3;
2731                 $$ = new MemberName (lt1.Value, lt2.Value, lt2.Location);
2732           }
2733         | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list {
2734                 LocatedToken lt = (LocatedToken) $3;
2735                 $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location);
2736           }
2737         ;
2739 member_name
2740         : IDENTIFIER opt_type_argument_list {
2741                 LocatedToken lt = (LocatedToken) $1;
2742                 $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location);
2743           }
2744         ;
2746 opt_type_argument_list
2747         : /* empty */                { $$ = null; } 
2748         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2749           {
2750                 $$ = $2;
2751                 if (RootContext.Version == LanguageVersion.ISO_1)
2752                         Report.FeatureIsNotStandardized (lexer.Location, "generics");
2753           }
2754         | GENERIC_DIMENSION
2755           {
2756                 $$ = new TypeArguments ((int) $1, lexer.Location);
2757                 if (RootContext.Version == LanguageVersion.ISO_1)
2758                         Report.FeatureIsNotStandardized (lexer.Location, "generics");
2759           }
2760         ;
2762 type_arguments
2763         : opt_attributes type {
2764                 TypeArguments type_args = new TypeArguments (lexer.Location);
2765                 if ($1 != null) {
2766                         SimpleName sn = $2 as SimpleName;
2767                         if (sn == null)
2768                                 Report.Error (1031, lexer.Location, "Type expected");
2769                         else
2770                                 $2 = new TypeParameterName (sn.Name, (Attributes) $1, lexer.Location);
2771                 }
2772                 type_args.Add ((Expression) $2);
2773                 $$ = type_args;
2774           }
2775         | type_arguments COMMA opt_attributes type {
2776                 TypeArguments type_args = (TypeArguments) $1;
2777                 if ($3 != null) {
2778                         SimpleName sn = $4 as SimpleName;
2779                         if (sn == null)
2780                                 Report.Error (1031, lexer.Location, "Type expected");
2781                         else
2782                                 $4 = new TypeParameterName (sn.Name, (Attributes) $3, lexer.Location);
2783                 }
2784                 type_args.Add ((Expression) $4);
2785                 $$ = type_args;
2786           }
2787         ;
2789         
2790 /* 
2791  * Before you think of adding a return_type, notice that we have been
2792  * using two rules in the places where it matters (one rule using type
2793  * and another identical one that uses VOID as the return type).  This
2794  * gets rid of a shift/reduce couple
2795  */
2796 type
2797         : namespace_or_type_name opt_nullable
2798           {
2799                 MemberName name = (MemberName) $1;
2800                 $$ = name.GetTypeExpression ();
2802                 if ((bool) $2)
2803                         $$ = new ComposedCast ((Expression) $$, "?", lexer.Location);
2804           }
2805         | builtin_types opt_nullable
2806           {
2807                 if ((bool) $2)
2808                         $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
2809           }
2810         | array_type
2811         | pointer_type
2812         ;
2814 pointer_type
2815         : type STAR
2816           {
2817                 //
2818                 // Note that here only unmanaged types are allowed but we
2819                 // can't perform checks during this phase - we do it during
2820                 // semantic analysis.
2821                 //
2822                 $$ = new ComposedCast ((Expression) $1, "*", Lexer.Location);
2823           }
2824         | VOID STAR
2825           {
2826                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1);
2827           }
2828         ;
2830 non_expression_type
2831         : builtin_types opt_nullable
2832           {
2833                 if ((bool) $2)
2834                         $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
2835           }
2836         | non_expression_type rank_specifier
2837           {
2838                 Location loc = GetLocation ($1);
2839                 if (loc.IsNull)
2840                         loc = lexer.Location;
2841                 $$ = new ComposedCast ((Expression) $1, (string) $2, loc);
2842           }
2843         | non_expression_type STAR
2844           {
2845                 Location loc = GetLocation ($1);
2846                 if (loc.IsNull)
2847                         loc = lexer.Location;
2848                 $$ = new ComposedCast ((Expression) $1, "*", loc);
2849           }
2850         | expression rank_specifiers 
2851           {
2852                 $$ = new ComposedCast ((Expression) $1, (string) $2);
2853           }
2854         | expression STAR 
2855           {
2856                 $$ = new ComposedCast ((Expression) $1, "*");
2857           }
2858         
2859         //
2860         // We need this because the parser will happily go and reduce IDENTIFIER STAR
2861         // through this different path
2862         //
2863         | multiplicative_expression STAR 
2864           {
2865                 $$ = new ComposedCast ((Expression) $1, "*");
2866           }
2867         ;
2869 type_list
2870         : type
2871           {
2872                 ArrayList types = new ArrayList (4);
2874                 types.Add ($1);
2875                 $$ = types;
2876           }
2877         | type_list COMMA type
2878           {
2879                 ArrayList types = (ArrayList) $1;
2881                 types.Add ($3);
2882                 $$ = types;
2883           }
2884         ;
2887  * replaces all the productions for isolating the various
2888  * simple types, but we need this to reuse it easily in local_variable_type
2889  */
2890 builtin_types
2891         : OBJECT        { $$ = TypeManager.system_object_expr; }
2892         | STRING        { $$ = TypeManager.system_string_expr; }
2893         | BOOL          { $$ = TypeManager.system_boolean_expr; }
2894         | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
2895         | FLOAT         { $$ = TypeManager.system_single_expr; }
2896         | DOUBLE        { $$ = TypeManager.system_double_expr; }
2897         | integral_type
2898         ;
2900 integral_type
2901         : SBYTE         { $$ = TypeManager.system_sbyte_expr; }
2902         | BYTE          { $$ = TypeManager.system_byte_expr; }
2903         | SHORT         { $$ = TypeManager.system_int16_expr; }
2904         | USHORT        { $$ = TypeManager.system_uint16_expr; }
2905         | INT           { $$ = TypeManager.system_int32_expr; }
2906         | UINT          { $$ = TypeManager.system_uint32_expr; }
2907         | LONG          { $$ = TypeManager.system_int64_expr; }
2908         | ULONG         { $$ = TypeManager.system_uint64_expr; }
2909         | CHAR          { $$ = TypeManager.system_char_expr; }
2910         | VOID          { $$ = TypeManager.system_void_expr; }
2911         ;
2913 array_type
2914         : type rank_specifiers opt_nullable
2915           {
2916                 string rank_specifiers = (string) $2;
2917                 if ((bool) $3)
2918                         rank_specifiers += "?";
2920                 $$ = current_array_type = new ComposedCast ((Expression) $1, rank_specifiers);
2921           }
2922         ;
2925 // Expressions, section 7.5
2927 primary_expression
2928         : literal
2929           {
2930                 // 7.5.1: Literals
2931           }
2932         | member_name
2933           {
2934                 MemberName mn = (MemberName) $1;
2935                 $$ = mn.GetTypeExpression ();
2936           }
2937         | IDENTIFIER DOUBLE_COLON IDENTIFIER
2938           {
2939                 LocatedToken lt1 = (LocatedToken) $1;
2940                 LocatedToken lt2 = (LocatedToken) $3;
2941                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, lt2.Location);
2942           }
2943         | parenthesized_expression
2944         | default_value_expression
2945         | member_access
2946         | invocation_expression
2947         | element_access
2948         | this_access
2949         | base_access
2950         | post_increment_expression
2951         | post_decrement_expression
2952         | new_expression
2953         | typeof_expression
2954         | sizeof_expression
2955         | checked_expression
2956         | unchecked_expression
2957         | pointer_member_access
2958         | anonymous_method_expression
2959         ;
2961 literal
2962         : boolean_literal
2963         | integer_literal
2964         | real_literal
2965         | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value, lexer.Location); }
2966         | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value, lexer.Location); } 
2967         | NULL                  { $$ = new NullLiteral (lexer.Location); }
2968         ;
2970 real_literal
2971         : LITERAL_FLOAT         { $$ = new FloatLiteral ((float) lexer.Value, lexer.Location); }
2972         | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value, lexer.Location); }
2973         | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value, lexer.Location); }
2974         ;
2976 integer_literal
2977         : LITERAL_INTEGER       { 
2978                 object v = lexer.Value;
2980                 if (v is int){
2981                         $$ = new IntLiteral ((int) v, lexer.Location);
2982                 } else if (v is uint)
2983                         $$ = new UIntLiteral ((UInt32) v, lexer.Location);
2984                 else if (v is long)
2985                         $$ = new LongLiteral ((Int64) v, lexer.Location);
2986                 else if (v is ulong)
2987                         $$ = new ULongLiteral ((UInt64) v, lexer.Location);
2988                 else
2989                         Console.WriteLine ("OOPS.  Unexpected result from scanner");
2990           }
2991         ;
2993 boolean_literal
2994         : TRUE                  { $$ = new BoolLiteral (true, lexer.Location); }
2995         | FALSE                 { $$ = new BoolLiteral (false, lexer.Location); }
2996         ;
2998 parenthesized_expression_0
2999         : OPEN_PARENS expression CLOSE_PARENS
3000           {
3001                 $$ = $2;
3002                 lexer.Deambiguate_CloseParens ($$);
3003                 // After this, the next token returned is one of
3004                 // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST (CLOSE_PARENS), CLOSE_PARENS_OPEN_PARENS
3005                 // or CLOSE_PARENS_MINUS.
3006           }
3007         | OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); }
3008         ;
3010 parenthesized_expression
3011         : parenthesized_expression_0 CLOSE_PARENS_NO_CAST
3012           {
3013                 $$ = $1;
3014           }  
3015         | parenthesized_expression_0 CLOSE_PARENS
3016           {
3017                 $$ = $1;
3018           }       
3019         | parenthesized_expression_0 CLOSE_PARENS_MINUS
3020           {
3021                 // If a parenthesized expression is followed by a minus, we need to wrap
3022                 // the expression inside a ParenthesizedExpression for the CS0075 check
3023                 // in Binary.DoResolve().
3024                 $$ = new ParenthesizedExpression ((Expression) $1);
3025           }
3026         ;
3028 member_access
3029         : primary_expression DOT IDENTIFIER opt_type_argument_list
3030           {
3031                 LocatedToken lt = (LocatedToken) $3;
3032                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3033           }
3034         | predefined_type DOT IDENTIFIER opt_type_argument_list
3035           {
3036                 LocatedToken lt = (LocatedToken) $3;
3037                 // TODO: Location is wrong as some predefined types doesn't hold a location
3038                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3039           }
3040         ;
3042 predefined_type
3043         : builtin_types
3044         ;
3046 invocation_expression
3047         : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3048           {
3049                 if ($1 == null)
3050                         Report.Error (1, (Location) $2, "Parse error");
3051                 else
3052                         $$ = new Invocation ((Expression) $1, (ArrayList) $3);
3053           }
3054         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS
3055           {
3056                 $$ = new Invocation ((Expression) $1, new ArrayList ());
3057           }
3058         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression
3059           {
3060                 $$ = new InvocationOrCast ((Expression) $1, (Expression) $3);
3061           }
3062         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS non_simple_argument CLOSE_PARENS
3063           {
3064                 ArrayList args = new ArrayList (1);
3065                 args.Add ($4);
3066                 $$ = new Invocation ((Expression) $1, args);
3067           }
3068         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS argument_list COMMA argument CLOSE_PARENS
3069           {
3070                 ArrayList args = ((ArrayList) $4);
3071                 args.Add ($6);
3072                 $$ = new Invocation ((Expression) $1, args);
3073           }
3074         ;
3076 opt_argument_list
3077         : /* empty */           { $$ = null; }
3078         | argument_list
3079         ;
3081 argument_list
3082         : argument
3083           { 
3084                 ArrayList list = new ArrayList (4);
3085                 list.Add ($1);
3086                 $$ = list;
3087           }
3088         | argument_list COMMA argument
3089           {
3090                 ArrayList list = (ArrayList) $1;
3091                 list.Add ($3);
3092                 $$ = list;
3093           }
3094         | argument_list error {
3095                 CheckToken (1026, yyToken, "Expected `,' or `)'", GetLocation ($2));
3096                 $$ = null;
3097           }
3098         ;
3100 argument
3101         : expression
3102           {
3103                 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3104           }
3105         | non_simple_argument
3106           {
3107                 $$ = $1;
3108           }
3109         ;
3111 non_simple_argument
3112         : REF variable_reference 
3113           { 
3114                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3115           }
3116         | OUT variable_reference 
3117           { 
3118                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
3119           }
3120         | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
3121           {
3122                 ArrayList list = (ArrayList) $3;
3123                 Argument[] args = new Argument [list.Count];
3124                 list.CopyTo (args, 0);
3126                 Expression expr = new Arglist (args, (Location) $1);
3127                 $$ = new Argument (expr, Argument.AType.Expression);
3128           }
3129         | ARGLIST
3130           {
3131                 $$ = new Argument (new ArglistAccess ((Location) $1), Argument.AType.ArgList);
3132           }
3133         ;
3135 variable_reference
3136         : expression { note ("section 5.4"); $$ = $1; }
3137         ;
3139 element_access
3140         : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET 
3141           {
3142                 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3);
3143           }
3144         | primary_expression rank_specifiers
3145           {
3146                 // So the super-trick is that primary_expression
3147                 // can only be either a SimpleName or a MemberAccess. 
3148                 // The MemberAccess case arises when you have a fully qualified type-name like :
3149                 // Foo.Bar.Blah i;
3150                 // SimpleName is when you have
3151                 // Blah i;
3152                   
3153                 Expression expr = (Expression) $1;  
3154                 if (expr is ComposedCast){
3155                         $$ = new ComposedCast (expr, (string) $2);
3156                 } else if (!(expr is SimpleName || expr is MemberAccess || expr is ConstructedType || expr is QualifiedAliasMember)){
3157                         Error_ExpectingTypeName (expr);
3158                         $$ = TypeManager.system_object_expr;
3159                 } else {
3160                         //
3161                         // So we extract the string corresponding to the SimpleName
3162                         // or MemberAccess
3163                         // 
3164                         $$ = new ComposedCast (expr, (string) $2);
3165                 }
3166                 current_array_type = (Expression)$$;
3167           }
3168         ;
3170 expression_list
3171         : expression
3172           {
3173                 ArrayList list = new ArrayList (4);
3174                 list.Add ($1);
3175                 $$ = list;
3176           }
3177         | expression_list COMMA expression
3178           {
3179                 ArrayList list = (ArrayList) $1;
3180                 list.Add ($3);
3181                 $$ = list;
3182           }
3183         ;
3185 this_access
3186         : THIS
3187           {
3188                 $$ = new This (current_block, (Location) $1);
3189           }
3190         ;
3192 base_access
3193         : BASE DOT IDENTIFIER opt_type_argument_list
3194           {
3195                 LocatedToken lt = (LocatedToken) $3;
3196                 $$ = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location);
3197           }
3198         | BASE OPEN_BRACKET expression_list CLOSE_BRACKET
3199           {
3200                 $$ = new BaseIndexerAccess ((ArrayList) $3, (Location) $1);
3201           }
3202         | BASE error {
3203                 Report.Error (175, (Location) $1, "Use of keyword `base' is not valid in this context");
3204                 $$ = null;
3205           }
3206         ;
3208 post_increment_expression
3209         : primary_expression OP_INC
3210           {
3211                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement,
3212                                        (Expression) $1, (Location) $2);
3213           }
3214         ;
3216 post_decrement_expression
3217         : primary_expression OP_DEC
3218           {
3219                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement,
3220                                        (Expression) $1, (Location) $2);
3221           }
3222         ;
3224 new_expression
3225         : object_or_delegate_creation_expression
3226         | array_creation_expression
3227         ;
3229 object_or_delegate_creation_expression
3230         : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3231           {
3232                 $$ = new New ((Expression) $2, (ArrayList) $4, (Location) $1);
3233           }
3234         ;
3236 array_creation_expression
3237         : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET 
3238           opt_rank_specifier
3239           opt_array_initializer
3240           {
3241                 $$ = new ArrayCreation ((Expression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, (Location) $1);
3242           }
3243         | NEW type rank_specifiers array_initializer
3244           {
3245                 $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, (Location) $1);
3246           }
3247         | NEW error
3248           {
3249                 Report.Error (1031, (Location) $1, "Type expected");
3250                 $$ = null;
3251           }          
3252         | NEW type error 
3253           {
3254                 Report.Error (1526, (Location) $1, "A new expression requires () or [] after type");
3255                 $$ = null;
3256           }
3257         ;
3259 opt_rank_specifier
3260         : /* empty */
3261           {
3262                   $$ = "";
3263           }
3264         | rank_specifiers
3265           {
3266                         $$ = $1;
3267           }
3268         ;
3270 opt_rank_specifier_or_nullable
3271         : /* empty */
3272           {
3273                 $$ = "";
3274           }
3275         | INTERR
3276           {
3277                 $$ = "?";
3278           }
3279         | opt_nullable rank_specifiers
3280           {
3281                 if ((bool) $1)
3282                         $$ = "?" + $2;
3283                 else
3284                         $$ = $2;
3285           }
3286         | opt_nullable rank_specifiers INTERR
3287           {
3288                 if ((bool) $1)
3289                         $$ = "?" + $2 + "?";
3290                 else
3291                         $$ = $2 + "?";
3292           }
3293         ;
3295 rank_specifiers
3296         : rank_specifier opt_rank_specifier
3297           {
3298                   $$ = (string) $2 + (string) $1;
3299           }
3300         ;
3302 rank_specifier
3303         : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
3304           {
3305                 $$ = "[" + (string) $2 + "]";
3306           }
3307         ;
3309 opt_dim_separators
3310         : /* empty */
3311           {
3312                 $$ = "";
3313           }
3314         | dim_separators
3315           {
3316                   $$ = $1;
3317           }               
3318         ;
3320 dim_separators
3321         : COMMA
3322           {
3323                 $$ = ",";
3324           }
3325         | dim_separators COMMA
3326           {
3327                 $$ = (string) $1 + ",";
3328           }
3329         ;
3331 opt_array_initializer
3332         : /* empty */
3333           {
3334                 $$ = null;
3335           }
3336         | array_initializer
3337           {
3338                 $$ = $1;
3339           }
3340         ;
3342 array_initializer
3343         : OPEN_BRACE CLOSE_BRACE
3344           {
3345                 ArrayList list = new ArrayList (4);
3346                 $$ = list;
3347           }
3348         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
3349           {
3350                 $$ = (ArrayList) $2;
3351           }
3352         ;
3354 variable_initializer_list
3355         : variable_initializer
3356           {
3357                 ArrayList list = new ArrayList (4);
3358                 list.Add ($1);
3359                 $$ = list;
3360           }
3361         | variable_initializer_list COMMA variable_initializer
3362           {
3363                 ArrayList list = (ArrayList) $1;
3364                 list.Add ($3);
3365                 $$ = list;
3366           }
3367         ;
3369 typeof_expression
3370         : TYPEOF
3371       {
3372                 pushed_current_array_type = current_array_type;
3373                 lexer.TypeOfParsing = true;
3374           }
3375           OPEN_PARENS type CLOSE_PARENS
3376           {
3377                 lexer.TypeOfParsing = false;
3378                 Expression type = (Expression)$4;
3379                 if (type == TypeManager.system_void_expr)
3380                         $$ = new TypeOfVoid ((Location) $1);
3381                 else
3382                         $$ = new TypeOf (type, (Location) $1);
3383                 current_array_type = pushed_current_array_type;
3384           }
3385         ;
3387 sizeof_expression
3388         : SIZEOF OPEN_PARENS type CLOSE_PARENS { 
3389                 $$ = new SizeOf ((Expression) $3, (Location) $1);
3390           }
3391         ;
3393 checked_expression
3394         : CHECKED OPEN_PARENS expression CLOSE_PARENS
3395           {
3396                 $$ = new CheckedExpr ((Expression) $3, (Location) $1);
3397           }
3398         ;
3400 unchecked_expression
3401         : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
3402           {
3403                 $$ = new UnCheckedExpr ((Expression) $3, (Location) $1);
3404           }
3405         ;
3407 pointer_member_access 
3408         : primary_expression OP_PTR IDENTIFIER
3409           {
3410                 Expression deref;
3411                 LocatedToken lt = (LocatedToken) $3;
3413                 deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lt.Location);
3414                 $$ = new MemberAccess (deref, lt.Value);
3415           }
3416         ;
3418 anonymous_method_expression
3419         : DELEGATE opt_anonymous_method_signature
3420           {
3421                 if (oob_stack == null)
3422                         oob_stack = new Stack (6);
3424                 oob_stack.Push (current_anonymous_method);
3425                 oob_stack.Push (current_local_parameters);
3426                 current_local_parameters = (Parameters)$2;
3428                 // Force the next block to be created as a ToplevelBlock
3429                 oob_stack.Push (current_block);
3430                 oob_stack.Push (top_current_block);
3432                 Location loc = (Location) $1;
3433                 current_anonymous_method = new AnonymousMethodExpression (
3434                         current_anonymous_method, current_generic_method, current_container,
3435                         (Parameters) $2, (ToplevelBlock) top_current_block, loc);
3437                 parsing_anonymous_method = true;
3438           }
3439           block
3440           {
3441                 Location loc = (Location) $1;
3442                 top_current_block = (Block) oob_stack.Pop ();
3443                 current_block = (Block) oob_stack.Pop ();
3445                 if (RootContext.Version == LanguageVersion.ISO_1){
3446                         Report.FeatureIsNotStandardized (loc, "anonymous methods");
3447                         $$ = null;
3448                 } else  {
3449                         ToplevelBlock anon_block = (ToplevelBlock) $4;
3451                         anon_block.Parent = current_block;
3453                         current_anonymous_method.Block = anon_block;
3454                         if ((anonymous_host != null) && (current_anonymous_method.Parent == null))
3455                                 anonymous_host.AddAnonymousMethod (current_anonymous_method);
3457                         $$ = current_anonymous_method;
3458                 }
3460                 current_local_parameters = (Parameters) oob_stack.Pop ();
3461                 current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
3462         }
3463         ;
3465 opt_anonymous_method_signature
3466         : /* empty */                   { $$ = null; } 
3467         | anonymous_method_signature
3468         ;
3470 anonymous_method_signature
3471         : OPEN_PARENS opt_anonymous_method_parameter_list CLOSE_PARENS 
3472           {
3473                 if ($2 == null)
3474                         $$ = Parameters.EmptyReadOnlyParameters;
3475                 else {
3476                         ArrayList par_list = (ArrayList) $2;
3477                         Parameter [] pars = new Parameter [par_list.Count];
3478                         par_list.CopyTo (pars);
3479                         $$ = new Parameters (pars);
3480                 }
3481           }
3482         ;
3484 opt_anonymous_method_parameter_list
3485         : /* empty */   { $$ = null; } 
3486         | anonymous_method_parameter_list  { $$ = $1; }
3487         ;
3489 anonymous_method_parameter_list
3490         : anonymous_method_parameter 
3491           {
3492                 ArrayList a = new ArrayList (4);
3493                 a.Add ($1);
3494                 $$ = a;
3495           }
3496         | anonymous_method_parameter_list COMMA anonymous_method_parameter 
3497           {
3498                 ArrayList a = (ArrayList) $1;
3499                 a.Add ($3);
3500                 $$ = a;
3501           }
3502         ; 
3504 anonymous_method_parameter
3505         : opt_parameter_modifier type IDENTIFIER {
3506                 LocatedToken lt = (LocatedToken) $3;
3507                 $$ = new Parameter ((Expression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
3508           }
3509         | PARAMS type IDENTIFIER {
3510                 Report.Error (1670, ((LocatedToken) $3).Location, "The `params' modifier is not allowed in anonymous method declaration");
3511                 $$ = null;
3512           }
3513         ;
3515 default_value_expression
3516         : DEFAULT_OPEN_PARENS type CLOSE_PARENS
3517           {
3518                 $$ = new DefaultValueExpression ((Expression) $2, lexer.Location);
3519           }
3520         ;
3522 unary_expression
3523         : primary_expression
3524         | BANG prefixed_unary_expression
3525           {
3526                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, (Location) $1);
3527           }
3528         | TILDE prefixed_unary_expression
3529           {
3530                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, (Location) $1);
3531           }
3532         | cast_expression
3533         ;
3535 cast_list
3536         : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression
3537           {
3538                 $$ = new Cast ((Expression) $1, (Expression) $3);
3539           }
3540         | parenthesized_expression_0 CLOSE_PARENS_NO_CAST default_value_expression
3541           {
3542                 $$ = new Cast ((Expression) $1, (Expression) $3);
3543           }
3544         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression
3545           {
3546                 $$ = new Cast ((Expression) $1, (Expression) $3);
3547           }     
3548         ;
3550 cast_expression
3551         : cast_list
3552         | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
3553           {
3554                 // TODO: wrong location
3555                 $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
3556           }
3557         ;
3559         //
3560         // The idea to split this out is from Rhys' grammar
3561         // to solve the problem with casts.
3562         //
3563 prefixed_unary_expression
3564         : unary_expression
3565         | PLUS prefixed_unary_expression
3566           { 
3567                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, (Location) $1);
3568           } 
3569         | MINUS prefixed_unary_expression 
3570           { 
3571                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, (Location) $1);
3572           }
3573         | OP_INC prefixed_unary_expression 
3574           {
3575                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
3576                                        (Expression) $2, (Location) $1);
3577           }
3578         | OP_DEC prefixed_unary_expression 
3579           {
3580                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
3581                                        (Expression) $2, (Location) $1);
3582           }
3583         | STAR prefixed_unary_expression
3584           {
3585                 $$ = new Unary (Unary.Operator.Indirection, (Expression) $2, (Location) $1);
3586           }
3587         | BITWISE_AND prefixed_unary_expression
3588           {
3589                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, (Location) $1);
3590           }
3591         ;
3593 pre_increment_expression
3594         : OP_INC prefixed_unary_expression 
3595           {
3596                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
3597                                        (Expression) $2, (Location) $1);
3598           }
3599         ;
3601 pre_decrement_expression
3602         : OP_DEC prefixed_unary_expression 
3603           {
3604                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
3605                                        (Expression) $2, (Location) $1);
3606           }
3607         ;
3609 multiplicative_expression
3610         : prefixed_unary_expression
3611         | multiplicative_expression STAR prefixed_unary_expression
3612           {
3613                 $$ = new Binary (Binary.Operator.Multiply, 
3614                                  (Expression) $1, (Expression) $3);
3615           }
3616         | multiplicative_expression DIV prefixed_unary_expression
3617           {
3618                 $$ = new Binary (Binary.Operator.Division, 
3619                                  (Expression) $1, (Expression) $3);
3620           }
3621         | multiplicative_expression PERCENT prefixed_unary_expression 
3622           {
3623                 $$ = new Binary (Binary.Operator.Modulus, 
3624                                  (Expression) $1, (Expression) $3);
3625           }
3626         ;
3628 additive_expression
3629         : multiplicative_expression
3630         | additive_expression PLUS multiplicative_expression 
3631           {
3632                 $$ = new Binary (Binary.Operator.Addition, 
3633                                  (Expression) $1, (Expression) $3);
3634           }
3635         | additive_expression MINUS multiplicative_expression
3636           {
3637                 $$ = new Binary (Binary.Operator.Subtraction, 
3638                                  (Expression) $1, (Expression) $3);
3639           }
3640         ;
3642 shift_expression
3643         : additive_expression
3644         | shift_expression OP_SHIFT_LEFT additive_expression
3645           {
3646                 $$ = new Binary (Binary.Operator.LeftShift, 
3647                                  (Expression) $1, (Expression) $3);
3648           }
3649         | shift_expression OP_SHIFT_RIGHT additive_expression
3650           {
3651                 $$ = new Binary (Binary.Operator.RightShift, 
3652                                  (Expression) $1, (Expression) $3);
3653           }
3654         ; 
3656 opt_error
3657         : /* empty */
3658           {
3659                 $$ = false;
3660           }
3661         | error
3662           {
3663                 lexer.PutbackNullable ();
3664                 $$ = true;
3665           }
3666         ;
3668 nullable_type_or_conditional
3669         : type opt_error
3670           {
3671                 if (((bool) $2) && ($1 is ComposedCast))
3672                         $$ = ((ComposedCast) $1).RemoveNullable ();
3673                 else
3674                         $$ = $1;
3675           }
3676         ;
3678 relational_expression
3679         : shift_expression
3680         | relational_expression OP_LT shift_expression
3681           {
3682                 $$ = new Binary (Binary.Operator.LessThan, 
3683                                  (Expression) $1, (Expression) $3);
3684           }
3685         | relational_expression OP_GT shift_expression
3686           {
3687                 $$ = new Binary (Binary.Operator.GreaterThan, 
3688                                  (Expression) $1, (Expression) $3);
3689           }
3690         | relational_expression OP_LE shift_expression
3691           {
3692                 $$ = new Binary (Binary.Operator.LessThanOrEqual, 
3693                                  (Expression) $1, (Expression) $3);
3694           }
3695         | relational_expression OP_GE shift_expression
3696           {
3697                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
3698                                  (Expression) $1, (Expression) $3);
3699           }
3700         | relational_expression IS
3701           {
3702                 yyErrorFlag = 3;
3703           } nullable_type_or_conditional
3704           {
3705                 $$ = new Is ((Expression) $1, (Expression) $4, (Location) $2);
3706           }
3707         | relational_expression AS
3708           {
3709                 yyErrorFlag = 3;
3710           } nullable_type_or_conditional
3711           {
3712                 $$ = new As ((Expression) $1, (Expression) $4, (Location) $2);
3713           }
3714         ;
3716 equality_expression
3717         : relational_expression
3718         | equality_expression OP_EQ relational_expression
3719           {
3720                 $$ = new Binary (Binary.Operator.Equality, 
3721                                  (Expression) $1, (Expression) $3);
3722           }
3723         | equality_expression OP_NE relational_expression
3724           {
3725                 $$ = new Binary (Binary.Operator.Inequality, 
3726                                  (Expression) $1, (Expression) $3);
3727           }
3728         ; 
3730 and_expression
3731         : equality_expression
3732         | and_expression BITWISE_AND equality_expression
3733           {
3734                 $$ = new Binary (Binary.Operator.BitwiseAnd, 
3735                                  (Expression) $1, (Expression) $3);
3736           }
3737         ;
3739 exclusive_or_expression
3740         : and_expression
3741         | exclusive_or_expression CARRET and_expression
3742           {
3743                 $$ = new Binary (Binary.Operator.ExclusiveOr, 
3744                                  (Expression) $1, (Expression) $3);
3745           }
3746         ;
3748 inclusive_or_expression
3749         : exclusive_or_expression
3750         | inclusive_or_expression BITWISE_OR exclusive_or_expression
3751           {
3752                 $$ = new Binary (Binary.Operator.BitwiseOr, 
3753                                  (Expression) $1, (Expression) $3);
3754           }
3755         ;
3757 conditional_and_expression
3758         : inclusive_or_expression
3759         | conditional_and_expression OP_AND inclusive_or_expression
3760           {
3761                 $$ = new Binary (Binary.Operator.LogicalAnd, 
3762                                  (Expression) $1, (Expression) $3);
3763           }
3764         ;
3766 conditional_or_expression
3767         : conditional_and_expression
3768         | conditional_or_expression OP_OR conditional_and_expression
3769           {
3770                 $$ = new Binary (Binary.Operator.LogicalOr, 
3771                                  (Expression) $1, (Expression) $3);
3772           }
3773         ;
3775 conditional_expression
3776         : conditional_or_expression
3777         | conditional_or_expression INTERR expression COLON expression 
3778           {
3779                 $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5);
3780           }
3781         | conditional_or_expression INTERR INTERR expression
3782           {
3783                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $4, lexer.Location);
3784           }
3785         // We'll be resolved into a `parenthesized_expression_0' later on.
3786         | conditional_or_expression INTERR CLOSE_PARENS
3787           {
3788                 $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
3789                 lexer.PutbackCloseParens ();
3790           }
3791         ;
3793 assignment_expression
3794         : prefixed_unary_expression ASSIGN expression
3795           {
3796                 $$ = new Assign ((Expression) $1, (Expression) $3);
3797           }
3798         | prefixed_unary_expression OP_MULT_ASSIGN expression
3799           {
3800                 $$ = new CompoundAssign (
3801                         Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
3802           }
3803         | prefixed_unary_expression OP_DIV_ASSIGN expression
3804           {
3805                 $$ = new CompoundAssign (
3806                         Binary.Operator.Division, (Expression) $1, (Expression) $3);
3807           }
3808         | prefixed_unary_expression OP_MOD_ASSIGN expression
3809           {
3810                 $$ = new CompoundAssign (
3811                         Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
3812           }
3813         | prefixed_unary_expression OP_ADD_ASSIGN expression
3814           {
3815                 $$ = new CompoundAssign (
3816                         Binary.Operator.Addition, (Expression) $1, (Expression) $3);
3817           }
3818         | prefixed_unary_expression OP_SUB_ASSIGN expression
3819           {
3820                 $$ = new CompoundAssign (
3821                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
3822           }
3823         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
3824           {
3825                 $$ = new CompoundAssign (
3826                         Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
3827           }
3828         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
3829           {
3830                 $$ = new CompoundAssign (
3831                         Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
3832           }
3833         | prefixed_unary_expression OP_AND_ASSIGN expression
3834           {
3835                 $$ = new CompoundAssign (
3836                         Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
3837           }
3838         | prefixed_unary_expression OP_OR_ASSIGN expression
3839           {
3840                 $$ = new CompoundAssign (
3841                         Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
3842           }
3843         | prefixed_unary_expression OP_XOR_ASSIGN expression
3844           {
3845                 $$ = new CompoundAssign (
3846                         Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
3847           }
3848         ;
3850 expression
3851         : conditional_expression
3852         | assignment_expression
3853         ;
3855 constant_expression
3856         : expression
3857         ;
3859 boolean_expression
3860         : expression
3861         ;
3864 // 10 classes
3866 class_declaration
3867         : opt_attributes
3868           opt_modifiers
3869           opt_partial
3870           CLASS
3871           {
3872                 lexer.ConstraintsParsing = true;
3873           }
3874           member_name
3875           {
3876                 MemberName name = MakeName ((MemberName) $6);
3877                 int mod_flags = (int) $2;
3879                 push_current_class (new Class (
3880                         current_namespace, current_class, name,
3881                         mod_flags, (Attributes) $1), false, $3);
3882           }
3883           opt_class_base
3884           opt_type_parameter_constraints_clauses
3885           {
3886                 lexer.ConstraintsParsing = false;
3888                 if ($8 != null) {
3889                         if (current_class.Name == "System.Object") {
3890                                 Report.Error (537, current_class.Location,
3891                                               "The class System.Object cannot have a base " +
3892                                               "class or implement an interface.");
3893                         }
3894                         current_container.AddBasesForPart (current_class, (ArrayList) $8);
3895                 }
3897                 current_class.SetParameterInfo ((ArrayList) $9);
3899                 if (RootContext.Documentation != null) {
3900                         current_container.DocComment = Lexer.consume_doc_comment ();
3901                         Lexer.doc_state = XmlCommentState.Allowed;
3902                 }
3903           }
3904           class_body
3905           {
3906                 if (RootContext.Documentation != null)
3907                         Lexer.doc_state = XmlCommentState.Allowed;
3908           }
3909           opt_semicolon 
3910           {
3911                 $$ = pop_current_class ();
3912           }
3913         ;       
3915 opt_partial
3916         : /* empty */
3917           { $$ = null; }
3918         | PARTIAL
3919           { $$ = $1; } // location
3920         ;
3922 opt_modifiers
3923         : /* empty */           { $$ = (int) 0; }
3924         | modifiers
3925         ;
3927 modifiers
3928         : modifier
3929         | modifiers modifier
3930           { 
3931                 int m1 = (int) $1;
3932                 int m2 = (int) $2;
3934                 if ((m1 & m2) != 0) {
3935                         Location l = lexer.Location;
3936                         Report.Error (1004, l, "Duplicate `{0}' modifier", Modifiers.Name (m2));
3937                 }
3938                 $$ = (int) (m1 | m2);
3939           }
3940         ;
3942 modifier
3943         : NEW                   { $$ = Modifiers.NEW; }
3944         | PUBLIC                { $$ = Modifiers.PUBLIC; }
3945         | PROTECTED             { $$ = Modifiers.PROTECTED; }
3946         | INTERNAL              { $$ = Modifiers.INTERNAL; }
3947         | PRIVATE               { $$ = Modifiers.PRIVATE; }
3948         | ABSTRACT              { $$ = Modifiers.ABSTRACT; }
3949         | SEALED                { $$ = Modifiers.SEALED; }
3950         | STATIC                { $$ = Modifiers.STATIC; }
3951         | READONLY              { $$ = Modifiers.READONLY; }
3952         | VIRTUAL               { $$ = Modifiers.VIRTUAL; }
3953         | OVERRIDE              { $$ = Modifiers.OVERRIDE; }
3954         | EXTERN                { $$ = Modifiers.EXTERN; }
3955         | VOLATILE              { $$ = Modifiers.VOLATILE; }
3956         | UNSAFE                { $$ = Modifiers.UNSAFE; }
3957         ;
3959 opt_class_base
3960         : /* empty */           { $$ = null; }
3961         | class_base            { $$ = $1;   }
3962         ;
3964 class_base
3965         : COLON type_list { $$ = $2; }
3966         ;
3968 opt_type_parameter_constraints_clauses
3969         : /* empty */           { $$ = null; }
3970         | type_parameter_constraints_clauses 
3971           { $$ = $1; }
3972         ;
3974 type_parameter_constraints_clauses
3975         : type_parameter_constraints_clause {
3976                 ArrayList constraints = new ArrayList (1);
3977                 constraints.Add ($1);
3978                 $$ = constraints;
3979           }
3980         | type_parameter_constraints_clauses type_parameter_constraints_clause {
3981                 ArrayList constraints = (ArrayList) $1;
3982                 Constraints new_constraint = (Constraints)$2;
3984                 foreach (Constraints c in constraints) {
3985                         if (new_constraint.TypeParameter == c.TypeParameter) {
3986                                 Report.Error (409, new_constraint.Location, "A constraint clause has already been specified for type parameter `{0}'",
3987                                         new_constraint.TypeParameter);
3988                         }
3989                 }
3991                 constraints.Add (new_constraint);
3992                 $$ = constraints;
3993           }
3994         ; 
3996 type_parameter_constraints_clause
3997         : WHERE IDENTIFIER COLON type_parameter_constraints {
3998                 LocatedToken lt = (LocatedToken) $2;
3999                 $$ = new Constraints (lt.Value, (ArrayList) $4, lt.Location);
4000           }
4001         ; 
4003 type_parameter_constraints
4004         : type_parameter_constraint {
4005                 ArrayList constraints = new ArrayList (1);
4006                 constraints.Add ($1);
4007                 $$ = constraints;
4008           }
4009         | type_parameter_constraints COMMA type_parameter_constraint {
4010                 ArrayList constraints = (ArrayList) $1;
4012                 constraints.Add ($3);
4013                 $$ = constraints;
4014           }
4015         ;
4017 type_parameter_constraint
4018         : type
4019         | NEW OPEN_PARENS CLOSE_PARENS {
4020                 $$ = SpecialConstraint.Constructor;
4021           }
4022         | CLASS {
4023                 $$ = SpecialConstraint.ReferenceType;
4024           }
4025         | STRUCT {
4026                 $$ = SpecialConstraint.ValueType;
4027           }
4028         ;
4031 // Statements (8.2)
4035 // A block is "contained" on the following places:
4036 //      method_body
4037 //      property_declaration as part of the accessor body (get/set)
4038 //      operator_declaration
4039 //      constructor_declaration
4040 //      destructor_declaration
4041 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
4042 //      
4043 block
4044         : OPEN_BRACE 
4045           {
4046                 if (parsing_anonymous_method) {
4047                         top_current_block = new ToplevelBlock (
4048                                 current_block, current_local_parameters, current_generic_method,
4049                                 (Location) $1);
4050                         if (current_block != null)
4051                                 current_block.AddAnonymousChild ((ToplevelBlock) top_current_block);
4052                         current_block = top_current_block;
4053                         parsing_anonymous_method = false;
4054                 } else if (current_block == null) {
4055                         current_block = new ToplevelBlock (
4056                                 (ToplevelBlock) top_current_block, current_local_parameters,
4057                                 current_generic_method, (Location) $1);
4058                         top_current_block = current_block;
4059                 } else {
4060                         current_block = new Block (current_block, (Location) $1, Location.Null);
4061                 }
4062           } 
4063           opt_statement_list CLOSE_BRACE 
4064           { 
4065                 while (current_block.Implicit)
4066                         current_block = current_block.Parent;
4067                 $$ = current_block;
4068                 current_block.SetEndLocation ((Location) $4);
4069                 current_block = current_block.Parent;
4070                 if (current_block == null)
4071                         top_current_block = null;
4072           }
4073         ;
4075 opt_statement_list
4076         : /* empty */
4077         | statement_list 
4078         ;
4080 statement_list
4081         : statement
4082         | statement_list statement
4083         ;
4085 statement
4086         : declaration_statement
4087           {
4088                 if ($1 != null && (Block) $1 != current_block){
4089                         current_block.AddStatement ((Statement) $1);
4090                         current_block = (Block) $1;
4091                 }
4092           }
4093         | valid_declaration_statement
4094           {
4095                 current_block.AddStatement ((Statement) $1);
4096           }
4097         | labeled_statement
4098         ;
4100 valid_declaration_statement
4101         : block
4102         | empty_statement
4103         | expression_statement
4104         | selection_statement
4105         | iteration_statement
4106         | jump_statement                  
4107         | try_statement
4108         | checked_statement
4109         | unchecked_statement
4110         | lock_statement
4111         | using_statement
4112         | unsafe_statement
4113         | fixed_statement
4114         ;
4116 embedded_statement
4117         : valid_declaration_statement
4118         | declaration_statement
4119           {
4120                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4121                   $$ = null;
4122           }
4123         | labeled_statement
4124           {
4125                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4126                   $$ = null;
4127           }
4128         ;
4130 empty_statement
4131         : SEMICOLON
4132           {
4133                   $$ = EmptyStatement.Value;
4134           }
4135         ;
4137 labeled_statement
4138         : IDENTIFIER COLON 
4139           {
4140                 LocatedToken lt = (LocatedToken) $1;
4141                 LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location);
4143                 if (current_block.AddLabel (labeled))
4144                         current_block.AddStatement (labeled);
4145           }
4146           statement
4147         ;
4149 declaration_statement
4150         : local_variable_declaration SEMICOLON
4151           {
4152                 current_array_type = null;
4153                 if ($1 != null){
4154                         DictionaryEntry de = (DictionaryEntry) $1;
4155                         Expression e = (Expression) de.Key;
4157                         $$ = declare_local_variables (e, (ArrayList) de.Value, e.Location);
4158                 }
4159           }
4161         | local_constant_declaration SEMICOLON
4162           {
4163                 current_array_type = null;
4164                 if ($1 != null){
4165                         DictionaryEntry de = (DictionaryEntry) $1;
4167                         $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value);
4168                 }
4169           }
4170         ;
4172 /* 
4173  * The following is from Rhys' grammar:
4174  * > Types in local variable declarations must be recognized as 
4175  * > expressions to prevent reduce/reduce errors in the grammar.
4176  * > The expressions are converted into types during semantic analysis.
4177  */
4178 local_variable_type
4179         : primary_expression opt_rank_specifier_or_nullable
4180           { 
4181                 // FIXME: Do something smart here regarding the composition of the type.
4183                 // Ok, the above "primary_expression" is there to get rid of
4184                 // both reduce/reduce and shift/reduces in the grammar, it should
4185                 // really just be "type_name".  If you use type_name, a reduce/reduce
4186                 // creeps up.  If you use namespace_or_type_name (which is all we need
4187                 // really) two shift/reduces appear.
4188                 // 
4190                 // So the super-trick is that primary_expression
4191                 // can only be either a SimpleName or a MemberAccess. 
4192                 // The MemberAccess case arises when you have a fully qualified type-name like :
4193                 // Foo.Bar.Blah i;
4194                 // SimpleName is when you have
4195                 // Blah i;
4196                   
4197                 Expression expr = (Expression) $1;  
4198                 if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType || expr is QualifiedAliasMember)) {
4199                         Error_ExpectingTypeName (expr);
4200                         $$ = null;
4201                 } else {
4202                         //
4203                         // So we extract the string corresponding to the SimpleName
4204                         // or MemberAccess
4205                         // 
4207                         if ((string) $2 == "")
4208                                 $$ = $1;
4209                         else
4210                                 $$ = new ComposedCast ((Expression) $1, (string) $2);
4211                 }
4212           }
4213         | builtin_types opt_rank_specifier_or_nullable
4214           {
4215                 if ((string) $2 == "")
4216                         $$ = $1;
4217                 else
4218                         $$ = current_array_type = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
4219           }
4220         ;
4222 local_variable_pointer_type
4223         : primary_expression STAR
4224           {
4225                 Expression expr = (Expression) $1;  
4227                 if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType || expr is QualifiedAliasMember)) {
4228                         Error_ExpectingTypeName (expr);
4230                         $$ = null;
4231                 } else 
4232                         $$ = new ComposedCast ((Expression) $1, "*");
4233           }
4234         | builtin_types STAR
4235           {
4236                 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
4237           }
4238         | VOID STAR
4239           {
4240                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1);
4241           }
4242         | local_variable_pointer_type STAR
4243           {
4244                 $$ = new ComposedCast ((Expression) $1, "*");
4245           }
4246         ;
4248 local_variable_declaration
4249         : local_variable_type variable_declarators
4250           {
4251                 if ($1 != null)
4252                         $$ = new DictionaryEntry ($1, $2);
4253                 else
4254                         $$ = null;
4255           }
4256         | local_variable_pointer_type opt_rank_specifier_or_nullable variable_declarators
4257           {
4258                 if ($1 != null){
4259                         Expression t;
4261                         if ((string) $2 == "")
4262                                 t = (Expression) $1;
4263                         else
4264                                 t = new ComposedCast ((Expression) $1, (string) $2);
4265                         $$ = new DictionaryEntry (t, $3);
4266                 } else 
4267                         $$ = null;
4268           }
4269         ;
4271 local_constant_declaration
4272         : CONST local_variable_type constant_declarators
4273           {
4274                 if ($2 != null)
4275                         $$ = new DictionaryEntry ($2, $3);
4276                 else
4277                         $$ = null;
4278           }
4279         ;
4281 expression_statement
4282         : statement_expression SEMICOLON { $$ = $1; }
4283         ;
4285         //
4286         // We have to do the wrapping here and not in the case above,
4287         // because statement_expression is used for example in for_statement
4288         //
4289 statement_expression
4290         : expression
4291           {
4292                 Expression expr = (Expression) $1;
4293                 ExpressionStatement s = expr as ExpressionStatement;
4294                 if (s == null) {
4295                         Report.Error (201, expr.Location, "Only assignment, call, increment, decrement, and new object expressions can be used as a statement");
4296                         $$ = null;
4297                 }
4298                 $$ = new StatementExpression (s);
4299           }
4300         | error
4301           {
4302                 Report.Error (1002, GetLocation ($1), "Expecting `;'");
4303                 $$ = null;
4304           }
4305         ;
4307 object_creation_expression
4308         : object_or_delegate_creation_expression
4309           { note ("complain if this is a delegate maybe?"); } 
4310         ;
4312 selection_statement
4313         : if_statement
4314         | switch_statement
4315         ; 
4317 if_statement
4318         : IF OPEN_PARENS boolean_expression CLOSE_PARENS 
4319           embedded_statement
4320           { 
4321                 Location l = (Location) $1;
4323                 $$ = new If ((Expression) $3, (Statement) $5, l);
4325                 // FIXME: location for warning should be loc property of $5.
4326                 if ($5 == EmptyStatement.Value)
4327                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4329           }
4330         | IF OPEN_PARENS boolean_expression CLOSE_PARENS
4331           embedded_statement ELSE embedded_statement
4332           {
4333                 Location l = (Location) $1;
4335                 $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7, l);
4337                 // FIXME: location for warning should be loc property of $5 and $7.
4338                 if ($5 == EmptyStatement.Value)
4339                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4340                 if ($7 == EmptyStatement.Value)
4341                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4342           }
4343         ;
4345 switch_statement
4346         : SWITCH OPEN_PARENS
4347           { 
4348                 if (switch_stack == null)
4349                         switch_stack = new Stack (2);
4350                 switch_stack.Push (current_block);
4351           }
4352           expression CLOSE_PARENS 
4353           switch_block
4354           {
4355                 $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) $1);
4356                 current_block = (Block) switch_stack.Pop ();
4357           }
4358         ;
4360 switch_block
4361         : OPEN_BRACE
4362           opt_switch_sections
4363           CLOSE_BRACE
4364           {
4365                 $$ = $2;
4366           }
4367         ;
4369 opt_switch_sections
4370         : /* empty */           
4371           {
4372                 Report.Warning (1522, 1, lexer.Location, "Empty switch block"); 
4373                 $$ = new ArrayList ();
4374           }
4375         | switch_sections
4376         ;
4378 switch_sections
4379         : switch_section 
4380           {
4381                 ArrayList sections = new ArrayList (4);
4383                 sections.Add ($1);
4384                 $$ = sections;
4385           }
4386         | switch_sections switch_section
4387           {
4388                 ArrayList sections = (ArrayList) $1;
4390                 sections.Add ($2);
4391                 $$ = sections;
4392           }
4393         ;
4395 switch_section
4396         : switch_labels
4397           {
4398                 current_block = current_block.CreateSwitchBlock (lexer.Location);
4399           }
4400           statement_list 
4401           {
4402                 Block topmost = current_block;
4404                 while (topmost.Implicit)
4405                         topmost = topmost.Parent;
4406                 $$ = new SwitchSection ((ArrayList) $1, topmost);
4407           }
4408         ;
4410 switch_labels
4411         : switch_label 
4412           {
4413                 ArrayList labels = new ArrayList (4);
4415                 labels.Add ($1);
4416                 $$ = labels;
4417           }
4418         | switch_labels switch_label 
4419           {
4420                 ArrayList labels = (ArrayList) ($1);
4421                 labels.Add ($2);
4423                 $$ = labels;
4424           }
4425         ;
4427 switch_label
4428         : CASE constant_expression COLON        { $$ = new SwitchLabel ((Expression) $2, (Location) $1); }
4429         | DEFAULT_COLON                         { $$ = new SwitchLabel (null, (Location) $1); }
4430         | error {
4431                 Report.Error (
4432                         1523, GetLocation ($1), 
4433                         "The keyword case or default must precede code in switch block");
4434           }
4435         ;
4437 iteration_statement
4438         : while_statement
4439         | do_statement
4440         | for_statement
4441         | foreach_statement
4442         ;
4444 while_statement
4445         : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement
4446           {
4447                 Location l = (Location) $1;
4448                 $$ = new While ((Expression) $3, (Statement) $5, l);
4449           }
4450         ;
4452 do_statement
4453         : DO embedded_statement 
4454           WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
4455           {
4456                 Location l = (Location) $1;
4458                 $$ = new Do ((Statement) $2, (Expression) $5, l);
4459           }
4460         ;
4462 for_statement
4463         : FOR OPEN_PARENS 
4464           opt_for_initializer SEMICOLON
4465           {
4466                 Block assign_block = new Block (current_block);
4467                 current_block = assign_block;
4469                 if ($3 is DictionaryEntry){
4470                         DictionaryEntry de = (DictionaryEntry) $3;
4471                         
4472                         Expression type = (Expression) de.Key;
4473                         ArrayList var_declarators = (ArrayList) de.Value;
4475                         foreach (VariableDeclaration decl in var_declarators){
4477                                 LocalInfo vi;
4479                                 vi = current_block.AddVariable (type, decl.identifier, decl.Location);
4480                                 if (vi == null)
4481                                         continue;
4483                                 Location l = lexer.Location;
4484                                 Expression expr = decl.expression_or_array_initializer;
4485                                         
4486                                 LocalVariableReference var;
4487                                 var = new LocalVariableReference (assign_block, decl.identifier, l);
4489                                 if (expr != null) {
4490                                         Assign a = new Assign (var, expr, decl.Location);
4491                                         
4492                                         assign_block.AddStatement (new StatementExpression (a));
4493                                 }
4494                         }
4495                         
4496                         // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal.
4497                         // This can be referred to as $5 below.
4498                         $$ = null;
4499                 } else {
4500                         $$ = $3;
4501                 }
4502           } 
4503           opt_for_condition SEMICOLON
4504           opt_for_iterator CLOSE_PARENS 
4505           embedded_statement
4506           {
4507                 Location l = (Location) $1;
4509                 For f = new For ((Statement) $5, (Expression) $6, (Statement) $8, (Statement) $10, l);
4511                 current_block.AddStatement (f);
4512                 while (current_block.Implicit)
4513                         current_block = current_block.Parent;
4514                 $$ = current_block;
4515                 current_block = current_block.Parent;
4516           }
4517         ;
4519 opt_for_initializer
4520         : /* empty */           { $$ = EmptyStatement.Value; }
4521         | for_initializer       
4522         ;
4524 for_initializer
4525         : local_variable_declaration
4526         | statement_expression_list
4527         ;
4529 opt_for_condition
4530         : /* empty */           { $$ = null; }
4531         | boolean_expression
4532         ;
4534 opt_for_iterator
4535         : /* empty */           { $$ = EmptyStatement.Value; }
4536         | for_iterator
4537         ;
4539 for_iterator
4540         : statement_expression_list
4541         ;
4543 statement_expression_list
4544         : statement_expression  
4545           {
4546                 // CHANGE: was `null'
4547                 Statement s = (Statement) $1;
4548                 Block b = new Block (current_block, Block.Flags.Implicit, s.loc, lexer.Location);   
4550                 b.AddStatement (s);
4551                 $$ = b;
4552           }
4553         | statement_expression_list COMMA statement_expression
4554           {
4555                 Block b = (Block) $1;
4557                 b.AddStatement ((Statement) $3);
4558                 $$ = $1;
4559           }
4560         ;
4562 foreach_statement
4563         : FOREACH OPEN_PARENS type IN expression CLOSE_PARENS
4564           {
4565                 Report.Error (230, (Location) $1, "Type and identifier are both required in a foreach statement");
4566                 $$ = null;
4567           }
4568         | FOREACH OPEN_PARENS type IDENTIFIER IN
4569           expression CLOSE_PARENS 
4570           {
4571                 Block foreach_block = new Block (current_block);
4572                 current_block = foreach_block;
4574                 LocatedToken lt = (LocatedToken) $4;
4575                 Location l = lt.Location;
4576                 LocalInfo vi;
4578                 vi = foreach_block.AddVariable ((Expression) $3, lt.Value, l);
4579                 if (vi != null) {
4580                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach);
4582                         // Get a writable reference to this read-only variable.
4583                         //
4584                         // Note that the $$ here refers to the value of _this_ code block,
4585                         // not the value of the LHS non-terminal.  This can be referred to as $8 below.
4586                         $$ = new LocalVariableReference (foreach_block, lt.Value, l, vi, false);
4587                 } else {
4588                         $$ = null;
4589                 }
4590           } 
4591           embedded_statement 
4592           {
4593                 LocalVariableReference v = (LocalVariableReference) $8;
4594                 Location l = (Location) $1;
4596                 if (v != null) {
4597                         Foreach f = new Foreach ((Expression) $3, v, (Expression) $6, (Statement) $9, l);
4598                         current_block.AddStatement (f);
4599                 }
4601                 while (current_block.Implicit)
4602                           current_block = current_block.Parent;
4603                 $$ = current_block;
4604                 current_block = current_block.Parent;
4605           }
4606         ;
4608 jump_statement
4609         : break_statement
4610         | continue_statement
4611         | goto_statement
4612         | return_statement
4613         | throw_statement
4614         | yield_statement
4615         ;
4617 break_statement
4618         : BREAK SEMICOLON
4619           {
4620                 $$ = new Break ((Location) $1);
4621           }
4622         ;
4624 continue_statement
4625         : CONTINUE SEMICOLON
4626           {
4627                 $$ = new Continue ((Location) $1);
4628           }
4629         ;
4631 goto_statement
4632         : GOTO IDENTIFIER SEMICOLON 
4633           {
4634                 LocatedToken lt = (LocatedToken) $2;
4635                 $$ = new Goto (lt.Value, lt.Location);
4636           }
4637         | GOTO CASE constant_expression SEMICOLON
4638           {
4639                 $$ = new GotoCase ((Expression) $3, (Location) $1);
4640           }
4641         | GOTO DEFAULT SEMICOLON 
4642           {
4643                 $$ = new GotoDefault ((Location) $1);
4644           }
4645         ; 
4647 return_statement
4648         : RETURN opt_expression SEMICOLON
4649           {
4650                 $$ = new Return ((Expression) $2, (Location) $1);
4651           }
4652         ;
4654 throw_statement
4655         : THROW opt_expression SEMICOLON
4656           {
4657                 $$ = new Throw ((Expression) $2, (Location) $1);
4658           }
4659         ;
4661 yield_statement 
4662         : IDENTIFIER RETURN expression SEMICOLON
4663           {
4664                 LocatedToken lt = (LocatedToken) $1;
4665                 string s = lt.Value;
4666                 if (s != "yield"){
4667                         Report.Error (1003, lt.Location, "; expected");
4668                         $$ = null;
4669                 }
4670                 if (RootContext.Version == LanguageVersion.ISO_1){
4671                         Report.FeatureIsNotStandardized (lt.Location, "yield statement");
4672                         $$ = null;
4673                 }
4674                 if (anonymous_host == null){
4675                         Report.Error (204, lt.Location, "yield statement can only be used within a method, operator or property");
4676                         $$ = null;
4677                 } else {
4678                         anonymous_host.SetYields ();
4679                         $$ = new Yield ((Expression) $3, lt.Location); 
4680                 }
4681           }
4682         | IDENTIFIER RETURN SEMICOLON
4683           {
4684                 Report.Error (1627, (Location) $2, "Expression expected after yield return");
4685                 $$ = null;
4686           }
4687         | IDENTIFIER BREAK SEMICOLON
4688           {
4689                 LocatedToken lt = (LocatedToken) $1;
4690                 string s = lt.Value;
4691                 if (s != "yield"){
4692                         Report.Error (1003, lt.Location, "; expected");
4693                         $$ = null;
4694                 }
4695                 if (RootContext.Version == LanguageVersion.ISO_1){
4696                         Report.FeatureIsNotStandardized (lt.Location, "yield statement");
4697                         $$ = null;
4698                 }
4699                 if (anonymous_host == null){
4700                         Report.Error (204, lt.Location, "yield statement can only be used within a method, operator or property");
4701                         $$ = null;
4702                 } else {
4703                         anonymous_host.SetYields ();
4704                         $$ = new YieldBreak (lt.Location);
4705                 }
4706           }
4707         ;
4709 opt_expression
4710         : /* empty */
4711         | expression
4712         ;
4714 try_statement
4715         : TRY block catch_clauses 
4716           {
4717                 Catch g = null;
4718                 
4719                 ArrayList c = (ArrayList)$3;
4720                 for (int i = 0; i < c.Count; ++i) {
4721                         Catch cc = (Catch) c [i];
4722                         if (cc.IsGeneral) {
4723                                 if (i != c.Count - 1)
4724                                         Report.Error (1017, cc.loc, "Try statement already has an empty catch block");
4725                                 g = cc;
4726                                 c.RemoveAt (i);
4727                                 i--;
4728                         }
4729                 }
4731                 // Now s contains the list of specific catch clauses
4732                 // and g contains the general one.
4733                 
4734                 $$ = new Try ((Block) $2, c, g, null, ((Block) $2).loc);
4735           }
4736         | TRY block opt_catch_clauses FINALLY block
4737           {
4738                 Catch g = null;
4739                 ArrayList s = new ArrayList (4);
4740                 ArrayList catch_list = (ArrayList) $3;
4742                 if (catch_list != null){
4743                         foreach (Catch cc in catch_list) {
4744                                 if (cc.IsGeneral)
4745                                         g = cc;
4746                                 else
4747                                         s.Add (cc);
4748                         }
4749                 }
4751                 $$ = new Try ((Block) $2, s, g, (Block) $5, ((Block) $2).loc);
4752           }
4753         | TRY block error 
4754           {
4755                 Report.Error (1524, (Location) $1, "Expected catch or finally");
4756                 $$ = null;
4757           }
4758         ;
4760 opt_catch_clauses
4761         : /* empty */  { $$ = null; }
4762         | catch_clauses
4763         ;
4765 catch_clauses
4766         : catch_clause 
4767           {
4768                 ArrayList l = new ArrayList (4);
4770                 l.Add ($1);
4771                 $$ = l;
4772           }
4773         | catch_clauses catch_clause
4774           {
4775                 ArrayList l = (ArrayList) $1;
4777                 l.Add ($2);
4778                 $$ = l;
4779           }
4780         ;
4782 opt_identifier
4783         : /* empty */   { $$ = null; }
4784         | IDENTIFIER
4785         ;
4787 catch_clause 
4788         : CATCH opt_catch_args 
4789           {
4790                 Expression type = null;
4791                 
4792                 if ($2 != null) {
4793                         DictionaryEntry cc = (DictionaryEntry) $2;
4794                         type = (Expression) cc.Key;
4795                         LocatedToken lt = (LocatedToken) cc.Value;
4797                         if (lt != null){
4798                                 ArrayList one = new ArrayList (4);
4800                                 one.Add (new VariableDeclaration (lt, null));
4802                                 current_block = new Block (current_block);
4803                                 Block b = declare_local_variables (type, one, lt.Location);
4804                                 current_block = b;
4805                         }
4806                 }
4807           } block {
4808                 Expression type = null;
4809                 string id = null;
4810                 Block var_block = null;
4812                 if ($2 != null){
4813                         DictionaryEntry cc = (DictionaryEntry) $2;
4814                         type = (Expression) cc.Key;
4815                         LocatedToken lt = (LocatedToken) cc.Value;
4817                         if (lt != null){
4818                                 id = lt.Value;
4819                                 while (current_block.Implicit)
4820                                         current_block = current_block.Parent;
4821                                 var_block = current_block;
4822                                 current_block = current_block.Parent;
4823                         }
4824                 }
4826                 $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc);
4827           }
4828         ;
4830 opt_catch_args
4831         : /* empty */ { $$ = null; }
4832         | catch_args
4833         ;         
4835 catch_args 
4836         : OPEN_PARENS type opt_identifier CLOSE_PARENS 
4837           {
4838                 $$ = new DictionaryEntry ($2, $3);
4839           }
4840         ;
4843 checked_statement
4844         : CHECKED block
4845           {
4846                 $$ = new Checked ((Block) $2);
4847           }
4848         ;
4850 unchecked_statement
4851         : UNCHECKED block
4852           {
4853                 $$ = new Unchecked ((Block) $2);
4854           }
4855         ;
4857 unsafe_statement
4858         : UNSAFE 
4859           {
4860                 RootContext.CheckUnsafeOption ((Location) $1);
4861           } block {
4862                 $$ = new Unsafe ((Block) $3);
4863           }
4864         ;
4866 fixed_statement
4867         : FIXED OPEN_PARENS 
4868           type fixed_pointer_declarators 
4869           CLOSE_PARENS
4870           {
4871                 ArrayList list = (ArrayList) $4;
4872                 Expression type = (Expression) $3;
4873                 Location l = (Location) $1;
4874                 int top = list.Count;
4876                 Block assign_block = new Block (current_block);
4877                 current_block = assign_block;
4879                 for (int i = 0; i < top; i++){
4880                         Pair p = (Pair) list [i];
4881                         LocalInfo v;
4883                         v = current_block.AddVariable (type, (string) p.First, l);
4884                         if (v == null)
4885                                 continue;
4887                         v.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
4888                         v.Pinned = true;
4889                         p.First = v;
4890                         list [i] = p;
4891                 }
4892           }
4893           embedded_statement 
4894           {
4895                 Location l = (Location) $1;
4897                 Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
4899                 current_block.AddStatement (f);
4900                 while (current_block.Implicit)
4901                         current_block = current_block.Parent;
4902                 $$ = current_block;
4903                 current_block = current_block.Parent;
4904           }
4905         ;
4907 fixed_pointer_declarators
4908         : fixed_pointer_declarator      { 
4909                 ArrayList declarators = new ArrayList (4);
4910                 if ($1 != null)
4911                         declarators.Add ($1);
4912                 $$ = declarators;
4913           }
4914         | fixed_pointer_declarators COMMA fixed_pointer_declarator
4915           {
4916                 ArrayList declarators = (ArrayList) $1;
4917                 if ($3 != null)
4918                         declarators.Add ($3);
4919                 $$ = declarators;
4920           }
4921         ;
4923 fixed_pointer_declarator
4924         : IDENTIFIER ASSIGN expression
4925           {
4926                 LocatedToken lt = (LocatedToken) $1;
4927                 // FIXME: keep location
4928                 $$ = new Pair (lt.Value, $3);
4929           }
4930         | IDENTIFIER
4931           {
4932                 Report.Error (210, ((LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration");
4933                 $$ = null;
4934           }
4935         ;
4937 lock_statement
4938         : LOCK OPEN_PARENS expression CLOSE_PARENS 
4939           {
4940                 //
4941           } 
4942           embedded_statement
4943           {
4944                 $$ = new Lock ((Expression) $3, (Statement) $6, (Location) $1);
4945           }
4946         ;
4948 using_statement
4949         : USING OPEN_PARENS resource_acquisition CLOSE_PARENS
4950           {
4951                 Block assign_block = new Block (current_block);
4952                 current_block = assign_block;
4954                 if ($3 is DictionaryEntry){
4955                         DictionaryEntry de = (DictionaryEntry) $3;
4956                         Location l = (Location) $1;
4958                         Expression type = (Expression) de.Key;
4959                         ArrayList var_declarators = (ArrayList) de.Value;
4961                         ArrayList vars = new ArrayList (4);
4963                         foreach (VariableDeclaration decl in var_declarators){
4965                                 LocalInfo vi = current_block.AddVariable (type, decl.identifier, decl.Location);
4966                                 if (vi == null)
4967                                         continue;
4968                                 vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
4970                                 Expression expr = decl.expression_or_array_initializer;
4971                                 if (expr == null) {
4972                                         Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
4973                                 }
4975                                 LocalVariableReference var;
4977                                 // Get a writable reference to this read-only variable.
4978                                 var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
4980                                 // This is so that it is not a warning on using variables
4981                                 vi.Used = true;
4983                                 vars.Add (new DictionaryEntry (var, expr));                             
4985                                 // Assign a = new Assign (var, expr, decl.Location);
4986                                 // assign_block.AddStatement (new StatementExpression (a));
4987                         }
4989                         // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
4990                         // It can be referred to as $5 below.
4991                         $$ = new DictionaryEntry (type, vars);
4992                  } else {
4993                         $$ = $3;
4994                  }
4995           } 
4996           embedded_statement
4997           {
4998                 Using u = new Using ($5, (Statement) $6, (Location) $1);
4999                 current_block.AddStatement (u);
5000                 while (current_block.Implicit)
5001                         current_block = current_block.Parent;
5002                 $$ = current_block;
5003                 current_block = current_block.Parent;
5004           }
5005         ; 
5007 resource_acquisition
5008         : local_variable_declaration
5009         | expression
5010         ;
5014 // <summary>
5015 //   A class used to pass around variable declarations and constants
5016 // </summary>
5017 public class VariableDeclaration {
5018         public string identifier;
5019         public Expression expression_or_array_initializer;
5020         public Location Location;
5021         public Attributes OptAttributes;
5022         public string DocComment;
5024         public VariableDeclaration (LocatedToken lt, object eoai, Attributes opt_attrs)
5025         {
5026                 this.identifier = lt.Value;
5027                 if (eoai is ArrayList) {
5028                         if (CSharpParser.current_array_type == null)
5029                                 Report.Error (622, lt.Location,
5030                                         "Can only use array initializer expressions to assign to array types. Try using a new expression instead.");
5031                         this.expression_or_array_initializer = new ArrayCreation (CSharpParser.current_array_type, "", (ArrayList)eoai, lt.Location);
5032                 } else {
5033                         this.expression_or_array_initializer = (Expression)eoai;
5034                 }
5035                 this.Location = lt.Location;
5036                 this.OptAttributes = opt_attrs;
5037         }
5039         public VariableDeclaration (LocatedToken lt, object eoai) : this (lt, eoai, null)
5040         {
5041         }
5044 // <summary>
5045 //   A class used to hold info about an indexer declarator
5046 // </summary>
5047 public class IndexerDeclaration {
5048         public Expression type;
5049         public MemberName interface_type;
5050         public Parameters param_list;
5051         public Location location;
5053         public IndexerDeclaration (Expression type, MemberName interface_type,
5054                                    Parameters param_list, Location loc)
5055         {
5056                 this.type = type;
5057                 this.interface_type = interface_type;
5058                 this.param_list = param_list;
5059                 this.location = loc;
5060         }
5064 // We use this when we do not have an object in advance that is an IAnonymousHost
5066 public class SimpleAnonymousHost : IAnonymousHost {
5067         public static readonly SimpleAnonymousHost Simple = new SimpleAnonymousHost ();
5069         bool yields;
5070         ArrayList anonymous_methods;
5072         public static SimpleAnonymousHost GetSimple () {
5073                 Simple.yields = false;
5074                 Simple.anonymous_methods = null;
5075                 return Simple;
5076         }
5078         public void SetYields ()
5079         {
5080                 yields = true;
5081         }
5083         public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
5084         {
5085                 if (anonymous_methods == null)
5086                         anonymous_methods = new ArrayList ();
5087                 anonymous_methods.Add (anonymous);
5088         }
5090         public void Propagate (IAnonymousHost real_host)
5091         {
5092                 if (yields)
5093                         real_host.SetYields ();
5094                 if (anonymous_methods != null) {
5095                         foreach (AnonymousMethodExpression ame in anonymous_methods)
5096                                 real_host.AddAnonymousMethod (ame);
5097                 }
5098         }
5101 // <summary>
5102 //  A class used to hold info about an operator declarator
5103 // </summary>
5104 public class OperatorDeclaration {
5105         public Operator.OpType optype;
5106         public Expression ret_type, arg1type, arg2type;
5107         public string arg1name, arg2name;
5108         public Location location;
5110         public OperatorDeclaration (Operator.OpType op, Expression ret_type, 
5111                                     Expression arg1type, string arg1name,
5112                                     Expression arg2type, string arg2name, Location location)
5113         {
5114                 optype = op;
5115                 this.ret_type = ret_type;
5116                 this.arg1type = arg1type;
5117                 this.arg1name = arg1name;
5118                 this.arg2type = arg2type;
5119                 this.arg2name = arg2name;
5120                 this.location = location;
5121         }
5125 void Error_ExpectingTypeName (Expression expr)
5127         if (expr is Invocation){
5128                 Report.Error (1002, expr.Location, "Expecting `;'");
5129         } else {
5130                 Report.Error (201, expr.Location, "Only assignment, call, increment, decrement, and new object expressions can be used as a statement");
5131         }
5134 public static void Error_ParameterModifierNotValid (Location loc)
5136         Report.Error (631, loc, "The modifiers `ref' and `out' are not valid in this context");
5139 void push_current_class (TypeContainer tc, bool is_interface, object partial_token)
5141         if (partial_token != null)
5142                 current_container = current_container.AddPartial (tc, is_interface);
5143         else
5144                 current_container = current_container.AddTypeContainer (tc, is_interface);
5145         current_class = tc;
5148 DeclSpace pop_current_class ()
5150         DeclSpace retval = current_class;
5152         current_class = current_class.Parent;
5153         current_container = current_class.PartialContainer;
5155         return retval;
5158 // <summary>
5159 //   Given the @class_name name, it creates a fully qualified name
5160 //   based on the containing declaration space
5161 // </summary>
5162 MemberName
5163 MakeName (MemberName class_name)
5165         Namespace ns = current_namespace.NS;
5167         if (current_container.Name.Length == 0){
5168                 if (ns.Name.Length != 0)
5169                         return new MemberName (ns.MemberName, class_name);
5170                 else
5171                         return class_name;
5172         } else {
5173                 return new MemberName (current_container.MemberName, class_name);
5174         }
5177 Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
5179         Block implicit_block;
5180         ArrayList inits = null;
5182         //
5183         // We use the `Used' property to check whether statements
5184         // have been added to the current block.  If so, we need
5185         // to create another block to contain the new declaration
5186         // otherwise, as an optimization, we use the same block to
5187         // add the declaration.
5188         //
5189         // FIXME: A further optimization is to check if the statements
5190         // that were added were added as part of the initialization
5191         // below.  In which case, no other statements have been executed
5192         // and we might be able to reduce the number of blocks for
5193         // situations like this:
5194         //
5195         // int j = 1;  int k = j + 1;
5196         //
5197         if (current_block.Used)
5198                 implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
5199         else
5200                 implicit_block = current_block;
5202         foreach (VariableDeclaration decl in variable_declarators){
5204                 if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) {
5205                         if (decl.expression_or_array_initializer != null){
5206                                 if (inits == null)
5207                                         inits = new ArrayList (4);
5208                                 inits.Add (decl);
5209                         }
5210                 }
5211         }
5213         if (inits == null)
5214                 return implicit_block;
5216         foreach (VariableDeclaration decl in inits){
5217                 Assign assign;
5218                 Expression expr = decl.expression_or_array_initializer;
5219                 
5220                 LocalVariableReference var;
5221                 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
5223                 assign = new Assign (var, expr, decl.Location);
5225                 implicit_block.AddStatement (new StatementExpression (assign));
5226         }
5227         
5228         return implicit_block;
5231 Block declare_local_constants (Expression type, ArrayList declarators)
5233         Block implicit_block;
5235         if (current_block.Used)
5236                 implicit_block = new Block (current_block, Block.Flags.Implicit);
5237         else
5238                 implicit_block = current_block;
5240         foreach (VariableDeclaration decl in declarators){
5241                 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer, decl.Location);
5242         }
5243         
5244         return implicit_block;
5247 void CheckAttributeTarget (string a, Location l)
5249         switch (a) {
5251         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
5252                 return;
5253                 
5254         default :
5255                 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
5256                 break;
5257         }
5261 void CheckUnaryOperator (Operator.OpType op, Location l)
5263         switch (op) {
5264                 
5265         case Operator.OpType.LogicalNot: 
5266         case Operator.OpType.OnesComplement: 
5267         case Operator.OpType.Increment:
5268         case Operator.OpType.Decrement:
5269         case Operator.OpType.True: 
5270         case Operator.OpType.False: 
5271         case Operator.OpType.Addition: 
5272         case Operator.OpType.Subtraction:
5273                 
5274                 break;
5275                 
5276         default :
5277                 Report.Error (1019, l, "Overloadable unary operator expected"); 
5278                 break;
5279                 
5280         }
5283 void CheckBinaryOperator (Operator.OpType op, Location l)
5285         switch (op) {
5286                 
5287         case Operator.OpType.Addition: 
5288         case Operator.OpType.Subtraction: 
5289         case Operator.OpType.Multiply:
5290         case Operator.OpType.Division:
5291         case Operator.OpType.Modulus: 
5292         case Operator.OpType.BitwiseAnd: 
5293         case Operator.OpType.BitwiseOr:
5294         case Operator.OpType.ExclusiveOr: 
5295         case Operator.OpType.LeftShift: 
5296         case Operator.OpType.RightShift:
5297         case Operator.OpType.Equality: 
5298         case Operator.OpType.Inequality:
5299         case Operator.OpType.GreaterThan: 
5300         case Operator.OpType.LessThan: 
5301         case Operator.OpType.GreaterThanOrEqual:
5302         case Operator.OpType.LessThanOrEqual:
5303                 break;
5304                 
5305         default :
5306                 Report.Error (1020, l, "Overloadable binary operator expected");
5307                 break;
5308         }
5309         
5312 void syntax_error (Location l, string msg)
5314         Report.Error (1003, l, "Syntax error, " + msg);
5317 void note (string s)
5319         // Used to put annotations
5322 Tokenizer lexer;
5324 public Tokenizer Lexer {
5325         get {
5326                 return lexer;
5327         }
5328 }                  
5330 public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
5332         this.name = file.Name;
5333         this.file = file;
5334         current_namespace = new NamespaceEntry (null, file, null);
5335         current_class = current_namespace.SlaveDeclSpace;
5336         current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
5338         lexer = new Tokenizer (reader, file, defines);
5341 public void parse ()
5343         int errors = Report.Errors;
5344         try {
5345                 if (yacc_verbose_flag > 1)
5346                         yyparse (lexer, new yydebug.yyDebugSimple ());
5347                 else
5348                         yyparse (lexer);
5349                 Tokenizer tokenizer = lexer as Tokenizer;
5350                 tokenizer.cleanup ();
5351         } catch (Exception e){
5352                 //
5353                 // Removed for production use, use parser verbose to get the output.
5354                 //
5355                 // Console.WriteLine (e);
5356                 if (Report.Errors == errors)
5357                         Report.Error (-25, lexer.Location, "Parsing error");
5358                 if (yacc_verbose_flag > 0)
5359                         Console.WriteLine (e);
5360         }
5362         if (RootContext.ToplevelTypes.NamespaceEntry != null)
5363                 throw new InternalErrorException ("who set it?");
5366 static void CheckToken (int error, int yyToken, string msg, Location loc)
5368         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
5369                 Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ());
5370         else
5371                 Report.Error (error, loc, msg);
5374 void CheckIdentifierToken (int yyToken, Location loc)
5376         CheckToken (1041, yyToken, "Identifier expected", loc);
5379 string ConsumeStoredComment ()
5381         string s = tmpComment;
5382         tmpComment = null;
5383         Lexer.doc_state = XmlCommentState.Allowed;
5384         return s;
5387 Location GetLocation (object obj)
5389         if (obj is MemberCore)
5390                 return ((MemberCore) obj).Location;
5391         if (obj is MemberName)
5392                 return ((MemberName) obj).Location;
5393         if (obj is LocatedToken)
5394                 return ((LocatedToken) obj).Location;
5395         if (obj is Location)
5396                 return (Location) obj;
5397         return lexer.Location;
5400 /* end end end */