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