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