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