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