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