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