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