2007-11-16 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / cs-parser.jay
1 %{
2 //
3 // cs-parser.jay: The Parser for the C# compiler
4 //
5 // Authors: Miguel de Icaza (miguel@gnu.org)
6 //          Ravi Pratap     (ravi@ximian.com)
7 //          Marek Safar         (marek.safar@gmail.com)
8 //
9 // Licensed under the terms of the GNU GPL
10 //
11 // (C) 2001 Ximian, Inc (http://www.ximian.com)
12 // (C) 2004 Novell, Inc
13 //
14 // TODO:
15 //   (1) Figure out why error productions dont work.  `type-declaration' is a
16 //       great spot to put an `error' because you can reproduce it with this input:
17 //       "public X { }"
18 //
19 // Possible optimization:
20 //   Run memory profiler with parsing only, and consider dropping 
21 //   arraylists where not needed.   Some pieces can use linked lists.
22 //
23 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).ToString (),
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                 c.ModFlags = (int) $2;
2346         
2347                 if (RootContext.Documentation != null)
2348                         c.DocComment = ConsumeStoredComment ();
2349
2350                 if (c.Name == current_container.Basename){
2351                         if ((c.ModFlags & Modifiers.STATIC) != 0){
2352                                 if ((c.ModFlags & Modifiers.Accessibility) != 0){
2353                                         Report.Error (515, c.Location,
2354                                                 "`{0}': access modifiers are not allowed on static constructors",
2355                                                 c.GetSignatureForError ());
2356                                 }
2357         
2358                                 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);   
2359         
2360                                 if (c.Initializer != null){
2361                                         Report.Error (514, c.Location,
2362                                                 "`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
2363                                                 c.GetSignatureForError ());
2364                                 }
2365                         } else {
2366                                 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
2367                         }
2368                 } else {
2369                         // We let another layer check the validity of the constructor.
2370                         //Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename);
2371                 }
2372
2373                 c.ModFlags |= yield_method;
2374                 current_container.AddConstructor (c);
2375
2376                 current_local_parameters = null;
2377                 if (RootContext.Documentation != null)
2378                         Lexer.doc_state = XmlCommentState.Allowed;
2379           }
2380         ;
2381
2382 constructor_declarator
2383         : constructor_header
2384           {
2385                 $$ = $1;
2386           }
2387         | constructor_header constructor_initializer
2388           {
2389                 ((Constructor)$1).Initializer = (ConstructorInitializer) $2;
2390                 $$ = $1;
2391           }
2392         ;
2393
2394 constructor_header
2395         : IDENTIFIER
2396           {
2397                 if (RootContext.Documentation != null) {
2398                         tmpComment = Lexer.consume_doc_comment ();
2399                         Lexer.doc_state = XmlCommentState.Allowed;
2400                 }
2401           }
2402           open_parens opt_formal_parameter_list CLOSE_PARENS
2403           {
2404                 LocatedToken lt = (LocatedToken) $1;
2405                 current_local_parameters = (Parameters) $4;
2406                 current_block = new ToplevelBlock (null, current_local_parameters, null, lt.Location);
2407
2408                 $$ = new Constructor (current_class, lt.Value, 0, current_local_parameters,
2409                                       null, lt.Location);
2410
2411                 anonymous_host = (IAnonymousHost) $$;
2412           }
2413         ;
2414
2415 constructor_body
2416         : block_prepared
2417         | SEMICOLON             { current_block = null; $$ = null; }
2418         ;
2419
2420 constructor_initializer
2421         : COLON BASE open_parens opt_argument_list CLOSE_PARENS
2422           {
2423                 $$ = new ConstructorBaseInitializer ((ArrayList) $4, (Location) $2);
2424           }
2425         | COLON THIS open_parens opt_argument_list CLOSE_PARENS
2426           {
2427                 $$ = new ConstructorThisInitializer ((ArrayList) $4, (Location) $2);
2428           }
2429         | COLON error {
2430                 Report.Error (1018, (Location) $1, "Keyword this or base expected");
2431                 $$ = null;
2432           }
2433         ;
2434
2435 opt_finalizer
2436         : /* EMPTY */           { $$ = 0; }
2437         | UNSAFE                { $$ = Modifiers.UNSAFE; }
2438         | EXTERN                { $$ = Modifiers.EXTERN; }
2439         ;
2440         
2441 destructor_declaration
2442         : opt_attributes opt_finalizer TILDE 
2443           {
2444                 if (RootContext.Documentation != null) {
2445                         tmpComment = Lexer.consume_doc_comment ();
2446                         Lexer.doc_state = XmlCommentState.NotAllowed;
2447                 }
2448           }
2449           IDENTIFIER OPEN_PARENS CLOSE_PARENS block
2450           {
2451                 LocatedToken lt = (LocatedToken) $5;
2452                 if (lt.Value != current_container.MemberName.Name){
2453                         Report.Error (574, lt.Location, "Name of destructor must match name of class");
2454                 } else if (current_container.Kind != Kind.Class){
2455                         Report.Error (575, lt.Location, "Only class types can contain destructor");
2456                 } else {
2457                         Location l = lt.Location;
2458
2459                         int m = (int) $2;
2460                         if (!RootContext.StdLib && current_container.Name == "System.Object")
2461                                 m |= Modifiers.PROTECTED | Modifiers.VIRTUAL;
2462                         else
2463                                 m |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
2464                         
2465                         Method d = new Destructor (
2466                                 current_class, TypeManager.system_void_expr, m, "Finalize", 
2467                                 Parameters.EmptyReadOnlyParameters, (Attributes) $1, l);
2468                         if (RootContext.Documentation != null)
2469                                 d.DocComment = ConsumeStoredComment ();
2470                   
2471                         d.Block = (ToplevelBlock) $8;
2472                         current_container.AddMethod (d);
2473                 }
2474           }
2475         ;
2476
2477 event_declaration
2478         : opt_attributes
2479           opt_modifiers
2480           EVENT type variable_declarators SEMICOLON
2481           {
2482                 current_array_type = null;
2483                 foreach (VariableDeclaration var in (ArrayList) $5) {
2484
2485                         MemberName name = new MemberName (var.identifier,
2486                                 var.Location);
2487
2488                         EventField e = new EventField (
2489                                 current_class, (Expression) $4, (int) $2, false, name,
2490                                 (Attributes) $1);
2491
2492                         e.Initializer = var.expression_or_array_initializer;
2493
2494                         current_container.AddEvent (e);
2495
2496                         if (RootContext.Documentation != null) {
2497                                 e.DocComment = Lexer.consume_doc_comment ();
2498                                 Lexer.doc_state = XmlCommentState.Allowed;
2499                         }
2500                 }
2501           }
2502         | opt_attributes
2503           opt_modifiers
2504           EVENT type namespace_or_type_name
2505           OPEN_BRACE
2506           {
2507                 implicit_value_parameter_type = (Expression) $4;  
2508                 lexer.EventParsing = true;
2509           }
2510           event_accessor_declarations
2511           {
2512                 lexer.EventParsing = false;  
2513           }
2514           CLOSE_BRACE
2515           {
2516                 MemberName name = (MemberName) $5;
2517
2518                 if ($8 == null){
2519                         Report.Error (65, (Location) $3, "`{0}.{1}': event property must have both add and remove accessors",
2520                                 current_container.Name, name.ToString ());
2521                         $$ = null;
2522                 } else {
2523                         Accessors accessors = (Accessors) $8;
2524                         
2525                         if (name.TypeArguments != null)
2526                                 syntax_error (lexer.Location, "an event can't have type arguments");
2527
2528                         if (accessors.get_or_add == null || accessors.set_or_remove == null)
2529                                 // CS0073 is already reported, so no CS0065 here.
2530                                 $$ = null;
2531                         else {
2532                                 Event e = new EventProperty (
2533                                         current_class, (Expression) $4, (int) $2, false, name,
2534                                         (Attributes) $1, accessors.get_or_add, accessors.set_or_remove);
2535                                 if (RootContext.Documentation != null) {
2536                                         e.DocComment = Lexer.consume_doc_comment ();
2537                                         Lexer.doc_state = XmlCommentState.Allowed;
2538                                 }
2539
2540                                 current_container.AddEvent (e);
2541                                 implicit_value_parameter_type = null;
2542                         }
2543                 }
2544           }
2545         | opt_attributes opt_modifiers EVENT type namespace_or_type_name error {
2546                 MemberName mn = (MemberName) $5;
2547
2548                 if (mn.Left != null)
2549                         Report.Error (71, mn.Location, "An explicit interface implementation of an event must use property syntax");
2550                 else 
2551                         Report.Error (71, mn.Location, "Event declaration should use property syntax");
2552
2553                 if (RootContext.Documentation != null)
2554                         Lexer.doc_state = XmlCommentState.Allowed;
2555           }
2556         ;
2557
2558 event_accessor_declarations
2559         : add_accessor_declaration remove_accessor_declaration
2560           {
2561                 $$ = new Accessors ((Accessor) $1, (Accessor) $2);
2562           }
2563         | remove_accessor_declaration add_accessor_declaration
2564           {
2565                 Accessors accessors = new Accessors ((Accessor) $2, (Accessor) $1);
2566                 accessors.declared_in_reverse = true;
2567                 $$ = accessors;
2568           }     
2569         | add_accessor_declaration  { $$ = null; } 
2570         | remove_accessor_declaration { $$ = null; } 
2571         | error
2572           { 
2573                 Report.Error (1055, GetLocation ($1), "An add or remove accessor expected");
2574                 $$ = null;
2575           }
2576         | { $$ = null; }
2577         ;
2578
2579 add_accessor_declaration
2580         : opt_attributes ADD
2581           {
2582                 Parameter [] args = new Parameter [1];
2583                 Parameter implicit_value_parameter = new Parameter (
2584                         implicit_value_parameter_type, "value", 
2585                         Parameter.Modifier.NONE, null, (Location) $2);
2586
2587                 args [0] = implicit_value_parameter;
2588                 
2589                 current_local_parameters = new Parameters (args);  
2590                 lexer.EventParsing = false;
2591                 
2592                 anonymous_host = SimpleAnonymousHost.GetSimple ();
2593           }
2594           block
2595           {
2596                 Accessor accessor = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, (Location) $2);
2597                 lexer.EventParsing = true;
2598                 
2599                 current_local_parameters = null;
2600                 SimpleAnonymousHost.Simple.Propagate (accessor);
2601                 anonymous_host = null;
2602                 
2603                 $$ = accessor;
2604           }
2605         | opt_attributes ADD error {
2606                 Report.Error (73, (Location) $2, "An add or remove accessor must have a body");
2607                 $$ = null;
2608           }
2609         | opt_attributes modifiers ADD {
2610                 Report.Error (1609, (Location) $3, "Modifiers cannot be placed on event accessor declarations");
2611                 $$ = null;
2612           }
2613         ;
2614
2615 remove_accessor_declaration
2616         : opt_attributes REMOVE
2617           {
2618                 Parameter [] args = new Parameter [1];
2619                 Parameter implicit_value_parameter = new Parameter (
2620                         implicit_value_parameter_type, "value", 
2621                         Parameter.Modifier.NONE, null, (Location) $2);
2622
2623                 args [0] = implicit_value_parameter;
2624                 
2625                 current_local_parameters = new Parameters (args);  
2626                 lexer.EventParsing = false;
2627           }
2628           block
2629           {
2630                 $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, (Location) $2);
2631                 lexer.EventParsing = true;
2632           }
2633         | opt_attributes REMOVE error {
2634                 Report.Error (73, (Location) $2, "An add or remove accessor must have a body");
2635                 $$ = null;
2636           }
2637         | opt_attributes modifiers REMOVE {
2638                 Report.Error (1609, (Location) $3, "Modifiers cannot be placed on event accessor declarations");
2639                 $$ = null;
2640           }
2641         ;
2642
2643 indexer_declaration
2644         : opt_attributes opt_modifiers indexer_declarator 
2645           OPEN_BRACE
2646           {
2647                 IndexerDeclaration decl = (IndexerDeclaration) $3;
2648
2649                 implicit_value_parameter_type = decl.type;
2650                 
2651                 lexer.PropertyParsing = true;
2652                 parsing_indexer  = true;
2653                 
2654                 indexer_parameters = decl.param_list;
2655                 anonymous_host = SimpleAnonymousHost.GetSimple ();
2656           }
2657           accessor_declarations 
2658           {
2659                   lexer.PropertyParsing = false;
2660                   has_get = has_set = false;
2661                   parsing_indexer  = false;
2662           }
2663           CLOSE_BRACE
2664           { 
2665                 if ($6 == null)
2666                         break;
2667
2668                 // The signature is computed from the signature of the indexer.  Look
2669                 // at section 3.6 on the spec
2670                 Indexer indexer;
2671                 IndexerDeclaration decl = (IndexerDeclaration) $3;
2672                 Location loc = decl.location;
2673                 Accessors accessors = (Accessors) $6;
2674                 Accessor get_block = accessors.get_or_add;
2675                 Accessor set_block = accessors.set_or_remove;
2676
2677                 MemberName name;
2678                 if (decl.interface_type != null)
2679                         name = new MemberName (decl.interface_type, TypeContainer.DefaultIndexerName, loc);
2680                 else
2681                         name = new MemberName (TypeContainer.DefaultIndexerName, loc);
2682
2683                 indexer = new Indexer (current_class, decl.type, name,
2684                                        (int) $2, false, decl.param_list, (Attributes) $1,
2685                                        get_block, set_block, accessors.declared_in_reverse);
2686
2687                 if (RootContext.Documentation != null)
2688                         indexer.DocComment = ConsumeStoredComment ();
2689
2690                 current_container.AddIndexer (indexer);
2691                 
2692                 current_local_parameters = null;
2693                 implicit_value_parameter_type = null;
2694                 indexer_parameters = null;
2695           }
2696         ;
2697
2698 indexer_declarator
2699         : type THIS OPEN_BRACKET opt_parameter_list_no_mod CLOSE_BRACKET
2700           {
2701                 Parameters pars = (Parameters) $4;
2702                 if (pars.Empty){
2703                         Report.Error (1551, (Location) $2, "Indexers must have at least one parameter");
2704                 }
2705                 if (RootContext.Documentation != null) {
2706                         tmpComment = Lexer.consume_doc_comment ();
2707                         Lexer.doc_state = XmlCommentState.Allowed;
2708                 }
2709
2710                 $$ = new IndexerDeclaration ((Expression) $1, null, pars, (Location) $2);
2711           }
2712         | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
2713           {
2714                 Parameters pars = (Parameters) $6;
2715                 if (pars.Empty){
2716                         Report.Error (1551, (Location) $4, "Indexers must have at least one parameter");
2717                 }
2718
2719                 MemberName name = (MemberName) $2;
2720                 $$ = new IndexerDeclaration ((Expression) $1, name, pars, (Location) $4);
2721
2722                 if (RootContext.Documentation != null) {
2723                         tmpComment = Lexer.consume_doc_comment ();
2724                         Lexer.doc_state = XmlCommentState.Allowed;
2725                 }
2726           }
2727         ;
2728
2729 enum_declaration
2730         : opt_attributes
2731           opt_modifiers
2732           ENUM IDENTIFIER 
2733           opt_enum_base {
2734                 if (RootContext.Documentation != null)
2735                         enumTypeComment = Lexer.consume_doc_comment ();
2736           }
2737           enum_body
2738           opt_semicolon
2739           {
2740                 LocatedToken lt = (LocatedToken) $4;
2741                 Location enum_location = lt.Location;
2742
2743                 MemberName name = MakeName (new MemberName (lt.Value, enum_location));
2744                 Enum e = new Enum (current_namespace, current_class, (Expression) $5, (int) $2,
2745                                    name, (Attributes) $1);
2746                 
2747                 if (RootContext.Documentation != null)
2748                         e.DocComment = enumTypeComment;
2749
2750
2751                 EnumMember em = null;
2752                 foreach (VariableDeclaration ev in (ArrayList) $7) {
2753                         em = new EnumMember (
2754                                 e, em, ev.identifier, (Expression) ev.expression_or_array_initializer,
2755                                 ev.OptAttributes, ev.Location);
2756
2757 //                      if (RootContext.Documentation != null)
2758                                 em.DocComment = ev.DocComment;
2759
2760                         e.AddEnumMember (em);
2761                 }
2762
2763                 current_container.AddTypeContainer (e);
2764                 $$ = e;
2765
2766           }
2767         ;
2768
2769 opt_enum_base
2770         : /* empty */           { $$ = TypeManager.system_int32_expr; }
2771         | COLON type            { $$ = $2;   }
2772         ;
2773
2774 enum_body
2775         : OPEN_BRACE
2776           {
2777                 if (RootContext.Documentation != null)
2778                         Lexer.doc_state = XmlCommentState.Allowed;
2779           }
2780           opt_enum_member_declarations
2781           {
2782                 // here will be evaluated after CLOSE_BLACE is consumed.
2783                 if (RootContext.Documentation != null)
2784                         Lexer.doc_state = XmlCommentState.Allowed;
2785           }
2786           CLOSE_BRACE
2787           {
2788                 $$ = $3;
2789           }
2790         ;
2791
2792 opt_enum_member_declarations
2793         : /* empty */                   { $$ = new ArrayList (4); }
2794         | enum_member_declarations opt_comma { $$ = $1; }
2795         ;
2796
2797 enum_member_declarations
2798         : enum_member_declaration 
2799           {
2800                 ArrayList l = new ArrayList (4);
2801
2802                 l.Add ($1);
2803                 $$ = l;
2804           }
2805         | enum_member_declarations COMMA enum_member_declaration
2806           {
2807                 ArrayList l = (ArrayList) $1;
2808
2809                 l.Add ($3);
2810
2811                 $$ = l;
2812           }
2813         ;
2814
2815 enum_member_declaration
2816         : opt_attributes IDENTIFIER 
2817           {
2818                 VariableDeclaration vd = new VariableDeclaration (
2819                         (LocatedToken) $2, null, (Attributes) $1);
2820
2821                 if (RootContext.Documentation != null) {
2822                         vd.DocComment = Lexer.consume_doc_comment ();
2823                         Lexer.doc_state = XmlCommentState.Allowed;
2824                 }
2825
2826                 $$ = vd;
2827           }
2828         | opt_attributes IDENTIFIER
2829           {
2830                 if (RootContext.Documentation != null) {
2831                         tmpComment = Lexer.consume_doc_comment ();
2832                         Lexer.doc_state = XmlCommentState.NotAllowed;
2833                 }
2834           }
2835           ASSIGN expression
2836           { 
2837                 VariableDeclaration vd = new VariableDeclaration (
2838                         (LocatedToken) $2, $5, (Attributes) $1);
2839
2840                 if (RootContext.Documentation != null)
2841                         vd.DocComment = ConsumeStoredComment ();
2842
2843                 $$ = vd;
2844           }
2845         ;
2846
2847 delegate_declaration
2848         : opt_attributes
2849           opt_modifiers
2850           DELEGATE
2851           {
2852                 lexer.ConstraintsParsing = true;
2853           }
2854           type type_name
2855           open_parens opt_formal_parameter_list CLOSE_PARENS
2856           {
2857                 MemberName name = MakeName ((MemberName) $6);
2858                 Parameters p = (Parameters) $8;
2859
2860                 Delegate del = new Delegate (current_namespace, current_class, (Expression) $5,
2861                                              (int) $2, name, p, (Attributes) $1);
2862
2863                 if (RootContext.Documentation != null) {
2864                         del.DocComment = Lexer.consume_doc_comment ();
2865                         Lexer.doc_state = XmlCommentState.Allowed;
2866                 }
2867
2868                 current_container.AddDelegate (del);
2869                 current_delegate = del;
2870           }
2871           opt_type_parameter_constraints_clauses
2872           {
2873                 lexer.ConstraintsParsing = false;
2874           }
2875           SEMICOLON
2876           {
2877                 current_delegate.SetParameterInfo ((ArrayList) $11);
2878                 $$ = current_delegate;
2879
2880                 current_delegate = null;
2881           }
2882         ;
2883
2884 opt_nullable
2885         : /* empty */
2886           {
2887                 lexer.CheckNullable (false);
2888                 $$ = false;
2889           }
2890         | INTERR
2891           {
2892                 if (RootContext.Version < LanguageVersion.ISO_2)
2893                         Report.FeatureIsNotAvailable (lexer.Location, "nullable types");
2894                         
2895                 lexer.CheckNullable (true);
2896                 $$ = true;
2897           }
2898         ;
2899
2900 namespace_or_type_name
2901         : IDENTIFIER opt_type_argument_list
2902           {
2903                 LocatedToken lt = (LocatedToken) $1;
2904                 $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location);
2905           }
2906         | IDENTIFIER DOUBLE_COLON IDENTIFIER opt_type_argument_list {
2907                 LocatedToken lt1 = (LocatedToken) $1;
2908                 LocatedToken lt2 = (LocatedToken) $3;
2909                 $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $4, lt2.Location);
2910           }
2911         | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list {
2912                 LocatedToken lt = (LocatedToken) $3;
2913                 $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location);
2914           }
2915         ;
2916
2917 member_name
2918         : IDENTIFIER opt_type_parameter_list
2919           {
2920                 LocatedToken lt = (LocatedToken) $1;
2921                 $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location);
2922           }
2923         | namespace_or_type_name DOT IDENTIFIER opt_type_parameter_list 
2924           {
2925                 LocatedToken lt = (LocatedToken) $3;
2926                 $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location);
2927           }
2928         ;
2929
2930 type_name
2931         : IDENTIFIER opt_type_parameter_list
2932           {
2933                 LocatedToken lt = (LocatedToken) $1;
2934                 $$ = new MemberName (lt.Value, (TypeArguments)$2, lt.Location);   
2935           }
2936         ;
2937
2938 //
2939 // Generics arguments  (any type, without attributes)
2940 //
2941
2942 opt_type_argument_list
2943         : /* empty */                { $$ = null; } 
2944         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2945           {
2946                 if (RootContext.Version == LanguageVersion.ISO_1)
2947                         Report.FeatureIsNotAvailable (lexer.Location, "generics");        
2948           
2949                 $$ = $2;
2950           }
2951         ;
2952
2953 //
2954 // Generics parameters (identifiers only, with attributes), used in type, method declarations
2955 //
2956
2957 opt_type_parameter_list
2958         : /* empty */                { $$ = null; } 
2959         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2960           {
2961                 if (RootContext.Version == LanguageVersion.ISO_1)
2962                         Report.FeatureIsNotAvailable (lexer.Location, "generics");
2963           
2964                 $$ = $2;
2965           }
2966         ;
2967
2968 type_arguments
2969         : type_argument
2970           {
2971                 TypeArguments type_args = new TypeArguments (lexer.Location);
2972                 type_args.Add ((Expression) $1);
2973                 $$ = type_args;
2974           }
2975         | type_arguments COMMA type_argument
2976           {
2977                 TypeArguments type_args = (TypeArguments) $1;
2978                 type_args.Add ((Expression) $3);
2979                 $$ = type_args;
2980           }       
2981         ;
2982
2983 type_argument
2984         : type
2985           {
2986                 $$ = $1;
2987           }
2988         | attribute_sections type
2989           {
2990                 SimpleName sn = $2 as SimpleName;
2991                 if (sn == null)
2992                         Error_TypeExpected (GetLocation ($2));
2993                 else
2994                         $2 = new TypeParameterName (sn.Name, (Attributes) $1, lexer.Location);
2995                 $$ = $2;          
2996           }
2997         ;
2998         
2999 /* 
3000  * Before you think of adding a return_type, notice that we have been
3001  * using two rules in the places where it matters (one rule using type
3002  * and another identical one that uses VOID as the return type).  This
3003  * gets rid of a shift/reduce couple
3004  */
3005 type
3006         : namespace_or_type_name opt_nullable
3007           {
3008                 MemberName name = (MemberName) $1;
3009
3010                 if ((bool) $2) {
3011                         $$ = new ComposedCast (name.GetTypeExpression (), "?", lexer.Location);
3012                 } else {
3013                         if (RootContext.Version > LanguageVersion.ISO_2 && name.Name == "var")
3014                                 $$ = new VarExpr (name.Location);
3015                         else
3016                                 $$ = name.GetTypeExpression ();
3017                 }
3018           }
3019         | builtin_types opt_nullable
3020           {
3021                 if ((bool) $2)
3022                         $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
3023           }
3024         | array_type
3025         | pointer_type
3026         ;
3027
3028 pointer_type
3029         : type STAR
3030           {
3031                 //
3032                 // Note that here only unmanaged types are allowed but we
3033                 // can't perform checks during this phase - we do it during
3034                 // semantic analysis.
3035                 //
3036                 $$ = new ComposedCast ((Expression) $1, "*", Lexer.Location);
3037           }
3038         | VOID STAR
3039           {
3040                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1);
3041           }
3042         ;
3043
3044 non_expression_type
3045         : builtin_types opt_nullable
3046           {
3047                 if ((bool) $2)
3048                         $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
3049           }
3050         | non_expression_type rank_specifier
3051           {
3052                 Location loc = GetLocation ($1);
3053                 if (loc.IsNull)
3054                         loc = lexer.Location;
3055                 $$ = new ComposedCast ((Expression) $1, (string) $2, loc);
3056           }
3057         | non_expression_type STAR
3058           {
3059                 Location loc = GetLocation ($1);
3060                 if (loc.IsNull)
3061                         loc = lexer.Location;
3062                 $$ = new ComposedCast ((Expression) $1, "*", loc);
3063           }
3064         | expression rank_specifiers 
3065           {
3066                 $$ = new ComposedCast ((Expression) $1, (string) $2);
3067           }
3068         | expression STAR 
3069           {
3070                 $$ = new ComposedCast ((Expression) $1, "*");
3071           }
3072         
3073         //
3074         // We need this because the parser will happily go and reduce IDENTIFIER STAR
3075         // through this different path
3076         //
3077         | multiplicative_expression STAR 
3078           {
3079                 $$ = new ComposedCast ((Expression) $1, "*");
3080           }
3081         ;
3082
3083 type_list
3084         : type
3085           {
3086                 ArrayList types = new ArrayList (4);
3087
3088                 types.Add ($1);
3089                 $$ = types;
3090           }
3091         | type_list COMMA type
3092           {
3093                 ArrayList types = (ArrayList) $1;
3094
3095                 types.Add ($3);
3096                 $$ = types;
3097           }
3098         ;
3099
3100 /*
3101  * replaces all the productions for isolating the various
3102  * simple types, but we need this to reuse it easily in local_variable_type
3103  */
3104 builtin_types
3105         : OBJECT        { $$ = TypeManager.system_object_expr; }
3106         | STRING        { $$ = TypeManager.system_string_expr; }
3107         | BOOL          { $$ = TypeManager.system_boolean_expr; }
3108         | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
3109         | FLOAT         { $$ = TypeManager.system_single_expr; }
3110         | DOUBLE        { $$ = TypeManager.system_double_expr; }
3111         | integral_type
3112         ;
3113
3114 integral_type
3115         : SBYTE         { $$ = TypeManager.system_sbyte_expr; }
3116         | BYTE          { $$ = TypeManager.system_byte_expr; }
3117         | SHORT         { $$ = TypeManager.system_int16_expr; }
3118         | USHORT        { $$ = TypeManager.system_uint16_expr; }
3119         | INT           { $$ = TypeManager.system_int32_expr; }
3120         | UINT          { $$ = TypeManager.system_uint32_expr; }
3121         | LONG          { $$ = TypeManager.system_int64_expr; }
3122         | ULONG         { $$ = TypeManager.system_uint64_expr; }
3123         | CHAR          { $$ = TypeManager.system_char_expr; }
3124         | VOID          { $$ = TypeManager.system_void_expr; }
3125         ;
3126
3127 array_type
3128         : type rank_specifiers opt_nullable
3129           {
3130                 string rank_specifiers = (string) $2;
3131                 if ((bool) $3)
3132                         rank_specifiers += "?";
3133
3134                 $$ = current_array_type = new ComposedCast ((Expression) $1, rank_specifiers);
3135           }
3136         ;
3137
3138 //
3139 // Expressions, section 7.5
3140 //
3141 primary_expression
3142         : literal
3143           {
3144                 // 7.5.1: Literals
3145           }
3146         | type_name
3147           {
3148                 MemberName mn = (MemberName) $1;
3149                 $$ = mn.GetTypeExpression ();
3150           }
3151         | IDENTIFIER DOUBLE_COLON IDENTIFIER
3152           {
3153                 LocatedToken lt1 = (LocatedToken) $1;
3154                 LocatedToken lt2 = (LocatedToken) $3;
3155                 $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, lt2.Location);
3156           }
3157         | parenthesized_expression
3158         | default_value_expression
3159         | member_access
3160         | invocation_expression
3161         | element_access
3162         | this_access
3163         | base_access
3164         | post_increment_expression
3165         | post_decrement_expression
3166         | new_expression
3167         | typeof_expression
3168         | sizeof_expression
3169         | checked_expression
3170         | unchecked_expression
3171         | pointer_member_access
3172         | anonymous_method_expression
3173         ;
3174
3175 literal
3176         : boolean_literal
3177         | integer_literal
3178         | real_literal
3179         | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value, lexer.Location); }
3180         | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value, lexer.Location); } 
3181         | NULL                  { $$ = new NullLiteral (lexer.Location); }
3182         ;
3183
3184 real_literal
3185         : LITERAL_FLOAT         { $$ = new FloatLiteral ((float) lexer.Value, lexer.Location); }
3186         | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value, lexer.Location); }
3187         | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value, lexer.Location); }
3188         ;
3189
3190 integer_literal
3191         : LITERAL_INTEGER       { 
3192                 object v = lexer.Value;
3193
3194                 if (v is int){
3195                         $$ = new IntLiteral ((int) v, lexer.Location);
3196                 } else if (v is uint)
3197                         $$ = new UIntLiteral ((UInt32) v, lexer.Location);
3198                 else if (v is long)
3199                         $$ = new LongLiteral ((Int64) v, lexer.Location);
3200                 else if (v is ulong)
3201                         $$ = new ULongLiteral ((UInt64) v, lexer.Location);
3202                 else
3203                         Console.WriteLine ("OOPS.  Unexpected result from scanner");
3204           }
3205         ;
3206
3207 boolean_literal
3208         : TRUE                  { $$ = new BoolLiteral (true, lexer.Location); }
3209         | FALSE                 { $$ = new BoolLiteral (false, lexer.Location); }
3210         ;
3211
3212 parenthesized_expression_0
3213         : OPEN_PARENS expression CLOSE_PARENS
3214           {
3215                 $$ = $2;
3216                 lexer.Deambiguate_CloseParens ($$);
3217                 // After this, the next token returned is one of
3218                 // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST (CLOSE_PARENS), CLOSE_PARENS_OPEN_PARENS
3219                 // or CLOSE_PARENS_MINUS.
3220           }
3221         | OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); }
3222         ;
3223
3224 parenthesized_expression
3225         : parenthesized_expression_0 CLOSE_PARENS_NO_CAST
3226           {
3227                 $$ = $1;
3228           }  
3229         | parenthesized_expression_0 CLOSE_PARENS
3230           {
3231                 $$ = $1;
3232           }       
3233         | parenthesized_expression_0 CLOSE_PARENS_MINUS
3234           {
3235                 // If a parenthesized expression is followed by a minus, we need to wrap
3236                 // the expression inside a ParenthesizedExpression for the CS0075 check
3237                 // in Binary.DoResolve().
3238                 $$ = new ParenthesizedExpression ((Expression) $1);
3239           }
3240         ;
3241
3242 member_access
3243         : primary_expression DOT IDENTIFIER opt_type_argument_list
3244           {
3245                 LocatedToken lt = (LocatedToken) $3;
3246                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3247           }
3248         | predefined_type DOT IDENTIFIER opt_type_argument_list
3249           {
3250                 LocatedToken lt = (LocatedToken) $3;
3251                 // TODO: Location is wrong as some predefined types doesn't hold a location
3252                 $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
3253           }
3254         ;
3255
3256 predefined_type
3257         : builtin_types
3258         ;
3259
3260 invocation_expression
3261         : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3262           {
3263                 if ($1 == null)
3264                         Report.Error (1, (Location) $2, "Parse error");
3265                 else
3266                         $$ = new Invocation ((Expression) $1, (ArrayList) $3);
3267           }
3268         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS
3269           {
3270                 $$ = new Invocation ((Expression) $1, new ArrayList ());
3271           }
3272         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression
3273           {
3274                 $$ = new InvocationOrCast ((Expression) $1, (Expression) $3);
3275           }
3276         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS non_simple_argument CLOSE_PARENS
3277           {
3278                 ArrayList args = new ArrayList (1);
3279                 args.Add ($4);
3280                 $$ = new Invocation ((Expression) $1, args);
3281           }
3282         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS argument_list COMMA argument CLOSE_PARENS
3283           {
3284                 ArrayList args = ((ArrayList) $4);
3285                 args.Add ($6);
3286                 $$ = new Invocation ((Expression) $1, args);
3287           }
3288         ;
3289
3290 opt_object_or_collection_initializer
3291         : /* empty */           { $$ = null; }
3292         | object_or_collection_initializer
3293         ;
3294
3295 object_or_collection_initializer
3296         : OPEN_BRACE opt_member_initializer_list CLOSE_BRACE
3297           {
3298                 if ($2 == null)
3299                   $$ = CollectionOrObjectInitializers.Empty;
3300                 else
3301                   $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1));
3302           }
3303         | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE
3304           {
3305                 $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1));
3306           }
3307         ;
3308
3309 opt_member_initializer_list
3310         : /* empty */           { $$ = null; }
3311         | member_initializer_list
3312         {
3313                 $$ = $1;
3314         }
3315         ;
3316
3317 member_initializer_list
3318         : member_initializer
3319           {
3320                 ArrayList a = new ArrayList ();
3321                 a.Add ($1);
3322                 $$ = a;
3323           }
3324         | member_initializer_list COMMA member_initializer
3325           {
3326                 ArrayList a = (ArrayList)$1;
3327                 a.Add ($3);
3328                 $$ = a;
3329           }
3330         ;
3331
3332 member_initializer
3333         : IDENTIFIER ASSIGN initializer_value
3334           {
3335                 LocatedToken lt = $1 as LocatedToken;
3336                 $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
3337           }
3338         | non_assignment_expression
3339           {
3340                 $$ = new CollectionElementInitializer ((Expression)$1);
3341           }
3342         | OPEN_BRACE expression_list CLOSE_BRACE
3343           {
3344                 $$ = new CollectionElementInitializer ((ArrayList)$2, GetLocation ($1));
3345           }
3346         | OPEN_BRACE CLOSE_BRACE
3347           {
3348                 Report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
3349           }       
3350         ;
3351
3352 initializer_value
3353         : expression
3354         | object_or_collection_initializer
3355         ;
3356
3357 opt_argument_list
3358         : /* empty */           { $$ = null; }
3359         | argument_list
3360         ;
3361
3362 argument_list
3363         : argument
3364           { 
3365                 ArrayList list = new ArrayList (4);
3366                 list.Add ($1);
3367                 $$ = list;
3368           }
3369         | argument_list COMMA argument
3370           {
3371                 ArrayList list = (ArrayList) $1;
3372                 list.Add ($3);
3373                 $$ = list;
3374           }
3375         | argument_list error {
3376                 CheckToken (1026, yyToken, "Expected `,' or `)'", GetLocation ($2));
3377                 $$ = null;
3378           }
3379         ;
3380
3381 argument
3382         : expression
3383           {
3384                 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3385           }
3386         | non_simple_argument
3387           {
3388                 $$ = $1;
3389           }
3390         ;
3391
3392 non_simple_argument
3393         : REF variable_reference 
3394           { 
3395                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3396           }
3397         | OUT variable_reference 
3398           { 
3399                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
3400           }
3401         | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
3402           {
3403                 ArrayList list = (ArrayList) $3;
3404                 Argument[] args = new Argument [list.Count];
3405                 list.CopyTo (args, 0);
3406
3407                 Expression expr = new Arglist (args, (Location) $1);
3408                 $$ = new Argument (expr, Argument.AType.Expression);
3409           }
3410         | ARGLIST OPEN_PARENS CLOSE_PARENS
3411           {
3412                 $$ = new Argument (new Arglist ((Location) $1), Argument.AType.Expression);
3413           }       
3414         | ARGLIST
3415           {
3416                 $$ = new Argument (new ArglistAccess ((Location) $1), Argument.AType.ArgList);
3417           }
3418         ;
3419
3420 variable_reference
3421         : expression { note ("section 5.4"); $$ = $1; }
3422         ;
3423
3424 element_access
3425         : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET 
3426           {
3427                 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3);
3428           }
3429         | primary_expression rank_specifiers
3430           {
3431                 // So the super-trick is that primary_expression
3432                 // can only be either a SimpleName or a MemberAccess. 
3433                 // The MemberAccess case arises when you have a fully qualified type-name like :
3434                 // Foo.Bar.Blah i;
3435                 // SimpleName is when you have
3436                 // Blah i;
3437                   
3438                 Expression expr = (Expression) $1;  
3439                 if (expr is ComposedCast){
3440                         $$ = new ComposedCast (expr, (string) $2);
3441                 } else if (!(expr is SimpleName || expr is MemberAccess || expr is ConstructedType || expr is QualifiedAliasMember)){
3442                         Error_ExpectingTypeName (expr);
3443                         $$ = TypeManager.system_object_expr;
3444                 } else {
3445                         //
3446                         // So we extract the string corresponding to the SimpleName
3447                         // or MemberAccess
3448                         // 
3449                         $$ = new ComposedCast (expr, (string) $2);
3450                 }
3451                 current_array_type = (Expression)$$;
3452           }
3453         ;
3454
3455 expression_list
3456         : expression
3457           {
3458                 ArrayList list = new ArrayList (4);
3459                 list.Add ($1);
3460                 $$ = list;
3461           }
3462         | expression_list COMMA expression
3463           {
3464                 ArrayList list = (ArrayList) $1;
3465                 list.Add ($3);
3466                 $$ = list;
3467           }
3468         ;
3469
3470 this_access
3471         : THIS
3472           {
3473                 $$ = new This (current_block, (Location) $1);
3474           }
3475         ;
3476
3477 base_access
3478         : BASE DOT IDENTIFIER opt_type_argument_list
3479           {
3480                 LocatedToken lt = (LocatedToken) $3;
3481                 $$ = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location);
3482           }
3483         | BASE OPEN_BRACKET expression_list CLOSE_BRACKET
3484           {
3485                 $$ = new BaseIndexerAccess ((ArrayList) $3, (Location) $1);
3486           }
3487         | BASE error {
3488                 Report.Error (175, (Location) $1, "Use of keyword `base' is not valid in this context");
3489                 $$ = null;
3490           }
3491         ;
3492
3493 post_increment_expression
3494         : primary_expression OP_INC
3495           {
3496                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement,
3497                                        (Expression) $1, (Location) $2);
3498           }
3499         ;
3500
3501 post_decrement_expression
3502         : primary_expression OP_DEC
3503           {
3504                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement,
3505                                        (Expression) $1, (Location) $2);
3506           }
3507         ;
3508
3509 new_expression
3510         : object_or_delegate_creation_expression
3511         | array_creation_expression
3512         | anonymous_type_expression
3513         ;
3514
3515 object_or_delegate_creation_expression
3516         : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer
3517           {
3518                 if ($6 != null) {
3519                         if (RootContext.Version <= LanguageVersion.ISO_2)
3520                                 Report.FeatureIsNotAvailable (GetLocation ($1), "object initializers");
3521                                 
3522                         $$ = new NewInitialize ((Expression) $2, (ArrayList) $4, (CollectionOrObjectInitializers) $6, (Location) $1);
3523                 }
3524                 else
3525                         $$ = new New ((Expression) $2, (ArrayList) $4, (Location) $1);
3526           }
3527         | NEW type object_or_collection_initializer
3528           {
3529                 if (RootContext.Version <= LanguageVersion.ISO_2)
3530                         Report.FeatureIsNotAvailable (GetLocation ($1), "collection initializers");
3531           
3532                 $$ = new NewInitialize ((Expression) $2, null, (CollectionOrObjectInitializers) $3, (Location) $1);
3533           }
3534         ;
3535
3536 array_creation_expression
3537         : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET 
3538           opt_rank_specifier
3539           opt_array_initializer
3540           {
3541                 $$ = new ArrayCreation ((Expression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, (Location) $1);
3542           }
3543         | NEW type rank_specifiers array_initializer
3544           {
3545                 $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, (Location) $1);
3546           }
3547         | NEW rank_specifiers array_initializer
3548           {
3549                 $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayList) $3, (Location) $1);
3550           }
3551         | NEW error
3552           {
3553                 Report.Error (1031, (Location) $1, "Type expected");
3554                 $$ = null;
3555           }          
3556         | NEW type error 
3557           {
3558                 Report.Error (1526, (Location) $1, "A new expression requires () or [] after type");
3559                 $$ = null;
3560           }
3561         ;
3562
3563 anonymous_type_expression
3564         : NEW OPEN_BRACE anonymous_type_parameters CLOSE_BRACE
3565           {
3566                 if (RootContext.Version <= LanguageVersion.ISO_2)
3567                         Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
3568
3569                 $$ = new AnonymousTypeDeclaration ((ArrayList) $3, current_container, GetLocation ($1));
3570           }
3571         ;
3572
3573 anonymous_type_parameters
3574         : { $$ = null; }
3575         | anonymous_type_parameter
3576           {
3577                 ArrayList a = new ArrayList (4);
3578                 a.Add ($1);
3579                 $$ = a;
3580           }
3581         | anonymous_type_parameters COMMA anonymous_type_parameter
3582           {
3583                 ArrayList a = (ArrayList) $1;
3584                 a.Add ($3);
3585                 $$ = a;
3586           }
3587         ;
3588
3589 anonymous_type_parameter
3590         : IDENTIFIER ASSIGN variable_initializer
3591           {
3592                 LocatedToken lt = (LocatedToken)$1;
3593                 $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
3594           }
3595         | IDENTIFIER
3596           {
3597                 LocatedToken lt = (LocatedToken)$1;
3598                 $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
3599                         lt.Value, lt.Location);
3600           }
3601         | member_access
3602           {
3603                 MemberAccess ma = (MemberAccess) $1;
3604                 $$ = new AnonymousTypeParameter (ma, ma.Identifier, ma.Location);
3605           }
3606         | error
3607           {
3608                 Report.Error (746, lexer.Location, "Invalid anonymous type member declarator. " +
3609                 "Anonymous type members must be a member assignment, simple name or member access expression");
3610           }
3611         ;
3612
3613 opt_rank_specifier
3614         : /* empty */
3615           {
3616                   $$ = "";
3617           }
3618         | rank_specifiers
3619           {
3620                         $$ = $1;
3621           }
3622         ;
3623
3624 opt_rank_specifier_or_nullable
3625         : /* empty */
3626           {
3627                 $$ = "";
3628           }
3629         | INTERR
3630           {
3631                 $$ = "?";
3632           }
3633         | opt_nullable rank_specifiers
3634           {
3635                 if ((bool) $1)
3636                         $$ = "?" + $2;
3637                 else
3638                         $$ = $2;
3639           }
3640         | opt_nullable rank_specifiers INTERR
3641           {
3642                 if ((bool) $1)
3643                         $$ = "?" + $2 + "?";
3644                 else
3645                         $$ = $2 + "?";
3646           }
3647         ;
3648
3649 rank_specifiers
3650         : rank_specifier opt_rank_specifier
3651           {
3652                   $$ = (string) $2 + (string) $1;
3653           }
3654         ;
3655
3656 rank_specifier
3657         : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
3658           {
3659                 $$ = "[" + (string) $2 + "]";
3660           }
3661         ;
3662
3663 opt_dim_separators
3664         : /* empty */
3665           {
3666                 $$ = "";
3667           }
3668         | dim_separators
3669           {
3670                   $$ = $1;
3671           }               
3672         ;
3673
3674 dim_separators
3675         : COMMA
3676           {
3677                 $$ = ",";
3678           }
3679         | dim_separators COMMA
3680           {
3681                 $$ = (string) $1 + ",";
3682           }
3683         ;
3684
3685 opt_array_initializer
3686         : /* empty */
3687           {
3688                 $$ = null;
3689           }
3690         | array_initializer
3691           {
3692                 $$ = $1;
3693           }
3694         ;
3695
3696 array_initializer
3697         : OPEN_BRACE CLOSE_BRACE
3698           {
3699                 ArrayList list = new ArrayList (4);
3700                 $$ = list;
3701           }
3702         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
3703           {
3704                 $$ = (ArrayList) $2;
3705           }
3706         ;
3707
3708 variable_initializer_list
3709         : variable_initializer
3710           {
3711                 ArrayList list = new ArrayList (4);
3712                 list.Add ($1);
3713                 $$ = list;
3714           }
3715         | variable_initializer_list COMMA variable_initializer
3716           {
3717                 ArrayList list = (ArrayList) $1;
3718                 list.Add ($3);
3719                 $$ = list;
3720           }
3721         ;
3722
3723 typeof_expression
3724         : TYPEOF
3725       {
3726                 pushed_current_array_type = current_array_type;
3727                 lexer.TypeOfParsing = true;
3728           }
3729           OPEN_PARENS typeof_type_expression CLOSE_PARENS
3730           {
3731                 lexer.TypeOfParsing = false;
3732                 Expression type = (Expression)$4;
3733                 if (type == TypeManager.system_void_expr)
3734                         $$ = new TypeOfVoid ((Location) $1);
3735                 else
3736                         $$ = new TypeOf (type, (Location) $1);
3737                 current_array_type = pushed_current_array_type;
3738           }
3739         ;
3740         
3741 typeof_type_expression
3742         : type
3743           {
3744                 $$ = $1;
3745           }
3746         | unbound_type_name
3747           {
3748                 $$ = new UnboundTypeExpression ((MemberName)$1, lexer.Location);
3749           }
3750         ;
3751         
3752 unbound_type_name
3753         : IDENTIFIER GENERIC_DIMENSION
3754           {
3755                 if (RootContext.Version == LanguageVersion.ISO_1)
3756                         Report.FeatureIsNotAvailable (lexer.Location, "generics");
3757           
3758                 LocatedToken lt = (LocatedToken) $1;
3759                 TypeArguments ta = new TypeArguments ((int)$2, lt.Location);
3760
3761                 $$ = new MemberName (lt.Value, ta, lt.Location);
3762           }
3763         | IDENTIFIER DOUBLE_COLON IDENTIFIER GENERIC_DIMENSION
3764           {
3765                 LocatedToken lt = (LocatedToken) $1;
3766                 MemberName left = new MemberName (lt.Value, lt.Location);
3767                 lt = (LocatedToken) $3;
3768                 TypeArguments ta = new TypeArguments ((int)$4, lt.Location);
3769                 
3770                 $$ = new MemberName (left, lt.Value, ta, lt.Location);
3771           }
3772         | unbound_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         | namespace_or_type_name DOT IDENTIFIER GENERIC_DIMENSION
3780           {
3781                 LocatedToken lt = (LocatedToken) $3;
3782                 TypeArguments ta = new TypeArguments ((int)$4, lt.Location);
3783                 
3784                 $$ = new MemberName ((MemberName)$1, lt.Value, ta, lt.Location);
3785           }
3786         ;
3787
3788
3789 sizeof_expression
3790         : SIZEOF OPEN_PARENS type CLOSE_PARENS { 
3791                 $$ = new SizeOf ((Expression) $3, (Location) $1);
3792           }
3793         ;
3794
3795 checked_expression
3796         : CHECKED OPEN_PARENS expression CLOSE_PARENS
3797           {
3798                 $$ = new CheckedExpr ((Expression) $3, (Location) $1);
3799           }
3800         ;
3801
3802 unchecked_expression
3803         : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
3804           {
3805                 $$ = new UnCheckedExpr ((Expression) $3, (Location) $1);
3806           }
3807         ;
3808
3809 pointer_member_access 
3810         : primary_expression OP_PTR IDENTIFIER
3811           {
3812                 Expression deref;
3813                 LocatedToken lt = (LocatedToken) $3;
3814
3815                 deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lt.Location);
3816                 $$ = new MemberAccess (deref, lt.Value);
3817           }
3818         ;
3819
3820 anonymous_method_expression
3821         : DELEGATE opt_anonymous_method_signature
3822           {
3823                 start_anonymous (false, (Parameters) $2, (Location) $1);
3824           }
3825           block
3826           {
3827                 $$ = end_anonymous ((ToplevelBlock) $4, (Location) $1);
3828         }
3829         ;
3830
3831 opt_anonymous_method_signature
3832         : /* empty */                   { $$ = null; } 
3833         | anonymous_method_signature
3834         ;
3835
3836 anonymous_method_signature
3837         : open_parens
3838           {
3839                 params_modifiers_not_allowed = true; 
3840           }
3841           opt_formal_parameter_list CLOSE_PARENS
3842           {
3843                 params_modifiers_not_allowed = false;
3844                 $$ = $3;
3845           }
3846         ;
3847
3848 default_value_expression
3849         : DEFAULT_OPEN_PARENS type CLOSE_PARENS
3850           {
3851                 if (RootContext.Version < LanguageVersion.ISO_2)
3852                         Report.FeatureIsNotAvailable (lexer.Location, "default value expression");
3853
3854                 $$ = new DefaultValueExpression ((Expression) $2, lexer.Location);
3855           }
3856         ;
3857
3858 unary_expression
3859         : primary_expression
3860         | BANG prefixed_unary_expression
3861           {
3862                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, (Location) $1);
3863           }
3864         | TILDE prefixed_unary_expression
3865           {
3866                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, (Location) $1);
3867           }
3868         | cast_expression
3869         ;
3870
3871 cast_list
3872         : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression
3873           {
3874                 $$ = new Cast ((Expression) $1, (Expression) $3);
3875           }
3876         | parenthesized_expression_0 CLOSE_PARENS_NO_CAST default_value_expression
3877           {
3878                 $$ = new Cast ((Expression) $1, (Expression) $3);
3879           }
3880         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression
3881           {
3882                 $$ = new Cast ((Expression) $1, (Expression) $3);
3883           }     
3884         ;
3885
3886 cast_expression
3887         : cast_list
3888         | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
3889           {
3890                 // TODO: wrong location
3891                 $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
3892           }
3893         ;
3894
3895         //
3896         // The idea to split this out is from Rhys' grammar
3897         // to solve the problem with casts.
3898         //
3899 prefixed_unary_expression
3900         : unary_expression
3901         | PLUS prefixed_unary_expression
3902           { 
3903                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, (Location) $1);
3904           } 
3905         | MINUS prefixed_unary_expression 
3906           { 
3907                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, (Location) $1);
3908           }
3909         | OP_INC prefixed_unary_expression 
3910           {
3911                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
3912                                        (Expression) $2, (Location) $1);
3913           }
3914         | OP_DEC prefixed_unary_expression 
3915           {
3916                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
3917                                        (Expression) $2, (Location) $1);
3918           }
3919         | STAR prefixed_unary_expression
3920           {
3921                 $$ = new Unary (Unary.Operator.Indirection, (Expression) $2, (Location) $1);
3922           }
3923         | BITWISE_AND prefixed_unary_expression
3924           {
3925                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, (Location) $1);
3926           }
3927         ;
3928
3929 multiplicative_expression
3930         : prefixed_unary_expression
3931         | multiplicative_expression STAR prefixed_unary_expression
3932           {
3933                 $$ = new Binary (Binary.Operator.Multiply, 
3934                                  (Expression) $1, (Expression) $3);
3935           }
3936         | multiplicative_expression DIV prefixed_unary_expression
3937           {
3938                 $$ = new Binary (Binary.Operator.Division, 
3939                                  (Expression) $1, (Expression) $3);
3940           }
3941         | multiplicative_expression PERCENT prefixed_unary_expression 
3942           {
3943                 $$ = new Binary (Binary.Operator.Modulus, 
3944                                  (Expression) $1, (Expression) $3);
3945           }
3946         ;
3947
3948 additive_expression
3949         : multiplicative_expression
3950         | additive_expression PLUS multiplicative_expression 
3951           {
3952                 $$ = new Binary (Binary.Operator.Addition, 
3953                                  (Expression) $1, (Expression) $3);
3954           }
3955         | additive_expression MINUS multiplicative_expression
3956           {
3957                 $$ = new Binary (Binary.Operator.Subtraction, 
3958                                  (Expression) $1, (Expression) $3);
3959           }
3960         ;
3961
3962 shift_expression
3963         : additive_expression
3964         | shift_expression OP_SHIFT_LEFT additive_expression
3965           {
3966                 $$ = new Binary (Binary.Operator.LeftShift, 
3967                                  (Expression) $1, (Expression) $3);
3968           }
3969         | shift_expression OP_SHIFT_RIGHT additive_expression
3970           {
3971                 $$ = new Binary (Binary.Operator.RightShift, 
3972                                  (Expression) $1, (Expression) $3);
3973           }
3974         ; 
3975
3976 opt_error
3977         : /* empty */
3978           {
3979                 $$ = false;
3980           }
3981         | error
3982           {
3983                 lexer.PutbackNullable ();
3984                 $$ = true;
3985           }
3986         ;
3987
3988 nullable_type_or_conditional
3989         : type opt_error
3990           {
3991                 if (((bool) $2) && ($1 is ComposedCast))
3992                         $$ = ((ComposedCast) $1).RemoveNullable ();
3993                 else
3994                         $$ = $1;
3995           }
3996         ;
3997
3998 relational_expression
3999         : shift_expression
4000         | relational_expression OP_LT shift_expression
4001           {
4002                 $$ = new Binary (Binary.Operator.LessThan, 
4003                                  (Expression) $1, (Expression) $3);
4004           }
4005         | relational_expression OP_GT shift_expression
4006           {
4007                 $$ = new Binary (Binary.Operator.GreaterThan, 
4008                                  (Expression) $1, (Expression) $3);
4009           }
4010         | relational_expression OP_LE shift_expression
4011           {
4012                 $$ = new Binary (Binary.Operator.LessThanOrEqual, 
4013                                  (Expression) $1, (Expression) $3);
4014           }
4015         | relational_expression OP_GE shift_expression
4016           {
4017                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
4018                                  (Expression) $1, (Expression) $3);
4019           }
4020         | relational_expression IS
4021           {
4022                 yyErrorFlag = 3;
4023           } nullable_type_or_conditional
4024           {
4025                 $$ = new Is ((Expression) $1, (Expression) $4, (Location) $2);
4026           }
4027         | relational_expression AS
4028           {
4029                 yyErrorFlag = 3;
4030           } nullable_type_or_conditional
4031           {
4032                 $$ = new As ((Expression) $1, (Expression) $4, (Location) $2);
4033           }
4034         ;
4035
4036 equality_expression
4037         : relational_expression
4038         | equality_expression OP_EQ relational_expression
4039           {
4040                 $$ = new Binary (Binary.Operator.Equality, 
4041                                  (Expression) $1, (Expression) $3);
4042           }
4043         | equality_expression OP_NE relational_expression
4044           {
4045                 $$ = new Binary (Binary.Operator.Inequality, 
4046                                  (Expression) $1, (Expression) $3);
4047           }
4048         ; 
4049
4050 and_expression
4051         : equality_expression
4052         | and_expression BITWISE_AND equality_expression
4053           {
4054                 $$ = new Binary (Binary.Operator.BitwiseAnd, 
4055                                  (Expression) $1, (Expression) $3);
4056           }
4057         ;
4058
4059 exclusive_or_expression
4060         : and_expression
4061         | exclusive_or_expression CARRET and_expression
4062           {
4063                 $$ = new Binary (Binary.Operator.ExclusiveOr, 
4064                                  (Expression) $1, (Expression) $3);
4065           }
4066         ;
4067
4068 inclusive_or_expression
4069         : exclusive_or_expression
4070         | inclusive_or_expression BITWISE_OR exclusive_or_expression
4071           {
4072                 $$ = new Binary (Binary.Operator.BitwiseOr, 
4073                                  (Expression) $1, (Expression) $3);
4074           }
4075         ;
4076
4077 conditional_and_expression
4078         : inclusive_or_expression
4079         | conditional_and_expression OP_AND inclusive_or_expression
4080           {
4081                 $$ = new Binary (Binary.Operator.LogicalAnd, 
4082                                  (Expression) $1, (Expression) $3);
4083           }
4084         ;
4085
4086 conditional_or_expression
4087         : conditional_and_expression
4088         | conditional_or_expression OP_OR conditional_and_expression
4089           {
4090                 $$ = new Binary (Binary.Operator.LogicalOr, 
4091                                  (Expression) $1, (Expression) $3);
4092           }
4093         ;
4094
4095 conditional_expression
4096         : conditional_or_expression
4097         | conditional_or_expression INTERR expression COLON expression 
4098           {
4099                 $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5);
4100           }
4101         | conditional_or_expression OP_COALESCING expression
4102           {
4103                 $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, lexer.Location);
4104           }
4105         // We'll be resolved into a `parenthesized_expression_0' later on.
4106         | conditional_or_expression INTERR CLOSE_PARENS
4107           {
4108                 $$ = new ComposedCast ((Expression) $1, "?", lexer.Location);
4109                 lexer.PutbackCloseParens ();
4110           }
4111         ;
4112
4113 assignment_expression
4114         : prefixed_unary_expression ASSIGN expression
4115           {
4116                 $$ = new Assign ((Expression) $1, (Expression) $3);
4117           }
4118         | prefixed_unary_expression OP_MULT_ASSIGN expression
4119           {
4120                 $$ = new CompoundAssign (
4121                         Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
4122           }
4123         | prefixed_unary_expression OP_DIV_ASSIGN expression
4124           {
4125                 $$ = new CompoundAssign (
4126                         Binary.Operator.Division, (Expression) $1, (Expression) $3);
4127           }
4128         | prefixed_unary_expression OP_MOD_ASSIGN expression
4129           {
4130                 $$ = new CompoundAssign (
4131                         Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
4132           }
4133         | prefixed_unary_expression OP_ADD_ASSIGN expression
4134           {
4135                 $$ = new CompoundAssign (
4136                         Binary.Operator.Addition, (Expression) $1, (Expression) $3);
4137           }
4138         | prefixed_unary_expression OP_SUB_ASSIGN expression
4139           {
4140                 $$ = new CompoundAssign (
4141                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
4142           }
4143         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
4144           {
4145                 $$ = new CompoundAssign (
4146                         Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
4147           }
4148         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
4149           {
4150                 $$ = new CompoundAssign (
4151                         Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
4152           }
4153         | prefixed_unary_expression OP_AND_ASSIGN expression
4154           {
4155                 $$ = new CompoundAssign (
4156                         Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
4157           }
4158         | prefixed_unary_expression OP_OR_ASSIGN expression
4159           {
4160                 $$ = new CompoundAssign (
4161                         Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
4162           }
4163         | prefixed_unary_expression OP_XOR_ASSIGN expression
4164           {
4165                 $$ = new CompoundAssign (
4166                         Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
4167           }
4168         ;
4169
4170 lambda_parameter_list
4171         : lambda_parameter
4172           {
4173                 ArrayList pars = new ArrayList (4);
4174                 pars.Add ($1);
4175
4176                 $$ = pars;
4177           }
4178         | lambda_parameter_list COMMA lambda_parameter
4179           {
4180                 ArrayList pars = (ArrayList) $1;
4181                 Parameter p = (Parameter)$3;
4182                 if (pars[0].GetType () != p.GetType ()) {
4183                         Report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
4184                 }
4185                 
4186                 pars.Add (p);
4187                 $$ = pars;
4188           }
4189         ;
4190
4191 lambda_parameter
4192         : parameter_modifier type IDENTIFIER
4193           {
4194                 LocatedToken lt = (LocatedToken) $3;
4195
4196                 $$ = new Parameter ((Expression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
4197           }
4198         | type IDENTIFIER
4199           {
4200                 LocatedToken lt = (LocatedToken) $2;
4201
4202                 $$ = new Parameter ((Expression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
4203           }
4204         | IDENTIFIER
4205           {
4206                 LocatedToken lt = (LocatedToken) $1;
4207                 $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
4208           }
4209         ;
4210
4211 opt_lambda_parameter_list
4212         : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
4213         | lambda_parameter_list         { 
4214                 ArrayList pars_list = (ArrayList) $1;
4215                 $$ = new Parameters ((Parameter[])pars_list.ToArray (typeof (Parameter)));
4216           }
4217         ;
4218
4219 lambda_expression_body
4220         : {
4221                 start_block (lexer.Location);
4222           }
4223           expression 
4224           {
4225                 Block b = end_block (lexer.Location);
4226                 b.AddStatement (new ContextualReturn ((Expression) $2));
4227                 $$ = b;
4228           } 
4229         | block { 
4230                 $$ = $1; 
4231           } 
4232         ;
4233
4234 lambda_expression
4235         : IDENTIFIER ARROW 
4236           {
4237                 LocatedToken lt = (LocatedToken) $1;
4238                 Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
4239                 start_anonymous (true, new Parameters (p), (Location) $2);
4240           }
4241           lambda_expression_body
4242           {
4243                 $$ = end_anonymous ((ToplevelBlock) $4, (Location) $2);
4244           }
4245         | OPEN_PARENS_LAMBDA opt_lambda_parameter_list CLOSE_PARENS ARROW 
4246           {
4247                 start_anonymous (true, (Parameters) $2, (Location) $4);
4248           }
4249           lambda_expression_body 
4250           {
4251                 $$ = end_anonymous ((ToplevelBlock) $6, (Location) $4);
4252           }
4253         ;
4254
4255 expression
4256         : assignment_expression
4257         | non_assignment_expression
4258         ;
4259         
4260 non_assignment_expression
4261         : conditional_expression
4262         | lambda_expression
4263         | query_expression
4264         ;
4265
4266 constant_expression
4267         : expression
4268         ;
4269
4270 boolean_expression
4271         : expression
4272         ;
4273
4274 //
4275 // 10 classes
4276 //
4277 class_declaration
4278         : opt_attributes
4279           opt_modifiers
4280           opt_partial
4281           CLASS
4282           {
4283                 lexer.ConstraintsParsing = true;
4284           }
4285           type_name
4286           {
4287                 MemberName name = MakeName ((MemberName) $6);
4288                 push_current_class (new Class (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3);
4289           }
4290           opt_class_base
4291           opt_type_parameter_constraints_clauses
4292           {
4293                 lexer.ConstraintsParsing = false;
4294
4295                 current_class.SetParameterInfo ((ArrayList) $9);
4296
4297                 if (RootContext.Documentation != null) {
4298                         current_container.DocComment = Lexer.consume_doc_comment ();
4299                         Lexer.doc_state = XmlCommentState.Allowed;
4300                 }
4301           }
4302           class_body
4303           {
4304                 if (RootContext.Documentation != null)
4305                         Lexer.doc_state = XmlCommentState.Allowed;
4306           }
4307           opt_semicolon 
4308           {
4309                 $$ = pop_current_class ();
4310           }
4311         ;       
4312
4313 opt_partial
4314         : /* empty */
4315           { $$ = null; }
4316         | PARTIAL
4317           { $$ = $1; } // location
4318         ;
4319
4320 opt_modifiers
4321         : /* empty */           { $$ = (int) 0; }
4322         | modifiers
4323         ;
4324
4325 modifiers
4326         : modifier
4327         | modifiers modifier
4328           { 
4329                 int m1 = (int) $1;
4330                 int m2 = (int) $2;
4331
4332                 if ((m1 & m2) != 0) {
4333                         Location l = lexer.Location;
4334                         Report.Error (1004, l, "Duplicate `{0}' modifier", Modifiers.Name (m2));
4335                 }
4336                 $$ = (int) (m1 | m2);
4337           }
4338         ;
4339
4340 modifier
4341         : NEW                   { $$ = Modifiers.NEW; }
4342         | PUBLIC                { $$ = Modifiers.PUBLIC; }
4343         | PROTECTED             { $$ = Modifiers.PROTECTED; }
4344         | INTERNAL              { $$ = Modifiers.INTERNAL; }
4345         | PRIVATE               { $$ = Modifiers.PRIVATE; }
4346         | ABSTRACT              { $$ = Modifiers.ABSTRACT; }
4347         | SEALED                { $$ = Modifiers.SEALED; }
4348         | STATIC                { $$ = Modifiers.STATIC; }
4349         | READONLY              { $$ = Modifiers.READONLY; }
4350         | VIRTUAL               { $$ = Modifiers.VIRTUAL; }
4351         | OVERRIDE              { $$ = Modifiers.OVERRIDE; }
4352         | EXTERN                { $$ = Modifiers.EXTERN; }
4353         | VOLATILE              { $$ = Modifiers.VOLATILE; }
4354         | UNSAFE                { $$ = Modifiers.UNSAFE; }
4355         ;
4356
4357 opt_class_base
4358         : /* empty */
4359         | class_base
4360         ;
4361
4362 class_base
4363         : COLON type_list       { current_container.AddBasesForPart (current_class, (ArrayList) $2); }
4364         ;
4365
4366 opt_type_parameter_constraints_clauses
4367         : /* empty */           { $$ = null; }
4368         | type_parameter_constraints_clauses 
4369           { $$ = $1; }
4370         ;
4371
4372 type_parameter_constraints_clauses
4373         : type_parameter_constraints_clause {
4374                 ArrayList constraints = new ArrayList (1);
4375                 constraints.Add ($1);
4376                 $$ = constraints;
4377           }
4378         | type_parameter_constraints_clauses type_parameter_constraints_clause {
4379                 ArrayList constraints = (ArrayList) $1;
4380                 Constraints new_constraint = (Constraints)$2;
4381
4382                 foreach (Constraints c in constraints) {
4383                         if (new_constraint.TypeParameter == c.TypeParameter) {
4384                                 Report.Error (409, new_constraint.Location, "A constraint clause has already been specified for type parameter `{0}'",
4385                                         new_constraint.TypeParameter);
4386                         }
4387                 }
4388
4389                 constraints.Add (new_constraint);
4390                 $$ = constraints;
4391           }
4392         ; 
4393
4394 type_parameter_constraints_clause
4395         : WHERE IDENTIFIER COLON type_parameter_constraints {
4396                 LocatedToken lt = (LocatedToken) $2;
4397                 $$ = new Constraints (lt.Value, (ArrayList) $4, lt.Location);
4398           }
4399         ; 
4400
4401 type_parameter_constraints
4402         : type_parameter_constraint {
4403                 ArrayList constraints = new ArrayList (1);
4404                 constraints.Add ($1);
4405                 $$ = constraints;
4406           }
4407         | type_parameter_constraints COMMA type_parameter_constraint {
4408                 ArrayList constraints = (ArrayList) $1;
4409
4410                 constraints.Add ($3);
4411                 $$ = constraints;
4412           }
4413         ;
4414
4415 type_parameter_constraint
4416         : type
4417         | NEW OPEN_PARENS CLOSE_PARENS {
4418                 $$ = SpecialConstraint.Constructor;
4419           }
4420         | CLASS {
4421                 $$ = SpecialConstraint.ReferenceType;
4422           }
4423         | STRUCT {
4424                 $$ = SpecialConstraint.ValueType;
4425           }
4426         ;
4427
4428 //
4429 // Statements (8.2)
4430 //
4431
4432 //
4433 // A block is "contained" on the following places:
4434 //      method_body
4435 //      property_declaration as part of the accessor body (get/set)
4436 //      operator_declaration
4437 //      constructor_declaration
4438 //      destructor_declaration
4439 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
4440 //      
4441 block
4442         : OPEN_BRACE  
4443           {
4444                 ++lexer.parsing_block;
4445                 start_block ((Location) $1);
4446           } 
4447           opt_statement_list CLOSE_BRACE 
4448           {
4449                 --lexer.parsing_block;
4450                 $$ = end_block ((Location) $4);
4451           }
4452         ;
4453
4454 block_prepared
4455         : OPEN_BRACE
4456           {
4457                 ++lexer.parsing_block;
4458           }
4459           opt_statement_list CLOSE_BRACE 
4460           {
4461                 --lexer.parsing_block;
4462                 $$ = end_block ((Location) $4);
4463           }
4464         ;
4465
4466 opt_statement_list
4467         : /* empty */
4468         | statement_list 
4469         ;
4470
4471 statement_list
4472         : statement
4473         | statement_list statement
4474         ;
4475
4476 statement
4477         : declaration_statement
4478           {
4479                 if ($1 != null && (Block) $1 != current_block){
4480                         current_block.AddStatement ((Statement) $1);
4481                         current_block = (Block) $1;
4482                 }
4483           }
4484         | valid_declaration_statement
4485           {
4486                 current_block.AddStatement ((Statement) $1);
4487           }
4488         | labeled_statement
4489         ;
4490
4491 valid_declaration_statement
4492         : block
4493         | empty_statement
4494         | expression_statement
4495         | selection_statement
4496         | iteration_statement
4497         | jump_statement                  
4498         | try_statement
4499         | checked_statement
4500         | unchecked_statement
4501         | lock_statement
4502         | using_statement
4503         | unsafe_statement
4504         | fixed_statement
4505         ;
4506
4507 embedded_statement
4508         : valid_declaration_statement
4509         | declaration_statement
4510           {
4511                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4512                   $$ = null;
4513           }
4514         | labeled_statement
4515           {
4516                   Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
4517                   $$ = null;
4518           }
4519         ;
4520
4521 empty_statement
4522         : SEMICOLON
4523           {
4524                   $$ = EmptyStatement.Value;
4525           }
4526         ;
4527
4528 labeled_statement
4529         : IDENTIFIER COLON 
4530           {
4531                 LocatedToken lt = (LocatedToken) $1;
4532                 LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location);
4533
4534                 if (current_block.AddLabel (labeled))
4535                         current_block.AddStatement (labeled);
4536           }
4537           statement
4538         ;
4539
4540 declaration_statement
4541         : local_variable_declaration SEMICOLON
4542           {
4543                 current_array_type = null;
4544                 if ($1 != null){
4545                         DictionaryEntry de = (DictionaryEntry) $1;
4546                         Expression e = (Expression) de.Key;
4547
4548                         $$ = declare_local_variables (e, (ArrayList) de.Value, e.Location);
4549                 }
4550           }
4551
4552         | local_constant_declaration SEMICOLON
4553           {
4554                 current_array_type = null;
4555                 if ($1 != null){
4556                         DictionaryEntry de = (DictionaryEntry) $1;
4557
4558                         $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value);
4559                 }
4560           }
4561         ;
4562
4563 /* 
4564  * The following is from Rhys' grammar:
4565  * > Types in local variable declarations must be recognized as 
4566  * > expressions to prevent reduce/reduce errors in the grammar.
4567  * > The expressions are converted into types during semantic analysis.
4568  */
4569 local_variable_type
4570         : primary_expression opt_rank_specifier_or_nullable
4571           { 
4572                 // FIXME: Do something smart here regarding the composition of the type.
4573
4574                 // Ok, the above "primary_expression" is there to get rid of
4575                 // both reduce/reduce and shift/reduces in the grammar, it should
4576                 // really just be "type_name".  If you use type_name, a reduce/reduce
4577                 // creeps up.  If you use namespace_or_type_name (which is all we need
4578                 // really) two shift/reduces appear.
4579                 // 
4580
4581                 // So the super-trick is that primary_expression
4582                 // can only be either a SimpleName or a MemberAccess. 
4583                 // The MemberAccess case arises when you have a fully qualified type-name like :
4584                 // Foo.Bar.Blah i;
4585                 // SimpleName is when you have
4586                 // Blah i;
4587                   
4588                 Expression expr = (Expression) $1;
4589                 SimpleName sn = expr as SimpleName;
4590                 if (!(sn != null || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType || expr is QualifiedAliasMember)) {
4591                         Error_ExpectingTypeName (expr);
4592                         $$ = null;
4593                 } else {
4594                         //
4595                         // So we extract the string corresponding to the SimpleName
4596                         // or MemberAccess
4597                         // 
4598
4599                         if ((string) $2 == "") {
4600                                 if (sn != null && RootContext.Version > LanguageVersion.ISO_2 && sn.Name == "var")
4601                                         $$ = new VarExpr (sn.Location);
4602                                 else
4603                                         $$ = $1;
4604                         } else
4605                                 $$ = new ComposedCast ((Expression) $1, (string) $2);
4606                 }
4607           }
4608         | builtin_types opt_rank_specifier_or_nullable
4609           {
4610                 if ((string) $2 == "")
4611                         $$ = $1;
4612                 else
4613                         $$ = current_array_type = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
4614           }
4615         ;
4616
4617 local_variable_pointer_type
4618         : primary_expression STAR
4619           {
4620                 Expression expr = (Expression) $1;  
4621
4622                 if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType || expr is QualifiedAliasMember)) {
4623                         Error_ExpectingTypeName (expr);
4624
4625                         $$ = null;
4626                 } else 
4627                         $$ = new ComposedCast ((Expression) $1, "*");
4628           }
4629         | builtin_types STAR
4630           {
4631                 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
4632           }
4633         | VOID STAR
4634           {
4635                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1);
4636           }
4637         | local_variable_pointer_type STAR
4638           {
4639                 $$ = new ComposedCast ((Expression) $1, "*");
4640           }
4641         ;
4642
4643 local_variable_declaration
4644         : local_variable_type variable_declarators
4645           {
4646                 if ($1 != null) {
4647                         VarExpr ve = $1 as VarExpr;
4648                         if (ve != null)
4649                                 ve.VariableInitializer = (ArrayList)$2;
4650                                 
4651                         $$ = new DictionaryEntry ($1, $2);
4652                 } else
4653                         $$ = null;
4654           }
4655         | local_variable_pointer_type opt_rank_specifier_or_nullable variable_declarators
4656           {
4657                 if ($1 != null){
4658                         Expression t;
4659
4660                         if ((string) $2 == "")
4661                                 t = (Expression) $1;
4662                         else
4663                                 t = new ComposedCast ((Expression) $1, (string) $2);
4664                         $$ = new DictionaryEntry (t, $3);
4665                 } else 
4666                         $$ = null;
4667           }
4668         ;
4669
4670 local_constant_declaration
4671         : CONST local_variable_type constant_declarators
4672           {
4673                 if ($2 != null)
4674                         $$ = new DictionaryEntry ($2, $3);
4675                 else
4676                         $$ = null;
4677           }
4678         ;
4679
4680 expression_statement
4681         : statement_expression SEMICOLON { $$ = $1; }
4682         ;
4683
4684         //
4685         // We have to do the wrapping here and not in the case above,
4686         // because statement_expression is used for example in for_statement
4687         //
4688 statement_expression
4689         : expression
4690           {
4691                 Expression expr = (Expression) $1;
4692                 ExpressionStatement s = expr as ExpressionStatement;
4693                 if (s == null) {
4694                         expr.Error_InvalidExpressionStatement ();
4695                         $$ = null;
4696                 }
4697                 $$ = new StatementExpression (s);
4698           }
4699         | error
4700           {
4701                 Report.Error (1002, GetLocation ($1), "Expecting `;'");
4702                 $$ = null;
4703           }
4704         ;
4705
4706 selection_statement
4707         : if_statement
4708         | switch_statement
4709         ; 
4710
4711 if_statement
4712         : IF OPEN_PARENS boolean_expression CLOSE_PARENS 
4713           embedded_statement
4714           { 
4715                 Location l = (Location) $1;
4716
4717                 $$ = new If ((Expression) $3, (Statement) $5, l);
4718
4719                 // FIXME: location for warning should be loc property of $5.
4720                 if ($5 == EmptyStatement.Value)
4721                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4722
4723           }
4724         | IF OPEN_PARENS boolean_expression CLOSE_PARENS
4725           embedded_statement ELSE embedded_statement
4726           {
4727                 Location l = (Location) $1;
4728
4729                 $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7, l);
4730
4731                 // FIXME: location for warning should be loc property of $5 and $7.
4732                 if ($5 == EmptyStatement.Value)
4733                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4734                 if ($7 == EmptyStatement.Value)
4735                         Report.Warning (642, 3, l, "Possible mistaken empty statement");
4736           }
4737         ;
4738
4739 switch_statement
4740         : SWITCH OPEN_PARENS
4741           { 
4742                 if (switch_stack == null)
4743                         switch_stack = new Stack (2);
4744                 switch_stack.Push (current_block);
4745           }
4746           expression CLOSE_PARENS 
4747           switch_block
4748           {
4749                 $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) $1);
4750                 current_block = (Block) switch_stack.Pop ();
4751           }
4752         ;
4753
4754 switch_block
4755         : OPEN_BRACE
4756           opt_switch_sections
4757           CLOSE_BRACE
4758           {
4759                 $$ = $2;
4760           }
4761         ;
4762
4763 opt_switch_sections
4764         : /* empty */           
4765           {
4766                 Report.Warning (1522, 1, lexer.Location, "Empty switch block"); 
4767                 $$ = new ArrayList ();
4768           }
4769         | switch_sections
4770         ;
4771
4772 switch_sections
4773         : switch_section 
4774           {
4775                 ArrayList sections = new ArrayList (4);
4776
4777                 sections.Add ($1);
4778                 $$ = sections;
4779           }
4780         | switch_sections switch_section
4781           {
4782                 ArrayList sections = (ArrayList) $1;
4783
4784                 sections.Add ($2);
4785                 $$ = sections;
4786           }
4787         ;
4788
4789 switch_section
4790         : switch_labels
4791           {
4792                 current_block = current_block.CreateSwitchBlock (lexer.Location);
4793           }
4794           statement_list 
4795           {
4796                 $$ = new SwitchSection ((ArrayList) $1, current_block.Explicit);
4797           }
4798         ;
4799
4800 switch_labels
4801         : switch_label 
4802           {
4803                 ArrayList labels = new ArrayList (4);
4804
4805                 labels.Add ($1);
4806                 $$ = labels;
4807           }
4808         | switch_labels switch_label 
4809           {
4810                 ArrayList labels = (ArrayList) ($1);
4811                 labels.Add ($2);
4812
4813                 $$ = labels;
4814           }
4815         ;
4816
4817 switch_label
4818         : CASE constant_expression COLON        { $$ = new SwitchLabel ((Expression) $2, (Location) $1); }
4819         | DEFAULT_COLON                         { $$ = new SwitchLabel (null, (Location) $1); }
4820         | error {
4821                 Report.Error (
4822                         1523, GetLocation ($1), 
4823                         "The keyword case or default must precede code in switch block");
4824           }
4825         ;
4826
4827 iteration_statement
4828         : while_statement
4829         | do_statement
4830         | for_statement
4831         | foreach_statement
4832         ;
4833
4834 while_statement
4835         : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement
4836           {
4837                 Location l = (Location) $1;
4838                 $$ = new While ((Expression) $3, (Statement) $5, l);
4839           }
4840         ;
4841
4842 do_statement
4843         : DO embedded_statement 
4844           WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
4845           {
4846                 Location l = (Location) $1;
4847
4848                 $$ = new Do ((Statement) $2, (Expression) $5, l);
4849           }
4850         ;
4851
4852 for_statement
4853         : FOR open_parens 
4854           opt_for_initializer SEMICOLON
4855           {
4856                 Location l = lexer.Location;
4857                 start_block (l);  
4858                 Block assign_block = current_block;
4859
4860                 if ($3 is DictionaryEntry){
4861                         DictionaryEntry de = (DictionaryEntry) $3;
4862                         
4863                         Expression type = (Expression) de.Key;
4864                         ArrayList var_declarators = (ArrayList) de.Value;
4865
4866                         foreach (VariableDeclaration decl in var_declarators){
4867
4868                                 LocalInfo vi;
4869
4870                                 vi = current_block.AddVariable (type, decl.identifier, decl.Location);
4871                                 if (vi == null)
4872                                         continue;
4873
4874                                 Expression expr = decl.expression_or_array_initializer;
4875                                         
4876                                 LocalVariableReference var;
4877                                 var = new LocalVariableReference (assign_block, decl.identifier, l);
4878
4879                                 if (expr != null) {
4880                                         Assign a = new Assign (var, expr, decl.Location);
4881                                         
4882                                         assign_block.AddStatement (new StatementExpression (a));
4883                                 }
4884                         }
4885                         
4886                         // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal.
4887                         // This can be referred to as $5 below.
4888                         $$ = null;
4889                 } else {
4890                         $$ = $3;
4891                 }
4892           } 
4893           opt_for_condition SEMICOLON
4894           opt_for_iterator CLOSE_PARENS 
4895           embedded_statement
4896           {
4897                 Location l = (Location) $1;
4898
4899                 For f = new For ((Statement) $5, (Expression) $6, (Statement) $8, (Statement) $10, l);
4900
4901                 current_block.AddStatement (f);
4902
4903                 $$ = end_block (lexer.Location);
4904           }
4905         ;
4906
4907 opt_for_initializer
4908         : /* empty */           { $$ = EmptyStatement.Value; }
4909         | for_initializer       
4910         ;
4911
4912 for_initializer
4913         : local_variable_declaration
4914         | statement_expression_list
4915         ;
4916
4917 opt_for_condition
4918         : /* empty */           { $$ = null; }
4919         | boolean_expression
4920         ;
4921
4922 opt_for_iterator
4923         : /* empty */           { $$ = EmptyStatement.Value; }
4924         | for_iterator
4925         ;
4926
4927 for_iterator
4928         : statement_expression_list
4929         ;
4930
4931 statement_expression_list
4932         : statement_expression  
4933           {
4934                 // CHANGE: was `null'
4935                 Statement s = (Statement) $1;
4936                 Block b = new Block (current_block, s.loc, lexer.Location);   
4937
4938                 b.AddStatement (s);
4939                 $$ = b;
4940           }
4941         | statement_expression_list COMMA statement_expression
4942           {
4943                 Block b = (Block) $1;
4944
4945                 b.AddStatement ((Statement) $3);
4946                 $$ = $1;
4947           }
4948         ;
4949
4950 foreach_statement
4951         : FOREACH open_parens type IN expression CLOSE_PARENS
4952           {
4953                 Report.Error (230, (Location) $1, "Type and identifier are both required in a foreach statement");
4954                 $$ = null;
4955           }
4956         | FOREACH open_parens type IDENTIFIER IN
4957           expression CLOSE_PARENS 
4958           {
4959                 start_block (lexer.Location);
4960                 Block foreach_block = current_block;
4961
4962                 LocatedToken lt = (LocatedToken) $4;
4963                 Location l = lt.Location;
4964                 LocalInfo vi = foreach_block.AddVariable ((Expression) $3, lt.Value, l);
4965                 if (vi != null) {
4966                         vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach);
4967
4968                         // Get a writable reference to this read-only variable.
4969                         //
4970                         // Note that the $$ here refers to the value of _this_ code block,
4971                         // not the value of the LHS non-terminal.  This can be referred to as $8 below.
4972                         $$ = new LocalVariableReference (foreach_block, lt.Value, l, vi, false);
4973                 } else {
4974                         $$ = null;
4975                 }
4976           } 
4977           embedded_statement 
4978           {
4979                 LocalVariableReference v = (LocalVariableReference) $8;
4980                 Location l = (Location) $1;
4981
4982                 if (v != null) {
4983                         Foreach f = new Foreach ((Expression) $3, v, (Expression) $6, (Statement) $9, l);
4984                         current_block.AddStatement (f);
4985                 }
4986
4987                 $$ = end_block (lexer.Location);
4988           }
4989         ;
4990
4991 jump_statement
4992         : break_statement
4993         | continue_statement
4994         | goto_statement
4995         | return_statement
4996         | throw_statement
4997         | yield_statement
4998         ;
4999
5000 break_statement
5001         : BREAK SEMICOLON
5002           {
5003                 $$ = new Break ((Location) $1);
5004           }
5005         ;
5006
5007 continue_statement
5008         : CONTINUE SEMICOLON
5009           {
5010                 $$ = new Continue ((Location) $1);
5011           }
5012         ;
5013
5014 goto_statement
5015         : GOTO IDENTIFIER SEMICOLON 
5016           {
5017                 LocatedToken lt = (LocatedToken) $2;
5018                 $$ = new Goto (lt.Value, lt.Location);
5019           }
5020         | GOTO CASE constant_expression SEMICOLON
5021           {
5022                 $$ = new GotoCase ((Expression) $3, (Location) $1);
5023           }
5024         | GOTO DEFAULT SEMICOLON 
5025           {
5026                 $$ = new GotoDefault ((Location) $1);
5027           }
5028         ; 
5029
5030 return_statement
5031         : RETURN opt_expression SEMICOLON
5032           {
5033                 $$ = new Return ((Expression) $2, (Location) $1);
5034           }
5035         ;
5036
5037 throw_statement
5038         : THROW opt_expression SEMICOLON
5039           {
5040                 $$ = new Throw ((Expression) $2, (Location) $1);
5041           }
5042         ;
5043
5044 yield_statement 
5045         : IDENTIFIER RETURN expression SEMICOLON
5046           {
5047                 LocatedToken lt = (LocatedToken) $1;
5048                 string s = lt.Value;
5049                 if (s != "yield"){
5050                         Report.Error (1003, lt.Location, "; expected");
5051                         $$ = null;
5052                 }
5053                 if (RootContext.Version == LanguageVersion.ISO_1){
5054                         Report.FeatureIsNotAvailable (lt.Location, "yield statement");
5055                         $$ = null;
5056                 }
5057                 if (anonymous_host == null){
5058                         Report.Error (204, lt.Location, "yield statement can only be used within a method, operator or property");
5059                         $$ = null;
5060                 } else {
5061                         anonymous_host.SetYields ();
5062                         $$ = new Yield ((Expression) $3, lt.Location); 
5063                 }
5064           }
5065         | IDENTIFIER RETURN SEMICOLON
5066           {
5067                 Report.Error (1627, (Location) $2, "Expression expected after yield return");
5068                 $$ = null;
5069           }
5070         | IDENTIFIER BREAK SEMICOLON
5071           {
5072                 LocatedToken lt = (LocatedToken) $1;
5073                 string s = lt.Value;
5074                 if (s != "yield"){
5075                         Report.Error (1003, lt.Location, "; expected");
5076                         $$ = null;
5077                 }
5078                 if (RootContext.Version == LanguageVersion.ISO_1){
5079                         Report.FeatureIsNotAvailable (lt.Location, "yield statement");
5080                         $$ = null;
5081                 }
5082                 if (anonymous_host == null){
5083                         Report.Error (204, lt.Location, "yield statement can only be used within a method, operator or property");
5084                         $$ = null;
5085                 } else {
5086                         anonymous_host.SetYields ();
5087                         $$ = new YieldBreak (lt.Location);
5088                 }
5089           }
5090         ;
5091
5092 opt_expression
5093         : /* empty */
5094         | expression
5095         ;
5096
5097 try_statement
5098         : TRY block catch_clauses 
5099           {
5100                 Catch g = null;
5101                 
5102                 ArrayList c = (ArrayList)$3;
5103                 for (int i = 0; i < c.Count; ++i) {
5104                         Catch cc = (Catch) c [i];
5105                         if (cc.IsGeneral) {
5106                                 if (i != c.Count - 1)
5107                                         Report.Error (1017, cc.loc, "Try statement already has an empty catch block");
5108                                 g = cc;
5109                                 c.RemoveAt (i);
5110                                 i--;
5111                         }
5112                 }
5113
5114                 // Now s contains the list of specific catch clauses
5115                 // and g contains the general one.
5116                 
5117                 $$ = new Try ((Block) $2, c, g, null, ((Block) $2).loc);
5118           }
5119         | TRY block opt_catch_clauses FINALLY block
5120           {
5121                 Catch g = null;
5122                 ArrayList s = new ArrayList (4);
5123                 ArrayList catch_list = (ArrayList) $3;
5124
5125                 if (catch_list != null){
5126                         foreach (Catch cc in catch_list) {
5127                                 if (cc.IsGeneral)
5128                                         g = cc;
5129                                 else
5130                                         s.Add (cc);
5131                         }
5132                 }
5133
5134                 $$ = new Try ((Block) $2, s, g, (Block) $5, ((Block) $2).loc);
5135           }
5136         | TRY block error 
5137           {
5138                 Report.Error (1524, (Location) $1, "Expected catch or finally");
5139                 $$ = null;
5140           }
5141         ;
5142
5143 opt_catch_clauses
5144         : /* empty */  { $$ = null; }
5145         | catch_clauses
5146         ;
5147
5148 catch_clauses
5149         : catch_clause 
5150           {
5151                 ArrayList l = new ArrayList (4);
5152
5153                 l.Add ($1);
5154                 $$ = l;
5155           }
5156         | catch_clauses catch_clause
5157           {
5158                 ArrayList l = (ArrayList) $1;
5159
5160                 l.Add ($2);
5161                 $$ = l;
5162           }
5163         ;
5164
5165 opt_identifier
5166         : /* empty */   { $$ = null; }
5167         | IDENTIFIER
5168         ;
5169
5170 catch_clause 
5171         : CATCH opt_catch_args 
5172           {
5173                 Expression type = null;
5174                 
5175                 if ($2 != null) {
5176                         DictionaryEntry cc = (DictionaryEntry) $2;
5177                         type = (Expression) cc.Key;
5178                         LocatedToken lt = (LocatedToken) cc.Value;
5179
5180                         if (lt != null){
5181                                 ArrayList one = new ArrayList (4);
5182
5183                                 one.Add (new VariableDeclaration (lt, null));
5184
5185                                 start_block (lexer.Location);
5186                                 current_block = declare_local_variables (type, one, lt.Location);
5187                         }
5188                 }
5189           } block {
5190                 Expression type = null;
5191                 string id = null;
5192                 Block var_block = null;
5193
5194                 if ($2 != null){
5195                         DictionaryEntry cc = (DictionaryEntry) $2;
5196                         type = (Expression) cc.Key;
5197                         LocatedToken lt = (LocatedToken) cc.Value;
5198
5199                         if (lt != null){
5200                                 id = lt.Value;
5201                                 var_block = end_block (lexer.Location);
5202                         }
5203                 }
5204
5205                 $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc);
5206           }
5207         ;
5208
5209 opt_catch_args
5210         : /* empty */ { $$ = null; }
5211         | catch_args
5212         ;         
5213
5214 catch_args 
5215         : open_parens type opt_identifier CLOSE_PARENS 
5216           {
5217                 $$ = new DictionaryEntry ($2, $3);
5218           }
5219         ;
5220
5221
5222 checked_statement
5223         : CHECKED block
5224           {
5225                 $$ = new Checked ((Block) $2);
5226           }
5227         ;
5228
5229 unchecked_statement
5230         : UNCHECKED block
5231           {
5232                 $$ = new Unchecked ((Block) $2);
5233           }
5234         ;
5235
5236 unsafe_statement
5237         : UNSAFE 
5238           {
5239                 RootContext.CheckUnsafeOption ((Location) $1);
5240           } block {
5241                 $$ = new Unsafe ((Block) $3);
5242           }
5243         ;
5244
5245 fixed_statement
5246         : FIXED open_parens 
5247           type fixed_pointer_declarators 
5248           CLOSE_PARENS
5249           {
5250                 ArrayList list = (ArrayList) $4;
5251                 Expression type = (Expression) $3;
5252                 Location l = (Location) $1;
5253                 int top = list.Count;
5254
5255                 start_block (lexer.Location);
5256
5257                 for (int i = 0; i < top; i++){
5258                         Pair p = (Pair) list [i];
5259                         LocalInfo v;
5260
5261                         v = current_block.AddVariable (type, (string) p.First, l);
5262                         if (v == null)
5263                                 continue;
5264
5265                         v.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
5266                         v.Pinned = true;
5267                         p.First = v;
5268                         list [i] = p;
5269                 }
5270           }
5271           embedded_statement 
5272           {
5273                 Location l = (Location) $1;
5274
5275                 Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
5276
5277                 current_block.AddStatement (f);
5278
5279                 $$ = end_block (lexer.Location);
5280           }
5281         ;
5282
5283 fixed_pointer_declarators
5284         : fixed_pointer_declarator      { 
5285                 ArrayList declarators = new ArrayList (4);
5286                 if ($1 != null)
5287                         declarators.Add ($1);
5288                 $$ = declarators;
5289           }
5290         | fixed_pointer_declarators COMMA fixed_pointer_declarator
5291           {
5292                 ArrayList declarators = (ArrayList) $1;
5293                 if ($3 != null)
5294                         declarators.Add ($3);
5295                 $$ = declarators;
5296           }
5297         ;
5298
5299 fixed_pointer_declarator
5300         : IDENTIFIER ASSIGN expression
5301           {
5302                 LocatedToken lt = (LocatedToken) $1;
5303                 // FIXME: keep location
5304                 $$ = new Pair (lt.Value, $3);
5305           }
5306         | IDENTIFIER
5307           {
5308                 Report.Error (210, ((LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration");
5309                 $$ = null;
5310           }
5311         ;
5312
5313 lock_statement
5314         : LOCK OPEN_PARENS expression CLOSE_PARENS 
5315           {
5316                 //
5317           } 
5318           embedded_statement
5319           {
5320                 $$ = new Lock ((Expression) $3, (Statement) $6, (Location) $1);
5321           }
5322         ;
5323
5324 using_statement
5325         : USING open_parens resource_acquisition CLOSE_PARENS
5326           {
5327                 start_block (lexer.Location);
5328                 Block assign_block = current_block;
5329
5330                 if ($3 is DictionaryEntry){
5331                         DictionaryEntry de = (DictionaryEntry) $3;
5332                         Location l = (Location) $1;
5333
5334                         Expression type = (Expression) de.Key;
5335                         ArrayList var_declarators = (ArrayList) de.Value;
5336
5337                         ArrayList vars = new ArrayList (4);
5338
5339                         foreach (VariableDeclaration decl in var_declarators){
5340
5341                                 LocalInfo vi = current_block.AddVariable (type, decl.identifier, decl.Location);
5342                                 if (vi == null)
5343                                         continue;
5344                                 vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using);
5345
5346                                 Expression expr = decl.expression_or_array_initializer;
5347                                 if (expr == null) {
5348                                         Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
5349                                 }
5350
5351                                 LocalVariableReference var;
5352
5353                                 // Get a writable reference to this read-only variable.
5354                                 var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
5355
5356                                 // This is so that it is not a warning on using variables
5357                                 vi.Used = true;
5358
5359                                 vars.Add (new DictionaryEntry (var, expr));                             
5360
5361                                 // Assign a = new Assign (var, expr, decl.Location);
5362                                 // assign_block.AddStatement (new StatementExpression (a));
5363                         }
5364
5365                         // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
5366                         // It can be referred to as $5 below.
5367                         $$ = new DictionaryEntry (type, vars);
5368                  } else {
5369                         $$ = $3;
5370                  }
5371           } 
5372           embedded_statement
5373           {
5374                 Using u = new Using ($5, (Statement) $6, (Location) $1);
5375                 current_block.AddStatement (u);
5376                 $$ = end_block (lexer.Location);
5377           }
5378         ; 
5379
5380 resource_acquisition
5381         : local_variable_declaration
5382         | expression
5383         ;
5384
5385
5386 // LINQ
5387
5388 query_expression
5389         : first_from_clause
5390           {
5391                 ++lexer.query_parsing;
5392           }
5393           query_body
5394           {
5395                 if (--lexer.query_parsing == 1)
5396                         lexer.query_parsing = 0;
5397                         
5398                 Linq.AQueryClause from = $1 as Linq.AQueryClause;
5399                         
5400                 from.Tail.Next = (Linq.AQueryClause)$3;
5401                 $$ = from;
5402                 
5403                 current_block.SetEndLocation (lexer.Location);
5404                 current_block = current_block.Parent;
5405           }     
5406         ;
5407         
5408 first_from_clause
5409         : FROM IDENTIFIER IN expression
5410           {
5411                 current_block = new Linq.QueryBlock (current_block, GetLocation ($1));
5412                 LocatedToken lt = (LocatedToken) $2;
5413                 
5414                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, lt.Value, lt.Location);
5415                 $$ = new Linq.QueryExpression (lt, new Linq.QueryStartClause ((Expression)$4));
5416           }
5417         | FROM type IDENTIFIER IN expression
5418           {
5419                 current_block = new Linq.QueryBlock (current_block, GetLocation ($1));
5420                 LocatedToken lt = (LocatedToken) $3;
5421
5422                 Expression type = (Expression)$2;
5423                 current_block.AddVariable (type, lt.Value, lt.Location);
5424                 $$ = new Linq.QueryExpression (lt, new Linq.Cast (type, (Expression)$5));
5425           }
5426         ;
5427         
5428 from_clause
5429         : FROM IDENTIFIER IN expression
5430           {
5431                 LocatedToken lt = (LocatedToken) $2;
5432                 
5433                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance,
5434                         lt.Value, lt.Location);
5435                         
5436                 $$ = new Linq.SelectMany (lt, (Expression)$4);                  
5437           }
5438         | FROM type IDENTIFIER IN expression
5439           {
5440                 LocatedToken lt = (LocatedToken) $3;
5441
5442                 Expression type = (Expression)$2;
5443                 current_block.AddVariable (type, lt.Value, lt.Location);
5444                 $$ = new Linq.SelectMany (lt, new Linq.Cast (type, (Expression)$5));
5445           }
5446         ;       
5447
5448 query_body
5449         : opt_query_body_clauses select_or_group_clause opt_query_continuation
5450           {
5451                 Linq.AQueryClause head = (Linq.AQueryClause)$2;
5452                 
5453                 if ($3 != null)
5454                         head.Next = (Linq.AQueryClause)$3;
5455                                 
5456                 if ($1 != null) {
5457                         Linq.AQueryClause clause = (Linq.AQueryClause)$1;
5458                         clause.Tail.Next = head;
5459                         head = clause;
5460                 }
5461                 
5462                 $$ = head;
5463           }
5464         ;
5465         
5466 select_or_group_clause
5467         : SELECT expression
5468           {
5469                 $$ = new Linq.Select ((Expression)$2, GetLocation ($1));
5470           }
5471         | GROUP expression BY expression
5472           {
5473             $$ = new Linq.GroupBy ((Expression)$2, (Expression)$4, GetLocation ($1));
5474           }
5475         ;
5476         
5477 opt_query_body_clauses
5478         : /* empty */
5479         | query_body_clauses
5480         ;
5481         
5482 query_body_clauses
5483         : query_body_clause
5484         | query_body_clauses query_body_clause
5485           {
5486                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
5487                 $$ = $1;
5488           }
5489         ;
5490         
5491 query_body_clause
5492         : from_clause
5493         | let_clause
5494         | where_clause
5495         | join_clause
5496         | orderby_clause
5497         ;
5498         
5499 let_clause
5500         : LET IDENTIFIER ASSIGN expression
5501           {
5502                 LocatedToken lt = (LocatedToken) $2;
5503                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance,
5504                         lt.Value, lt.Location);   
5505                 $$ = new Linq.Let (lt, (Expression)$4, GetLocation ($1));
5506           }
5507         ;
5508
5509 where_clause
5510         : WHERE boolean_expression
5511           {
5512                 $$ = new Linq.Where ((Expression)$2, GetLocation ($1));
5513           }
5514         ;
5515         
5516 join_clause
5517         : JOIN IDENTIFIER IN expression ON expression EQUALS expression opt_join_into
5518           {
5519                 Location loc = GetLocation ($1);
5520                 LocatedToken lt = (LocatedToken) $2;
5521                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance,
5522                         lt.Value, lt.Location);
5523                 
5524                 if ($9 == null) {
5525                         $$ = new Linq.Join (lt, (Expression)$4, (Expression)$6,
5526                                 (Expression)$8, loc);
5527                 } else {
5528                         LocatedToken lt_into = (LocatedToken) $9;
5529                         $$ = new Linq.GroupJoin (lt, (Expression)$4, (Expression)$6,
5530                                 (Expression)$8, lt_into, loc);
5531                 }
5532           }
5533         | JOIN type IDENTIFIER IN expression ON expression EQUALS expression opt_join_into
5534           {
5535                 Location loc = GetLocation ($1);
5536                 LocatedToken lt = (LocatedToken) $3;
5537                 current_block.AddVariable ((Expression)$2, lt.Value, lt.Location);
5538                 
5539                 Linq.Cast cast = new Linq.Cast ((Expression)$2, (Expression)$5);
5540                 if ($10 == null) {
5541                         $$ = new Linq.Join (lt, cast, (Expression)$7,
5542                                 (Expression)$9, loc);
5543                 } else {
5544                         LocatedToken lt_into = (LocatedToken) $10;
5545                         $$ = new Linq.GroupJoin (lt, cast, (Expression)$7,
5546                                 (Expression)$9, lt_into, loc);
5547                 }
5548           }
5549         ;
5550         
5551 opt_join_into
5552         : /* empty */
5553         | INTO IDENTIFIER
5554           {
5555                 $$ = $2;
5556           }
5557         ;
5558         
5559 orderby_clause
5560         : ORDERBY orderings
5561           {
5562                 $$ = $2;
5563           }
5564         ;
5565         
5566 orderings
5567         : order_by
5568         | order_by COMMA orderings_then_by
5569           {
5570                 ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$3;
5571                 $$ = $1;
5572           }
5573         ;
5574         
5575 orderings_then_by
5576         : then_by
5577           {
5578                 $$ = $1;
5579           }
5580         | orderings_then_by COMMA then_by
5581           {
5582                 ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$3;
5583                 $$ = $1;
5584           }
5585         ;       
5586         
5587 order_by
5588         : expression
5589           {
5590                 $$ = new Linq.OrderByAscending ((Expression)$1);        
5591           }
5592         | expression ASCENDING
5593           {
5594                 $$ = new Linq.OrderByAscending ((Expression)$1);        
5595           }
5596         | expression DESCENDING
5597           {
5598                 $$ = new Linq.OrderByDescending ((Expression)$1);       
5599           }
5600         ;
5601
5602 then_by
5603         : expression
5604           {
5605                 $$ = new Linq.ThenByAscending ((Expression)$1); 
5606           }
5607         | expression ASCENDING
5608           {
5609                 $$ = new Linq.ThenByAscending ((Expression)$1); 
5610           }
5611         | expression DESCENDING
5612           {
5613                 $$ = new Linq.ThenByDescending ((Expression)$1);        
5614           }     
5615         ;
5616
5617
5618 opt_query_continuation
5619         : /* empty */
5620         | INTO IDENTIFIER
5621           {
5622                 // query continuation block is not linked with query block but with block
5623                 // before. This means each query can use same range variable names for
5624                 // different identifiers.
5625
5626                 current_block.SetEndLocation (GetLocation ($1));
5627                 current_block = current_block.Parent;
5628                 current_block = new Linq.QueryBlock (current_block, GetLocation ($1));
5629                 
5630                 LocatedToken lt = (LocatedToken) $2;
5631                 current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance,
5632                         lt.Value, lt.Location);
5633           }
5634           query_body
5635           {
5636                 $$ = new Linq.QueryExpression ((LocatedToken) $2,
5637                         (Linq.AQueryClause)$4);
5638           }
5639         ;
5640         
5641 %%
5642
5643 // <summary>
5644 //   A class used to pass around variable declarations and constants
5645 // </summary>
5646 public class VariableDeclaration {
5647         public string identifier;
5648         public Expression expression_or_array_initializer;
5649         public Location Location;
5650         public Attributes OptAttributes;
5651         public string DocComment;
5652
5653         public VariableDeclaration (LocatedToken lt, object eoai, Attributes opt_attrs)
5654         {
5655                 this.identifier = lt.Value;
5656                 if (eoai is ArrayList) {
5657                         this.expression_or_array_initializer = new ArrayCreation (CSharpParser.current_array_type, "", (ArrayList)eoai, lt.Location);
5658                 } else {
5659                         this.expression_or_array_initializer = (Expression)eoai;
5660                 }
5661                 this.Location = lt.Location;
5662                 this.OptAttributes = opt_attrs;
5663         }
5664
5665         public VariableDeclaration (LocatedToken lt, object eoai) : this (lt, eoai, null)
5666         {
5667         }
5668 }
5669
5670 // <summary>
5671 //   A class used to hold info about an indexer declarator
5672 // </summary>
5673 public class IndexerDeclaration {
5674         public Expression type;
5675         public MemberName interface_type;
5676         public Parameters param_list;
5677         public Location location;
5678
5679         public IndexerDeclaration (Expression type, MemberName interface_type,
5680                                    Parameters param_list, Location loc)
5681         {
5682                 this.type = type;
5683                 this.interface_type = interface_type;
5684                 this.param_list = param_list;
5685                 this.location = loc;
5686         }
5687 }
5688
5689 //
5690 // We use this when we do not have an object in advance that is an IAnonymousHost
5691 //
5692 public class SimpleAnonymousHost : IAnonymousHost {
5693         public static readonly SimpleAnonymousHost Simple = new SimpleAnonymousHost ();
5694
5695         bool yields;
5696         ArrayList anonymous_methods;
5697
5698         public static SimpleAnonymousHost GetSimple () {
5699                 Simple.yields = false;
5700                 Simple.anonymous_methods = null;
5701                 return Simple;
5702         }
5703
5704         public void SetYields ()
5705         {
5706                 yields = true;
5707         }
5708
5709         public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
5710         {
5711                 if (anonymous_methods == null)
5712                         anonymous_methods = new ArrayList ();
5713                 anonymous_methods.Add (anonymous);
5714         }
5715
5716         public void Propagate (IAnonymousHost real_host)
5717         {
5718                 if (yields)
5719                         real_host.SetYields ();
5720                 if (anonymous_methods != null) {
5721                         foreach (AnonymousMethodExpression ame in anonymous_methods)
5722                                 real_host.AddAnonymousMethod (ame);
5723                 }
5724         }
5725 }
5726
5727 // <summary>
5728 //  A class used to hold info about an operator declarator
5729 // </summary>
5730 struct OperatorDeclaration {
5731         public readonly Operator.OpType optype;
5732         public readonly Expression ret_type;
5733         public readonly Location location;
5734
5735         public OperatorDeclaration (Operator.OpType op, Expression ret_type, Location location)
5736         {
5737                 optype = op;
5738                 this.ret_type = ret_type;
5739                 this.location = location;
5740         }
5741 }
5742
5743 void Error_ExpectingTypeName (Expression expr)
5744 {
5745         if (expr is Invocation){
5746                 Report.Error (1002, expr.Location, "Expecting `;'");
5747         } else {
5748                 expr.Error_InvalidExpressionStatement ();
5749         }
5750 }
5751
5752 static void Error_ParameterModifierNotValid (string modifier, Location loc)
5753 {
5754         Report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
5755                                       modifier);
5756 }
5757
5758 static void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
5759 {
5760         Report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
5761                 Parameter.GetModifierSignature (mod));
5762 }
5763
5764 static void Error_TypeExpected (Location loc)
5765 {
5766         Report.Error (1031, loc, "Type expected");
5767 }
5768
5769 void push_current_class (TypeContainer tc, object partial_token)
5770 {
5771         if (partial_token != null)
5772                 current_container = current_container.AddPartial (tc);
5773         else
5774                 current_container = current_container.AddTypeContainer (tc);
5775         current_class = tc;
5776 }
5777
5778 DeclSpace pop_current_class ()
5779 {
5780         DeclSpace retval = current_class;
5781
5782         current_class = current_class.Parent;
5783         current_container = current_class.PartialContainer;
5784
5785         return retval;
5786 }
5787
5788 // <summary>
5789 //   Given the @class_name name, it creates a fully qualified name
5790 //   based on the containing declaration space
5791 // </summary>
5792 MemberName
5793 MakeName (MemberName class_name)
5794 {
5795         Namespace ns = current_namespace.NS;
5796
5797         if (current_container.Name.Length == 0){
5798                 if (ns.Name.Length != 0)
5799                         return new MemberName (ns.MemberName, class_name);
5800                 else
5801                         return class_name;
5802         } else {
5803                 return new MemberName (current_container.MemberName, class_name);
5804         }
5805 }
5806
5807 Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
5808 {
5809         Block implicit_block;
5810         ArrayList inits = null;
5811
5812         //
5813         // We use the `Used' property to check whether statements
5814         // have been added to the current block.  If so, we need
5815         // to create another block to contain the new declaration
5816         // otherwise, as an optimization, we use the same block to
5817         // add the declaration.
5818         //
5819         // FIXME: A further optimization is to check if the statements
5820         // that were added were added as part of the initialization
5821         // below.  In which case, no other statements have been executed
5822         // and we might be able to reduce the number of blocks for
5823         // situations like this:
5824         //
5825         // int j = 1;  int k = j + 1;
5826         //
5827         if (current_block.Used)
5828                 implicit_block = new Block (current_block, loc, Location.Null);
5829         else
5830                 implicit_block = current_block;
5831
5832         foreach (VariableDeclaration decl in variable_declarators){
5833
5834                 if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) {
5835                         if (decl.expression_or_array_initializer != null){
5836                                 if (inits == null)
5837                                         inits = new ArrayList (4);
5838                                 inits.Add (decl);
5839                         }
5840                 }
5841         }
5842
5843         if (inits == null)
5844                 return implicit_block;
5845
5846         foreach (VariableDeclaration decl in inits){
5847                 Assign assign;
5848                 Expression expr = decl.expression_or_array_initializer;
5849                 
5850                 LocalVariableReference var;
5851                 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
5852
5853                 assign = new Assign (var, expr, decl.Location);
5854
5855                 implicit_block.AddStatement (new StatementExpression (assign));
5856         }
5857         
5858         return implicit_block;
5859 }
5860
5861 Block declare_local_constants (Expression type, ArrayList declarators)
5862 {
5863         Block implicit_block;
5864
5865         if (current_block.Used)
5866                 implicit_block = new Block (current_block);
5867         else
5868                 implicit_block = current_block;
5869
5870         foreach (VariableDeclaration decl in declarators){
5871                 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer, decl.Location);
5872         }
5873         
5874         return implicit_block;
5875 }
5876
5877 string CheckAttributeTarget (string a, Location l)
5878 {
5879         switch (a) {
5880         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
5881                         return a;
5882         }
5883
5884         Report.Warning (658, 1, l,
5885                  "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
5886         return string.Empty;
5887 }
5888
5889 static bool IsUnaryOperator (Operator.OpType op)
5890 {
5891         switch (op) {
5892                 
5893         case Operator.OpType.LogicalNot: 
5894         case Operator.OpType.OnesComplement: 
5895         case Operator.OpType.Increment:
5896         case Operator.OpType.Decrement:
5897         case Operator.OpType.True: 
5898         case Operator.OpType.False: 
5899         case Operator.OpType.UnaryPlus: 
5900         case Operator.OpType.UnaryNegation:
5901                 return true;
5902         }
5903         return false;
5904 }
5905
5906 void syntax_error (Location l, string msg)
5907 {
5908         Report.Error (1003, l, "Syntax error, " + msg);
5909 }
5910
5911 void note (string s)
5912 {
5913         // Used to put annotations
5914 }
5915
5916 Tokenizer lexer;
5917
5918 public Tokenizer Lexer {
5919         get {
5920                 return lexer;
5921         }
5922 }                  
5923
5924 static CSharpParser ()
5925 {
5926         oob_stack = new Stack ();
5927 }
5928
5929 public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
5930 {
5931         this.name = file.Name;
5932         this.file = file;
5933         current_namespace = new NamespaceEntry (null, file, null);
5934         current_class = current_namespace.SlaveDeclSpace;
5935         current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
5936         oob_stack.Clear ();
5937         lexer = new Tokenizer (reader, file, defines);
5938 }
5939
5940 public void parse ()
5941 {
5942         int errors = Report.Errors;
5943         try {
5944                 if (yacc_verbose_flag > 1)
5945                         yyparse (lexer, new yydebug.yyDebugSimple ());
5946                 else
5947                         yyparse (lexer);
5948                 Tokenizer tokenizer = lexer as Tokenizer;
5949                 tokenizer.cleanup ();
5950         } catch (Exception e){
5951                 //
5952                 // Removed for production use, use parser verbose to get the output.
5953                 //
5954                 // Console.WriteLine (e);
5955                 if (Report.Errors == errors)
5956                         Report.Error (-25, lexer.Location, "Parsing error");
5957                 if (yacc_verbose_flag > 0)
5958                         Console.WriteLine (e);
5959         }
5960
5961         if (RootContext.ToplevelTypes.NamespaceEntry != null)
5962                 throw new InternalErrorException ("who set it?");
5963 }
5964
5965 static void CheckToken (int error, int yyToken, string msg, Location loc)
5966 {
5967         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
5968                 Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ());
5969         else
5970                 Report.Error (error, loc, msg);
5971 }
5972
5973 void CheckIdentifierToken (int yyToken, Location loc)
5974 {
5975         CheckToken (1041, yyToken, "Identifier expected", loc);
5976 }
5977
5978 string ConsumeStoredComment ()
5979 {
5980         string s = tmpComment;
5981         tmpComment = null;
5982         Lexer.doc_state = XmlCommentState.Allowed;
5983         return s;
5984 }
5985
5986 Location GetLocation (object obj)
5987 {
5988         if (obj is MemberCore)
5989                 return ((MemberCore) obj).Location;
5990         if (obj is MemberName)
5991                 return ((MemberName) obj).Location;
5992         if (obj is LocatedToken)
5993                 return ((LocatedToken) obj).Location;
5994         if (obj is Location)
5995                 return (Location) obj;
5996         return lexer.Location;
5997 }
5998
5999 void start_block (Location loc)
6000 {
6001         if (current_block == null || parsing_anonymous_method) {
6002                 current_block = new ToplevelBlock (current_block, current_local_parameters, current_generic_method, loc);
6003                 parsing_anonymous_method = false;
6004         } else {
6005                 current_block = new ExplicitBlock (current_block, loc, Location.Null);
6006         }
6007 }
6008
6009 Block
6010 end_block (Location loc)
6011 {
6012         Block retval = current_block.Explicit;
6013         retval.SetEndLocation (loc);
6014         current_block = retval.Parent;
6015         return retval;
6016 }
6017
6018 void
6019 start_anonymous (bool lambda, Parameters parameters, Location loc)
6020 {
6021         oob_stack.Push (current_anonymous_method);
6022         oob_stack.Push (current_local_parameters);
6023
6024         current_local_parameters = parameters;
6025
6026         ToplevelBlock top_current_block = current_block == null ? null : current_block.Toplevel;
6027
6028         current_anonymous_method = lambda 
6029                 ? new LambdaExpression (
6030                         current_anonymous_method, current_generic_method, current_container,
6031                         parameters, top_current_block, loc) 
6032                 : new AnonymousMethodExpression (
6033                         current_anonymous_method, current_generic_method, current_container,
6034                         parameters, top_current_block, loc);
6035
6036         // Force the next block to be created as a ToplevelBlock
6037         parsing_anonymous_method = true;
6038 }
6039
6040 /*
6041  * Completes the anonymous method processing, if lambda_expr is null, this
6042  * means that we have a Statement instead of an Expression embedded 
6043  */
6044 AnonymousMethodExpression 
6045 end_anonymous (ToplevelBlock anon_block, Location loc)
6046 {
6047         AnonymousMethodExpression retval;
6048
6049         if (RootContext.Version == LanguageVersion.ISO_1){
6050                 Report.FeatureIsNotAvailable (loc, "anonymous methods");
6051                 retval = null;
6052         } else  {
6053                 current_anonymous_method.Block = anon_block;
6054                 if ((anonymous_host != null) && (current_anonymous_method.Parent == null))
6055                         anonymous_host.AddAnonymousMethod (current_anonymous_method);
6056
6057                 retval = current_anonymous_method;
6058         }
6059
6060         current_local_parameters = (Parameters) oob_stack.Pop ();
6061         current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
6062
6063         return retval;
6064 }
6065
6066 /* end end end */
6067 }