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