Use Mono_IsInflatedMethod.
[mono.git] / mcs / gmcs / cs-parser.jay
1 %{
2 //
3 // cs-parser.jay: The Parser for the C# compiler
4 //
5 // Authors: Miguel de Icaza (miguel@gnu.org)
6 //          Ravi Pratap     (ravi@ximian.com)
7 //
8 // Licensed under the terms of the GNU GPL
9 //
10 // (C) 2001 Ximian, Inc (http://www.ximian.com)
11 //
12 // TODO:
13 //   (1) Figure out why error productions dont work.  `type-declaration' is a
14 //       great spot to put an `error' because you can reproduce it with this input:
15 //       "public X { }"
16 //
17 // Possible optimization:
18 //   Run memory profiler with parsing only, and consider dropping 
19 //   arraylists where not needed.   Some pieces can use linked lists.
20 //
21 using System.Text;
22 using System.IO;
23 using System;
24
25 namespace Mono.CSharp
26 {
27         using System.Collections;
28
29         /// <summary>
30         ///    The C# Parser
31         /// </summary>
32         public class CSharpParser {
33                 NamespaceEntry  current_namespace;
34                 TypeContainer   current_container;
35         
36                 IIteratorContainer iterator_container;
37
38                 /// <summary>
39                 ///   Current block is used to add statements as we find
40                 ///   them.  
41                 /// </summary>
42
43                 Block      current_block;
44
45                 /// <summary>
46                 ///   If true, creates a toplevel block in the block production
47                 ///   This is flagged by the delegate creation
48                 /// </summary>
49                 bool       create_toplevel_block;
50
51                 /// <summary>
52                 /// <summary>
53                 ///   Current interface is used by the various declaration
54                 ///   productions in the interface declaration to "add"
55                 ///   the interfaces as we find them.
56                 /// </summary>
57                 Interface  current_interface;
58
59                 Delegate   current_delegate;
60
61                 /// <summary>
62                 ///   This is used by the unary_expression code to resolve
63                 ///   a name against a parameter.  
64                 /// </summary>
65                 Parameters current_local_parameters;
66
67                 /// <summary>
68                 ///   Using during property parsing to describe the implicit
69                 ///   value parameter that is passed to the "set" and "get"accesor
70                 ///   methods (properties and indexers).
71                 /// </summary>
72                 Expression implicit_value_parameter_type;
73                 Parameters indexer_parameters;
74
75                 /// <summary>
76                 ///   Used to determine if we are parsing the get/set pair
77                 ///   of an indexer or a property
78                 /// </summmary>
79                 bool  parsing_indexer;
80
81                 ///
82                 /// An out-of-band stack.
83                 ///
84                 Stack oob_stack;
85
86                 ///
87                 /// Switch stack.
88                 ///
89                 Stack switch_stack;
90
91                 public bool yacc_verbose_flag;
92
93                 // Name of the file we are parsing
94                 public string name;
95
96                 ///
97                 /// The current file.
98                 ///
99                 SourceFile file;
100 %}
101
102 %token EOF
103 %token NONE   /* This token is never returned by our lexer */
104 %token ERROR            // This is used not by the parser, but by the tokenizer.
105                         // do not remove.
106
107 /*
108  *These are the C# keywords
109  */
110 %token FIRST_KEYWORD
111 %token ABSTRACT 
112 %token AS
113 %token ADD
114 %token ASSEMBLY
115 %token BASE     
116 %token BOOL     
117 %token BREAK    
118 %token BYTE     
119 %token CASE     
120 %token CATCH    
121 %token CHAR     
122 %token CHECKED  
123 %token CLASS    
124 %token CONST    
125 %token CONTINUE 
126 %token DECIMAL  
127 %token DEFAULT  
128 %token DELEGATE 
129 %token DO       
130 %token DOUBLE   
131 %token ELSE     
132 %token ENUM     
133 %token EVENT    
134 %token EXPLICIT 
135 %token EXTERN   
136 %token FALSE    
137 %token FINALLY  
138 %token FIXED    
139 %token FLOAT    
140 %token FOR      
141 %token FOREACH  
142 %token GOTO     
143 %token IF       
144 %token IMPLICIT 
145 %token IN       
146 %token INT      
147 %token INTERFACE
148 %token INTERNAL 
149 %token IS       
150 %token LOCK     
151 %token LONG     
152 %token NAMESPACE
153 %token NEW      
154 %token NULL     
155 %token OBJECT   
156 %token OPERATOR 
157 %token OUT      
158 %token OVERRIDE 
159 %token PARAMS   
160 %token PRIVATE  
161 %token PROTECTED
162 %token PUBLIC   
163 %token READONLY 
164 %token REF      
165 %token RETURN   
166 %token REMOVE
167 %token SBYTE    
168 %token SEALED   
169 %token SHORT    
170 %token SIZEOF   
171 %token STACKALLOC
172 %token STATIC   
173 %token STRING   
174 %token STRUCT   
175 %token SWITCH   
176 %token THIS     
177 %token THROW    
178 %token TRUE     
179 %token TRY      
180 %token TYPEOF   
181 %token UINT     
182 %token ULONG    
183 %token UNCHECKED
184 %token UNSAFE   
185 %token USHORT   
186 %token USING    
187 %token VIRTUAL  
188 %token VOID     
189 %token VOLATILE
190 %token WHERE
191 %token WHILE    
192
193 /* C# keywords which are not really keywords */
194 %token GET           "get"
195 %token SET           "set"
196
197 %left LAST_KEYWORD
198
199 /* C# single character operators/punctuation. */
200 %token OPEN_BRACE    "{"
201 %token CLOSE_BRACE   "}"
202 %token OPEN_BRACKET  "["
203 %token CLOSE_BRACKET "]"
204 %token OPEN_PARENS   "("
205 %token CLOSE_PARENS  ")"
206 %token DOT           "."
207 %token COMMA         ","
208 %token COLON         ":"
209 %token SEMICOLON     ";"
210 %token TILDE         "~"
211
212 %token PLUS           "+"
213 %token MINUS          "-"
214 %token BANG           "!"
215 %token ASSIGN         "="
216 %token OP_LT          "<"
217 %token OP_GENERICS_LT "<"
218 %token OP_GT          ">"
219 %token OP_GENERICS_GT ">"
220 %token BITWISE_AND    "&"
221 %token BITWISE_OR     "|"
222 %token STAR           "*"
223 %token PERCENT        "%"
224 %token DIV            "/"
225 %token CARRET         "^"
226 %token INTERR         "?"
227
228 /* C# multi-character operators. */
229 %token OP_INC                 "++"
230 %token OP_DEC                 "--"
231 %token OP_SHIFT_LEFT          "<<"
232 %token OP_SHIFT_RIGHT         ">>"
233 %token OP_LE                  "<="
234 %token OP_GE                  ">="
235 %token OP_EQ                  "=="
236 %token OP_NE                  "!="
237 %token OP_AND                 "&&"
238 %token OP_OR                  "||"
239 %token OP_MULT_ASSIGN         "*="
240 %token OP_DIV_ASSIGN          "/="
241 %token OP_MOD_ASSIGN          "%="
242 %token OP_ADD_ASSIGN          "+="
243 %token OP_SUB_ASSIGN          "-="
244 %token OP_SHIFT_LEFT_ASSIGN   "<<="
245 %token OP_SHIFT_RIGHT_ASSIGN  ">>="
246 %token OP_AND_ASSIGN          "&="
247 %token OP_XOR_ASSIGN          "^="
248 %token OP_OR_ASSIGN           "|="
249 %token OP_PTR                 "->"
250
251 /* Numbers */
252 %token LITERAL_INTEGER           "int literal"
253 %token LITERAL_FLOAT             "float literal"
254 %token LITERAL_DOUBLE            "double literal"
255 %token LITERAL_DECIMAL           "decimal literal"
256 %token LITERAL_CHARACTER         "character literal"
257 %token LITERAL_STRING            "string literal"
258
259 %token IDENTIFIER
260 %token CLOSE_PARENS_CAST
261 %token CLOSE_PARENS_NO_CAST
262 %token CLOSE_PARENS_OPEN_PARENS
263 %token CLOSE_PARENS_MINUS
264 %token DEFAULT_OPEN_PARENS
265
266 /* Add precedence rules to solve dangling else s/r conflict */
267 %nonassoc LOWPREC
268 %nonassoc IF
269 %nonassoc ELSE
270 %right ASSIGN
271 %left OP_OR
272 %left OP_AND
273 %left BITWISE_OR
274 %left BITWISE_AND
275 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
276 %left PLUS MINUS
277 %left STAR DIV PERCENT
278 %right BANG CARRET UMINUS
279 %nonassoc OP_INC OP_DEC
280 %left OPEN_PARENS
281 %left OPEN_BRACKET OPEN_BRACE
282 %left DOT
283 %nonassoc HIGHPREC
284
285 %start compilation_unit
286 %%
287
288 compilation_unit
289         : outer_declarations opt_EOF
290         | outer_declarations attribute_sections opt_EOF
291         | attribute_sections opt_EOF
292         | opt_EOF /* allow empty files */
293         ;
294         
295 opt_EOF
296         : /* empty */
297         | EOF
298         ;
299
300 outer_declarations
301         : outer_declaration
302         | outer_declarations outer_declaration
303         ;
304  
305 outer_declaration
306         : using_directive
307         | namespace_member_declaration
308         ;
309   
310 using_directives
311         : using_directive 
312         | using_directives using_directive
313         ;
314
315 using_directive
316         : using_alias_directive
317         | using_namespace_directive
318         ;
319
320 using_alias_directive
321         : USING IDENTIFIER ASSIGN 
322           namespace_or_type_name SEMICOLON
323           {
324                 Expression expr = ((MemberName) $4).GetTypeExpression (lexer.Location);
325                 current_namespace.UsingAlias ((string) $2, expr, lexer.Location);
326           }
327         | USING error {
328                 CheckIdentifierToken (yyToken);
329           }
330         ;
331
332 using_namespace_directive
333         : USING namespace_name SEMICOLON 
334           {
335                 current_namespace.Using ((string) $2, lexer.Location);
336           }
337         ;
338
339 //
340 // Strictly speaking, namespaces don't have attributes but
341 // we parse global attributes along with namespace declarations and then
342 // detach them
343 // 
344 namespace_declaration
345         : opt_attributes NAMESPACE namespace_name
346         {
347                 Attributes attrs = (Attributes) $1;
348
349                 if (attrs != null) {
350                         foreach (AttributeSection asec in attrs.AttributeSections)
351                                 if (asec.Target == "assembly")
352                                         CodeGen.Assembly.AddAttribute (current_container, asec);
353                                 else
354                                         Report.Error(1518, Lexer.Location,
355                                         "Attributes cannot be applied to namespaces."
356                                         + " Expected class, delegate, enum, interface, or struct");
357                 }
358
359                 current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3, lexer.Location);
360         } 
361           namespace_body opt_semicolon
362           { 
363                 current_namespace = current_namespace.Parent;
364           }
365         ;
366
367 opt_semicolon
368         : /* empty */
369         | SEMICOLON
370         ;
371
372 opt_comma
373         : /* empty */
374         | COMMA
375         ;
376
377 namespace_name
378         : namespace_or_type_name {
379                 MemberName name = (MemberName) $1;
380
381                 if (name.TypeArguments != null)
382                         syntax_error (lexer.Location, "namespace name expected");
383
384                 $$ = name.GetName ();
385           }
386         ;
387
388 namespace_body
389         : OPEN_BRACE
390           opt_using_directives
391           opt_namespace_member_declarations
392           CLOSE_BRACE
393           {
394           }
395         ;
396
397 opt_using_directives
398         : /* empty */
399         | using_directives
400         ;
401
402 opt_namespace_member_declarations
403         : /* empty */
404         | namespace_member_declarations
405         ;
406
407 namespace_member_declarations
408         : namespace_member_declaration
409         | namespace_member_declarations namespace_member_declaration
410         ;
411
412 namespace_member_declaration
413         : type_declaration
414           {
415                 string name = "";
416                 int mod_flags;
417
418                 if ($1 is Class){
419                         Class c = (Class) $1;
420                         mod_flags = c.ModFlags;
421                         name = c.Name;
422                 } else if ($1 is Struct){
423                         Struct s = (Struct) $1;
424                         mod_flags = s.ModFlags;
425                         name = s.Name;
426                 } else
427                         break;
428
429                 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
430                         Report.Error (
431                                 1527, lexer.Location, 
432                                 "Namespace elements cant be explicitly " +
433                                 "declared private or protected in `" + name + "'");
434                 }
435                 current_namespace.DeclarationFound = true;
436           }
437         | namespace_declaration {
438                 current_namespace.DeclarationFound = true;
439           }
440
441         | field_declaration {
442                 Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations");
443           }
444         | method_declaration {
445                 Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations");
446           }
447         ;
448
449 type_declaration
450         : class_declaration             
451         | struct_declaration            
452         | interface_declaration         
453         | enum_declaration              
454         | delegate_declaration
455 //
456 // Enable this when we have handled all errors, because this acts as a generic fallback
457 //
458 //      | error {
459 //              Console.WriteLine ("Token=" + yyToken);
460 //              Report.Error (1518, lexer.Location, "Expected class, struct, interface, enum or delegate");
461 //        }
462         ;
463
464 //
465 // Attributes 17.2
466 //
467
468 opt_attributes
469         : /* empty */
470         | attribute_sections { $$ = $1; }
471         ;
472  
473 attribute_sections
474         : attribute_section
475           {
476                 AttributeSection sect = (AttributeSection) $1;
477
478                 if (sect.Target == "assembly") {
479                         CodeGen.Assembly.AddAttribute (current_container, sect);
480                         $$ = null;
481                 }
482                 else if (sect.Target == "module") {
483                         CodeGen.Module.AddAttribute (current_container, sect);
484                         $$ = null;
485                 }
486                 else
487                         $$ = new Attributes (sect);
488           }
489         | attribute_sections attribute_section
490           {
491                 Attributes attrs = $1 as Attributes;
492                 AttributeSection sect = (AttributeSection) $2;
493
494                 if (sect.Target == "assembly") {
495                         CodeGen.Assembly.AddAttribute (current_container, sect);
496                 }
497                 else if (sect.Target == "module") {
498                         CodeGen.Module.AddAttribute (current_container, sect);
499                 }
500                 else {
501                         if (attrs == null)
502                                 attrs = new Attributes (sect);
503                         else
504                         attrs.AddAttributeSection (sect);
505                 }
506                 
507                 $$ = attrs;
508           }
509         ;
510
511 attribute_section
512         : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
513           {
514                 string target = null;
515                 
516                 if ($2 != null)
517                         target = (string) $2;
518                 
519                 $$ = new AttributeSection (target, (ArrayList) $3);
520           }
521         | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
522           {
523                 $$ = new AttributeSection (null, (ArrayList) $2);
524           }
525         ;
526  
527 attribute_target_specifier
528         : attribute_target COLON
529           {
530                 $$ = $1;
531           }
532         ;
533
534 attribute_target
535         : IDENTIFIER
536           {
537                 CheckAttributeTarget ((string) $1);
538                 $$ = $1;
539           }
540         | EVENT  { $$ = "event"; }        
541         | RETURN { $$ = "return"; }
542         ;
543
544 attribute_list
545         : attribute
546           {
547                 ArrayList attrs = new ArrayList (4);
548                 attrs.Add ($1);
549
550                 $$ = attrs;
551                
552           }
553         | attribute_list COMMA attribute
554           {
555                 ArrayList attrs = (ArrayList) $1;
556                 attrs.Add ($3);
557
558                 $$ = attrs;
559           }
560         ;
561
562 attribute
563         : attribute_name
564           {
565                 $$ = lexer.Location;
566           }
567           opt_attribute_arguments
568           {
569                 //
570                 // Attributes need a string, not an expression: generic types will fail here.
571                 //
572                 $$ = new Attribute (((Expression) $1).ToString (), (ArrayList) $3, (Location) $2);
573           }
574         ;
575
576 attribute_name
577         : type_name  { /* reserved attribute name or identifier: 17.4 */ }
578         ;
579
580 opt_attribute_arguments
581         : /* empty */   { $$ = null; }
582         | OPEN_PARENS attribute_arguments CLOSE_PARENS
583           {
584                 $$ = $2;
585           }
586         ;
587
588
589 attribute_arguments
590         : opt_positional_argument_list
591           {
592                 if ($1 == null)
593                         $$ = null;
594                 else {
595                         ArrayList args = new ArrayList (4);
596                         args.Add ($1);
597                 
598                         $$ = args;
599                 }
600           }
601         | positional_argument_list COMMA named_argument_list
602           {
603                 ArrayList args = new ArrayList (4);
604                 args.Add ($1);
605                 args.Add ($3);
606
607                 $$ = args;
608           }
609         | named_argument_list
610           {
611                 ArrayList args = new ArrayList (4);
612                 args.Add (null);
613                 args.Add ($1);
614                 
615                 $$ = args;
616           }
617         ;
618
619
620 opt_positional_argument_list
621         : /* empty */           { $$ = null; } 
622         | positional_argument_list
623         ;
624
625 positional_argument_list
626         : expression
627           {
628                 ArrayList args = new ArrayList (4);
629                 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
630
631                 $$ = args;
632           }
633         | positional_argument_list COMMA expression
634          {
635                 ArrayList args = (ArrayList) $1;
636                 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
637
638                 $$ = args;
639          }
640         ;
641
642 named_argument_list
643         : named_argument
644           {
645                 ArrayList args = new ArrayList (4);
646                 args.Add ($1);
647
648                 $$ = args;
649           }
650         | named_argument_list COMMA named_argument
651           {       
652                 ArrayList args = (ArrayList) $1;
653                 args.Add ($3);
654
655                 $$ = args;
656           }
657         ;
658
659 named_argument
660         : IDENTIFIER ASSIGN expression
661           {
662                 $$ = new DictionaryEntry (
663                         (string) $1, 
664                         new Argument ((Expression) $3, Argument.AType.Expression));
665           }
666         ;
667
668                   
669 class_body
670         :  OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
671         ;
672
673 opt_class_member_declarations
674         : /* empty */
675         | class_member_declarations
676         ;
677
678 class_member_declarations
679         : class_member_declaration
680         | class_member_declarations 
681           class_member_declaration
682         ;
683
684 class_member_declaration
685         : constant_declaration                  // done
686         | field_declaration                     // done
687         | method_declaration                    // done
688         | property_declaration                  // done
689         | event_declaration                     // done
690         | indexer_declaration                   // done
691         | operator_declaration                  // done
692         | constructor_declaration               // done
693         | destructor_declaration                // done
694         | type_declaration
695         ;
696
697 struct_declaration
698         : opt_attributes
699           opt_modifiers
700           STRUCT IDENTIFIER
701           { 
702                 Struct new_struct;
703                 string full_struct_name = MakeName ((string) $4);
704
705                 new_struct = new Struct (current_namespace, current_container, full_struct_name,
706                                          (int) $2, (Attributes) $1, lexer.Location);
707                 current_container = new_struct;
708                 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
709                 lexer.ConstraintsParsing = true;
710           }
711           opt_type_parameter_list
712           opt_class_base
713           opt_type_parameter_constraints_clauses
714           {
715                 lexer.ConstraintsParsing = false;
716           }
717           struct_body
718           opt_semicolon
719           {
720                 Struct new_struct = (Struct) current_container;
721
722                 if ($8 != null && $6 == null)
723                         Report.Error (80, lexer.Location,
724                                       "Contraints are not allowed on non-generic declarations");
725                 if ($6 != null)
726                         CheckDef (new_struct.SetParameterInfo ((ArrayList) $6, (ArrayList) $8), new_struct.Name, new_struct.Location);
727
728                 if ($7 != null)
729                         new_struct.Bases = (ArrayList) $7;
730
731                 current_container = current_container.Parent;
732                 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
733                 $$ = new_struct;
734           }
735         | opt_attributes opt_modifiers STRUCT error {
736                 CheckIdentifierToken (yyToken);
737           }
738         ;
739
740 struct_body
741         : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE
742         ;
743
744 opt_struct_member_declarations
745         : /* empty */
746         | struct_member_declarations
747         ;
748
749 struct_member_declarations
750         : struct_member_declaration
751         | struct_member_declarations struct_member_declaration
752         ;
753
754 struct_member_declaration
755         : constant_declaration
756         | field_declaration
757         | method_declaration
758         | property_declaration
759         | event_declaration
760         | indexer_declaration
761         | operator_declaration
762         | constructor_declaration
763         | type_declaration
764
765         /*
766          * This is only included so we can flag error 575: 
767          * destructors only allowed on class types
768          */
769         | destructor_declaration 
770         ;
771
772 constant_declaration
773         : opt_attributes 
774           opt_modifiers
775           CONST
776           type
777           constant_declarators
778           SEMICOLON
779           {
780                 foreach (VariableDeclaration constant in (ArrayList) $5){
781                         Location l = constant.Location;
782
783                         Const c = new Const (
784                                 (Expression) $4, (string) constant.identifier, 
785                                 (Expression) constant.expression_or_array_initializer, (int) $2, 
786                                 (Attributes) $1, l);
787
788                         CheckDef (current_container.AddConstant (c), c.Name, l);
789                 }
790           }
791         ;
792
793 constant_declarators
794         : constant_declarator 
795           {
796                 ArrayList constants = new ArrayList (4);
797                 constants.Add ($1);
798                 $$ = constants;
799           }
800         | constant_declarators COMMA constant_declarator
801           {
802                 ArrayList constants = (ArrayList) $1;
803
804                 constants.Add ($3);
805           }
806         ;
807
808 constant_declarator
809         : IDENTIFIER ASSIGN constant_expression
810           {
811                 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
812           }
813         ;
814
815 field_declaration
816         : opt_attributes
817           opt_modifiers
818           type 
819           variable_declarators
820           SEMICOLON
821           { 
822                 Expression type = (Expression) $3;
823                 int mod = (int) $2;
824
825                 foreach (VariableDeclaration var in (ArrayList) $4){
826                         Location l = var.Location;
827
828                         Field field = new Field (type, mod, var.identifier, 
829                                                  var.expression_or_array_initializer, 
830                                                  (Attributes) $1, l);
831
832                         CheckDef (current_container.AddField (field), field.Name, l);
833                 }
834           }
835         | opt_attributes
836           opt_modifiers
837           VOID  
838           variable_declarators
839           SEMICOLON {
840                 Report.Error (670, lexer.Location, "void type is not allowed for fields");
841           }
842         ;
843
844 variable_declarators
845         : variable_declarator 
846           {
847                 ArrayList decl = new ArrayList (4);
848                 decl.Add ($1);
849                 $$ = decl;
850           }
851         | variable_declarators COMMA variable_declarator
852           {
853                 ArrayList decls = (ArrayList) $1;
854                 decls.Add ($3);
855                 $$ = $1;
856           }
857         ;
858
859 variable_declarator
860         : IDENTIFIER ASSIGN variable_initializer
861           {
862                 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
863           }
864         | IDENTIFIER
865           {
866                 $$ = new VariableDeclaration ((string) $1, null, lexer.Location);
867           }
868         ;
869
870 variable_initializer
871         : expression
872           {
873                 $$ = $1;
874           }
875         | array_initializer
876           {
877                 $$ = $1;
878           }
879         | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
880           {
881                 $$ = new StackAlloc ((Expression) $2, (Expression) $4, lexer.Location);
882           }
883         ;
884
885 method_declaration
886         : method_header {
887                 iterator_container = (IIteratorContainer) $1;
888           }
889           method_body
890           {
891                 Method method = (Method) $1;
892                 Block b = (Block) $3;
893                 const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
894
895                 if (b == null){
896                         if ((method.ModFlags & extern_abstract) == 0){
897                                 Report.Error (
898                                         501, lexer.Location,  current_container.MakeName (method.Name) +
899                                         "must declare a body because it is not marked abstract or extern");
900                         }
901                 } else {
902                         if ((method.ModFlags & Modifiers.EXTERN) != 0){
903                                 Report.Error (
904                                         179, lexer.Location, current_container.MakeName (method.Name) +
905                                         " is declared extern, but has a body");
906                         }
907                 }
908
909                 method.Block = (Block) $3;
910                 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
911
912                 current_local_parameters = null;
913                 iterator_container = null;
914           }
915         ;
916
917 opt_error_modifier
918         : /* empty */
919         | modifiers 
920           {
921                 int m = (int) $1;
922                 int i = 1;
923
924                 while (m != 0){
925                         if ((i & m) != 0){
926                                 Report.Error (
927                                         1585, lexer.Location, "Member modifier `" + 
928                                         Modifiers.Name (i) + "' must precede member type and name");
929                         }
930                         m &= ~i;
931                         i = i << 1;
932                 }
933           }
934         ;
935
936 method_header
937         : opt_attributes
938           opt_modifiers
939           type
940           namespace_or_type_name
941           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
942           {
943                 lexer.ConstraintsParsing = true;
944           }
945           opt_type_parameter_constraints_clauses
946           {
947                 lexer.ConstraintsParsing = false;
948
949                 MemberName name = (MemberName) $4;
950
951                 if ($9 != null && name.TypeArguments == null)
952                         Report.Error (80, lexer.Location,
953                                       "Contraints are not allowed on non-generic declarations");
954
955                 Method method;
956
957                 GenericMethod generic = null;
958                 if (name.TypeArguments != null) {
959                         generic = new GenericMethod (current_namespace, current_container,
960                                                      name.Name, (Attributes) $1,
961                                                      lexer.Location);
962
963                         CheckDef (generic.SetParameterInfo (name.TypeArguments, (ArrayList) $9), name.Name, lexer.Location);
964
965                         method = new Method (generic, (Expression) $3, (int) $2, false, name,
966                                              (Parameters) $6, (Attributes) $1, lexer.Location);
967                 } else
968                         method = new Method (current_container, (Expression) $3, (int) $2,
969                                              false, name, (Parameters) $6, (Attributes) $1,
970                                              lexer.Location);
971
972                 current_local_parameters = (Parameters) $6;
973
974                 $$ = method;
975           }
976         | opt_attributes
977           opt_modifiers
978           VOID
979           namespace_or_type_name
980           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
981           {
982                 lexer.ConstraintsParsing = true;
983           }
984           opt_type_parameter_constraints_clauses
985           {
986                 lexer.ConstraintsParsing = false;
987
988                 MemberName name = (MemberName) $4;
989
990                 if ($9 != null && name.TypeArguments == null)
991                         Report.Error (80, lexer.Location,
992                                       "Contraints are not allowed on non-generic declarations");
993
994                 Method method;
995                 GenericMethod generic = null;
996                 if (name.TypeArguments != null) {
997                         generic = new GenericMethod (current_namespace, current_container,
998                                                      name.Name, (Attributes) $1,
999                                                      lexer.Location);
1000
1001
1002                         CheckDef (generic.SetParameterInfo (name.TypeArguments, (ArrayList) $9), name.Name, lexer.Location);
1003
1004                         method = new Method (generic, TypeManager.system_void_expr, (int) $2,
1005                                              false, name, (Parameters) $6, (Attributes) $1,
1006                                              lexer.Location);
1007                 } else
1008                         method = new Method (current_container, TypeManager.system_void_expr,
1009                                              (int) $2, false, name, (Parameters) $6,
1010                                              (Attributes) $1, lexer.Location);
1011
1012                 current_local_parameters = (Parameters) $6;
1013
1014                 $$ = method;
1015           }
1016         | opt_attributes
1017           opt_modifiers
1018           type 
1019           modifiers namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1020           {
1021                 Report.Error (1585, lexer.Location, 
1022                         String.Format ("Modifier {0} should appear before type", 
1023                                 Modifiers.Name ((int) $4)));
1024                 Method method = new Method (current_container, TypeManager.system_void_expr,
1025                                             0, false, (MemberName) $5, (Parameters) $6,
1026                                             (Attributes) $1, lexer.Location);
1027
1028                 current_local_parameters = (Parameters) $6;
1029                 $$ = method;
1030           }
1031         ;
1032
1033 method_body
1034         : block
1035         | SEMICOLON             { $$ = null; }
1036         ;
1037
1038 opt_formal_parameter_list
1039         : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
1040         | formal_parameter_list
1041         ;
1042
1043 formal_parameter_list
1044         : fixed_parameters              
1045           { 
1046                 ArrayList pars_list = (ArrayList) $1;
1047
1048                 Parameter [] pars = new Parameter [pars_list.Count];
1049                 pars_list.CopyTo (pars);
1050
1051                 $$ = new Parameters (pars, null, lexer.Location); 
1052           } 
1053         | fixed_parameters COMMA parameter_array
1054           {
1055                 ArrayList pars_list = (ArrayList) $1;
1056
1057                 Parameter [] pars = new Parameter [pars_list.Count];
1058                 pars_list.CopyTo (pars);
1059
1060                 $$ = new Parameters (pars, (Parameter) $3, lexer.Location); 
1061           }
1062         | parameter_array 
1063           {
1064                 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1065           }
1066         ;
1067
1068 fixed_parameters
1069         : fixed_parameter       
1070           {
1071                 ArrayList pars = new ArrayList (4);
1072
1073                 pars.Add ($1);
1074                 $$ = pars;
1075           }
1076         | fixed_parameters COMMA fixed_parameter
1077           {
1078                 ArrayList pars = (ArrayList) $1;
1079
1080                 pars.Add ($3);
1081                 $$ = $1;
1082           }
1083         ;
1084
1085 fixed_parameter
1086         : opt_attributes
1087           opt_parameter_modifier
1088           type
1089           IDENTIFIER
1090           {
1091                 $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
1092           }
1093         | opt_attributes
1094           opt_parameter_modifier
1095           type
1096           error {
1097                 CheckIdentifierToken (yyToken);
1098                 $$ = null;
1099           }
1100         ;
1101
1102 opt_parameter_modifier
1103         : /* empty */           { $$ = Parameter.Modifier.NONE; }
1104         | parameter_modifier
1105         ;
1106
1107 parameter_modifier
1108         : REF                   { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
1109         | OUT                   { $$ = Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF; }
1110         ;
1111
1112 parameter_array
1113         : opt_attributes PARAMS type IDENTIFIER
1114           { 
1115                 $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
1116                 note ("type must be a single-dimension array type"); 
1117           }
1118         | opt_attributes PARAMS type error {
1119                 CheckIdentifierToken (yyToken);
1120                 $$ = null;
1121           }
1122         ;
1123
1124 property_declaration
1125         : opt_attributes
1126           opt_modifiers
1127           type namespace_or_type_name
1128           OPEN_BRACE 
1129           {
1130                 implicit_value_parameter_type = (Expression) $3;
1131
1132                 lexer.PropertyParsing = true;
1133
1134                 $$ = lexer.Location;
1135
1136                 iterator_container = SimpleIteratorContainer.GetSimple ();
1137           }
1138           accessor_declarations 
1139           {
1140                 lexer.PropertyParsing = false;
1141           }
1142           CLOSE_BRACE
1143           { 
1144                 Property prop;
1145                 Pair pair = (Pair) $7;
1146                 Accessor get_block = (Accessor) pair.First;
1147                 Accessor set_block = (Accessor) pair.Second;
1148
1149                 MemberName name = (MemberName) $4;
1150                 if (name.TypeArguments != null)
1151                         syntax_error (lexer.Location, "a property can't have type arguments");
1152
1153                 Location loc = (Location) $6;
1154                 prop = new Property (current_container, (Expression) $3, (int) $2, false,
1155                                      name, (Attributes) $1, get_block, set_block, loc);
1156                 if (SimpleIteratorContainer.Simple.Yields)
1157                         prop.SetYields ();
1158                 
1159                 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1160                 implicit_value_parameter_type = null;
1161                 iterator_container = null;
1162           }
1163         ;
1164
1165 accessor_declarations
1166         : get_accessor_declaration opt_set_accessor_declaration
1167           { 
1168                 $$ = new Pair ($1, $2);
1169           }
1170         | set_accessor_declaration opt_get_accessor_declaration
1171           {
1172                 $$ = new Pair ($2, $1);
1173           }
1174         ;
1175
1176 opt_get_accessor_declaration
1177         : /* empty */                   { $$ = null; }
1178         | get_accessor_declaration
1179         ;
1180
1181 opt_set_accessor_declaration
1182         : /* empty */                   { $$ = null; }
1183         | set_accessor_declaration
1184         ;
1185
1186 get_accessor_declaration
1187         : opt_attributes GET
1188           {
1189                 // If this is not the case, then current_local_parameters has already
1190                 // been set in indexer_declaration
1191                 if (parsing_indexer == false)
1192                         current_local_parameters = null;
1193                 else 
1194                         current_local_parameters = indexer_parameters;
1195                 lexer.PropertyParsing = false;
1196           }
1197           accessor_body
1198           {
1199                 $$ = new Accessor ((Block) $4, (Attributes) $1);
1200                 current_local_parameters = null;
1201                 lexer.PropertyParsing = true;
1202           }
1203         ;
1204
1205 set_accessor_declaration
1206         : opt_attributes SET 
1207           {
1208                 Parameter [] args;
1209                 Parameter implicit_value_parameter = new Parameter (
1210                         implicit_value_parameter_type, "value", 
1211                         Parameter.Modifier.NONE, null);
1212
1213                 if (parsing_indexer == false) {
1214                         args  = new Parameter [1];
1215                         args [0] = implicit_value_parameter;
1216                         current_local_parameters = new Parameters (args, null, lexer.Location);
1217                 } else {
1218                         Parameter [] fpars = indexer_parameters.FixedParameters;
1219
1220                         if (fpars != null){
1221                                 int count = fpars.Length;
1222
1223                                 args = new Parameter [count + 1];
1224                                 fpars.CopyTo (args, 0);
1225                                 args [count] = implicit_value_parameter;
1226                         } else 
1227                                 args = null;
1228                         current_local_parameters = new Parameters (
1229                                 args, indexer_parameters.ArrayParameter, lexer.Location);
1230                 }
1231                 
1232                 lexer.PropertyParsing = false;
1233           }
1234           accessor_body
1235           {
1236                 $$ = new Accessor ((Block) $4, (Attributes) $1);
1237                 current_local_parameters = null;
1238                 lexer.PropertyParsing = true;
1239           }
1240         ;
1241
1242 accessor_body
1243         : block 
1244         | SEMICOLON             { $$ = null; }
1245         ;
1246
1247 interface_declaration
1248         : opt_attributes
1249           opt_modifiers
1250           INTERFACE IDENTIFIER
1251           {
1252                 Interface new_interface;
1253                 string full_interface_name = MakeName ((string) $4);
1254
1255                 new_interface = new Interface (current_namespace, current_container, full_interface_name,
1256                                                (int) $2, (Attributes) $1, lexer.Location);
1257                 if (current_interface != null) {
1258                         Location l = lexer.Location;
1259                         Report.Error (-2, l, "Internal compiler error: interface inside interface");
1260                 }
1261                 current_interface = new_interface;
1262                 current_container = new_interface;
1263                 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1264                 lexer.ConstraintsParsing = true;
1265           }
1266           opt_type_parameter_list
1267           opt_class_base
1268           opt_type_parameter_constraints_clauses
1269           {
1270                 lexer.ConstraintsParsing = false;
1271           }
1272           interface_body opt_semicolon
1273           { 
1274                 Interface new_interface = (Interface) current_interface;
1275
1276                 if ($8 != null && $6 == null)
1277                         Report.Error (80, lexer.Location,
1278                                       "Contraints are not allowed on non-generic declarations");
1279                 if ($6 != null)
1280                         CheckDef (new_interface.SetParameterInfo ((ArrayList) $6, (ArrayList) $8), new_interface.Name, new_interface.Location);
1281                 if ($7 != null)
1282                         new_interface.Bases = (ArrayList) $7;
1283
1284                 current_interface = null;
1285                 current_container = current_container.Parent;
1286                 CheckDef (current_container.AddInterface (new_interface), 
1287                           new_interface.Name, new_interface.Location);
1288           }
1289         | opt_attributes opt_modifiers INTERFACE error {
1290                 CheckIdentifierToken (yyToken);
1291           }
1292         ;
1293
1294 interface_body
1295         : OPEN_BRACE
1296           opt_interface_member_declarations
1297           CLOSE_BRACE
1298         ;
1299
1300 opt_interface_member_declarations
1301         : /* empty */
1302         | interface_member_declarations
1303         ;
1304
1305 interface_member_declarations
1306         : interface_member_declaration
1307         | interface_member_declarations interface_member_declaration
1308         ;
1309
1310 interface_member_declaration
1311         : interface_method_declaration          
1312           { 
1313                 Method m = (Method) $1;
1314
1315                 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1316           }
1317         | interface_property_declaration        
1318           { 
1319                 Property p = (Property) $1;
1320
1321                 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1322           }
1323         | interface_event_declaration 
1324           { 
1325                 if ($1 != null){
1326                         Event e = (Event) $1;
1327                         CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1328                 }
1329           }
1330         | interface_indexer_declaration
1331           { 
1332                 Indexer i = (Indexer) $1;
1333
1334                 current_interface.AddIndexer (i);
1335           }
1336         ;
1337
1338 opt_new
1339         : opt_modifiers 
1340           {
1341                 int val = (int) $1;
1342                 val = Modifiers.Check (Modifiers.NEW | Modifiers.UNSAFE, val, 0, lexer.Location);
1343                 $$ = val;
1344           }
1345         ;
1346
1347 interface_method_declaration
1348         : opt_attributes opt_new type IDENTIFIER 
1349           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1350           SEMICOLON
1351           {
1352                 $$ = new Method (current_container, (Expression) $3, (int) $2, true,
1353                                  new MemberName ((string) $4), (Parameters) $6,
1354                                  (Attributes) $1, lexer.Location);
1355           }
1356         | opt_attributes opt_new VOID IDENTIFIER 
1357           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1358           SEMICOLON
1359           {
1360                 $$ = new Method (current_container, TypeManager.system_void_expr, (int) $2,
1361                                  true, new MemberName ((string) $4), (Parameters) $6,
1362                                  (Attributes) $1, lexer.Location);
1363           }
1364         ;
1365
1366 interface_property_declaration
1367         : opt_attributes
1368           opt_new
1369           type IDENTIFIER 
1370           OPEN_BRACE 
1371           { lexer.PropertyParsing = true; }
1372           interface_accessors 
1373           { lexer.PropertyParsing = false; }
1374           CLOSE_BRACE
1375           {
1376                 InterfaceAccessorInfo pinfo = (InterfaceAccessorInfo) $7;
1377
1378                 $$ = new Property (current_container, (Expression) $3, (int) $2, true,
1379                                    new MemberName ((string) $4), (Attributes) $1,
1380                                    pinfo.Get, pinfo.Set, lexer.Location);
1381           }
1382         | opt_attributes
1383           opt_new
1384           type error {
1385                 CheckIdentifierToken (yyToken);
1386                 $$ = null;
1387           }
1388         ;
1389
1390 interface_accessors
1391         : opt_attributes GET SEMICOLON          { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null); }
1392         | opt_attributes SET SEMICOLON          { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1); }
1393         | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON 
1394           { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $3); }
1395         | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON
1396           { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $3, (Attributes) $1); }
1397         ;
1398
1399 interface_event_declaration
1400         : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
1401           {
1402                 $$ = new Event ((Expression) $4, (int) $2, true,
1403                                  new MemberName ((string) $5), null,
1404                                 (Attributes) $1, null, null, lexer.Location);
1405           }
1406         | opt_attributes opt_new EVENT type error {
1407                 CheckIdentifierToken (yyToken);
1408                 $$ = null;
1409           }
1410         | opt_attributes opt_new EVENT type IDENTIFIER ASSIGN  {
1411                 Report.Error (68, lexer.Location, "Event declarations on interfaces can not be initialized.");
1412                 $$ = null;
1413           }
1414         | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE event_accessor_declarations CLOSE_BRACE {
1415                 Report.Error (69, lexer.Location, "Event accessors not valid on interfaces");
1416                 $$ = null;
1417           }
1418         ;
1419
1420 interface_indexer_declaration 
1421         : opt_attributes opt_new type THIS 
1422           OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
1423           OPEN_BRACE 
1424           { lexer.PropertyParsing = true; }
1425           interface_accessors 
1426           { lexer.PropertyParsing = false; }
1427           CLOSE_BRACE
1428           {
1429                 InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10;
1430
1431                 $$ = new Indexer (current_container, (Expression) $3, (int) $2, true,
1432                                   MemberName.Null, (Parameters) $6, (Attributes) $1,
1433                                   info.Get, info.Set, lexer.Location);
1434           }
1435         ;
1436
1437 operator_declaration
1438         : opt_attributes opt_modifiers operator_declarator 
1439           {
1440                 iterator_container = SimpleIteratorContainer.GetSimple ();
1441           }
1442           operator_body
1443           {
1444                 OperatorDeclaration decl = (OperatorDeclaration) $3;
1445                 
1446                 Operator op = new Operator (decl.optype, decl.ret_type, (int) $2, decl.arg1type, decl.arg1name,
1447                                             decl.arg2type, decl.arg2name, (Block) $5, (Attributes) $1, decl.location);
1448
1449                 if (SimpleIteratorContainer.Simple.Yields)
1450                         op.SetYields ();
1451
1452                 // Note again, checking is done in semantic analysis
1453                 current_container.AddOperator (op);
1454
1455                 current_local_parameters = null;
1456                 iterator_container = null;
1457           }
1458         ;
1459
1460 operator_body 
1461         : block
1462         | SEMICOLON { $$ = null; }
1463         ; 
1464 operator_declarator
1465         : type OPERATOR overloadable_operator 
1466           OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1467         {
1468                 Operator.OpType op = (Operator.OpType) $3;
1469                 CheckUnaryOperator (op);
1470
1471                 if (op == Operator.OpType.Addition)
1472                         op = Operator.OpType.UnaryPlus;
1473
1474                 if (op == Operator.OpType.Subtraction)
1475                         op = Operator.OpType.UnaryNegation;
1476
1477                 Parameter [] pars = new Parameter [1];
1478
1479                 pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
1480
1481                 current_local_parameters = new Parameters (pars, null, lexer.Location);
1482
1483                 $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6,
1484                                               null, null, lexer.Location);
1485         }
1486         | type OPERATOR overloadable_operator
1487           OPEN_PARENS 
1488                 type IDENTIFIER COMMA
1489                 type IDENTIFIER 
1490           CLOSE_PARENS
1491         {
1492                CheckBinaryOperator ((Operator.OpType) $3);
1493
1494                Parameter [] pars = new Parameter [2];
1495
1496                pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
1497                pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null);
1498
1499                current_local_parameters = new Parameters (pars, null, lexer.Location);
1500                
1501                $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1, 
1502                                              (Expression) $5, (string) $6,
1503                                              (Expression) $8, (string) $9, lexer.Location);
1504         }
1505         | conversion_operator_declarator
1506         ;
1507
1508 overloadable_operator
1509 // Unary operators:
1510         : BANG   { $$ = Operator.OpType.LogicalNot; }
1511         | TILDE  { $$ = Operator.OpType.OnesComplement; }  
1512         | OP_INC { $$ = Operator.OpType.Increment; }
1513         | OP_DEC { $$ = Operator.OpType.Decrement; }
1514         | TRUE   { $$ = Operator.OpType.True; }
1515         | FALSE  { $$ = Operator.OpType.False; }
1516 // Unary and binary:
1517         | PLUS { $$ = Operator.OpType.Addition; }
1518         | MINUS { $$ = Operator.OpType.Subtraction; }
1519 // Binary:
1520         | STAR { $$ = Operator.OpType.Multiply; }
1521         | DIV {  $$ = Operator.OpType.Division; }
1522         | PERCENT { $$ = Operator.OpType.Modulus; }
1523         | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
1524         | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
1525         | CARRET { $$ = Operator.OpType.ExclusiveOr; }
1526         | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
1527         | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
1528         | OP_EQ { $$ = Operator.OpType.Equality; }
1529         | OP_NE { $$ = Operator.OpType.Inequality; }
1530         | OP_GT { $$ = Operator.OpType.GreaterThan; }
1531         | OP_LT { $$ = Operator.OpType.LessThan; }
1532         | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
1533         | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
1534         ;
1535
1536 conversion_operator_declarator
1537         : IMPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1538           {
1539                 Parameter [] pars = new Parameter [1];
1540
1541                 pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
1542
1543                 current_local_parameters = new Parameters (pars, null, lexer.Location);  
1544                   
1545                 $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, (Expression) $5, (string) $6,
1546                                               null, null, lexer.Location);
1547           }
1548         | EXPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1549           {
1550                 Parameter [] pars = new Parameter [1];
1551
1552                 pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
1553
1554                 current_local_parameters = new Parameters (pars, null, lexer.Location);  
1555                   
1556                 $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, (Expression) $5, (string) $6,
1557                                               null, null, lexer.Location);
1558           }
1559         | IMPLICIT error 
1560           {
1561                 syntax_error (lexer.Location, "'operator' expected");
1562           }
1563         | EXPLICIT error 
1564           {
1565                 syntax_error (lexer.Location, "'operator' expected");
1566           }
1567         ;
1568
1569 constructor_declaration
1570         : opt_attributes
1571           opt_modifiers
1572           constructor_declarator
1573           constructor_body
1574           { 
1575                 Constructor c = (Constructor) $3;
1576                 c.Block = (Block) $4;
1577                 c.OptAttributes = (Attributes) $1;
1578                 c.ModFlags = (int) $2;
1579         
1580                 if (c.Name == current_container.Basename){
1581                         if ((c.ModFlags & Modifiers.STATIC) != 0){
1582                                 if ((c.ModFlags & Modifiers.Accessibility) != 0){
1583                                         Report.Error (
1584                                                 515, c.Location, String.Format (
1585                                                 "`{0}.{1}': static constructor can not have access modifiers",
1586                                                 c.Name, current_container.Name));
1587                                 }
1588         
1589                                 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);   
1590         
1591                                 if (c.Initializer != null){
1592                                         Report.Error (
1593                                                 514, c.Location, 
1594                                                 "Static constructors can not have an explicit this or base " +
1595                                                 "constructor invocations");
1596                                 }
1597         
1598                                 if (!c.Parameters.Empty){
1599                                         Report.Error (
1600                                                 132, c.Location, "Static constructors should not have parameters");
1601                                 }
1602                         } else {
1603                                 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
1604                         }
1605                 } else {
1606                         // We let another layer check the validity of the constructor.
1607                         Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename);
1608                 }
1609
1610                 CheckDef (current_container.AddConstructor (c), c.Name, c.Location);
1611
1612                 current_local_parameters = null;
1613           }
1614         ;
1615
1616 constructor_declarator
1617         : IDENTIFIER 
1618           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
1619           {
1620                 oob_stack.Push (lexer.Location);
1621
1622                 current_local_parameters = (Parameters) $3;
1623           }
1624           opt_constructor_initializer
1625           {
1626                 Location l = (Location) oob_stack.Pop ();
1627                 $$ = new Constructor (current_container, (string) $1, 0, (Parameters) $3,
1628                                       (ConstructorInitializer) $6, l);
1629           }
1630         ;
1631
1632 constructor_body
1633         : block
1634         | SEMICOLON             { $$ = null; }
1635         ;
1636
1637 opt_constructor_initializer
1638         : /* empty */                   { $$ = null; }
1639         | constructor_initializer
1640         ;
1641
1642 constructor_initializer
1643         : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
1644           {
1645                 $$ = new ConstructorBaseInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
1646           }
1647         | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
1648           {
1649                 $$ = new ConstructorThisInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
1650           }
1651         | COLON error {
1652                 Report.Error (1018, lexer.Location, "Keyword this or base expected");
1653                 $$ = null;
1654           }
1655         ;
1656
1657 opt_finalizer
1658         : /* EMPTY */           { $$ = 0; }
1659         | UNSAFE                { $$ = Modifiers.UNSAFE; }
1660         | EXTERN                { $$ = Modifiers.EXTERN; }
1661         ;
1662         
1663 destructor_declaration
1664         : opt_attributes opt_finalizer TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
1665           {
1666                 if ((string) $4 != current_container.Basename){
1667                         Report.Error (574, lexer.Location, "Name of destructor must match name of class");
1668                 } else if (!(current_container is Class)){
1669                         Report.Error (575, lexer.Location, "Destructors are only allowed in class types");
1670                 } else {
1671                         Location l = lexer.Location;
1672
1673                         int m = (int) $2;
1674                         if (!RootContext.StdLib && current_container.Name == "System.Object")
1675                                 m |= Modifiers.PROTECTED | Modifiers.VIRTUAL;
1676                         else
1677                                 m |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
1678                         
1679                         if ((m & Modifiers.UNSAFE) != 0){
1680                                 if (!RootContext.Unsafe){
1681                                         Report.Error (227, l,
1682                                               "Unsafe code requires the --unsafe command " +
1683                                               "line option to be specified");
1684                                 }
1685                         }
1686                         
1687                         Method d = new Destructor (
1688                                 current_container, TypeManager.system_void_expr, m, "Finalize", 
1689                                 new Parameters (null, null, l), (Attributes) $1, l);
1690                   
1691                         d.Block = (Block) $7;
1692                         CheckDef (current_container.AddMethod (d), d.Name, d.Location);
1693                 }
1694           }
1695         ;
1696
1697 event_declaration
1698         : opt_attributes
1699           opt_modifiers
1700           EVENT type variable_declarators SEMICOLON
1701           {
1702                 foreach (VariableDeclaration var in (ArrayList) $5) {
1703
1704                         MemberName name = new MemberName (var.identifier);
1705
1706                         Event e = new Event ((Expression) $4, (int) $2, false, name,
1707                                              var.expression_or_array_initializer,
1708                                              (Attributes) $1, null, null, lexer.Location);
1709
1710                         CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1711                                        
1712                 }
1713           }
1714         | opt_attributes
1715           opt_modifiers
1716           EVENT type namespace_or_type_name
1717           OPEN_BRACE
1718           {
1719                 implicit_value_parameter_type = (Expression) $4;  
1720                 lexer.EventParsing = true;
1721                 oob_stack.Push (lexer.Location);
1722           }
1723           event_accessor_declarations
1724           {
1725                 lexer.EventParsing = false;  
1726           }
1727           CLOSE_BRACE
1728           {
1729                 Location loc = (Location) oob_stack.Pop ();
1730
1731                 if ($8 == null){
1732                         Report.Error (65, lexer.Location, "Event must have both add and remove accesors");
1733                         $$ = null;
1734                 } else {
1735                 Pair pair = (Pair) $8;
1736                 Accessor add_accessor = null;
1737                 Accessor rem_accessor = null;
1738
1739                 if (pair.First != null)
1740                         add_accessor = (Accessor) pair.First;
1741                 if (pair.Second != null)
1742                         rem_accessor = (Accessor) pair.Second;
1743
1744                 MemberName name = (MemberName) $5;
1745                 if (name.TypeArguments != null)
1746                         syntax_error (lexer.Location, "an event can't have type arguments");
1747
1748                 Event e = new Event ((Expression) $4, (int) $2, false, name, null,
1749                                      (Attributes) $1, add_accessor, rem_accessor, loc);
1750                 
1751                 CheckDef (current_container.AddEvent (e), e.Name, loc);
1752                 implicit_value_parameter_type = null;
1753           }
1754           }
1755         ;
1756
1757 event_accessor_declarations
1758         : add_accessor_declaration remove_accessor_declaration
1759         {
1760                 $$ = new Pair ($1, $2);
1761         }
1762         | remove_accessor_declaration add_accessor_declaration
1763         {
1764                 $$ = new Pair ($2, $1);
1765         }       
1766         | add_accessor_declaration  { $$ = null; } 
1767         | remove_accessor_declaration { $$ = null; } 
1768         ;
1769
1770 add_accessor_declaration
1771         : opt_attributes ADD
1772           {
1773                 Parameter [] args = new Parameter [1];
1774                 Parameter implicit_value_parameter = new Parameter (
1775                         implicit_value_parameter_type, "value", 
1776                         Parameter.Modifier.NONE, null);
1777
1778                 args [0] = implicit_value_parameter;
1779                 
1780                 current_local_parameters = new Parameters (args, null, lexer.Location);  
1781                 lexer.EventParsing = false;
1782           }
1783           block
1784           {
1785                 $$ = new Accessor ((Block) $4, (Attributes) $1);
1786                 lexer.EventParsing = true;
1787           }
1788         | opt_attributes ADD error {
1789                 Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
1790                 $$ = null;
1791           }
1792         ;
1793
1794 remove_accessor_declaration
1795         : opt_attributes REMOVE
1796           {
1797                 Parameter [] args = new Parameter [1];
1798                 Parameter implicit_value_parameter = new Parameter (
1799                         implicit_value_parameter_type, "value", 
1800                         Parameter.Modifier.NONE, null);
1801
1802                 args [0] = implicit_value_parameter;
1803                 
1804                 current_local_parameters = new Parameters (args, null, lexer.Location);  
1805                 lexer.EventParsing = false;
1806           }
1807           block
1808           {
1809                 $$ = new Accessor ((Block) $4, (Attributes) $1);
1810                 lexer.EventParsing = true;
1811           }
1812         | opt_attributes REMOVE error {
1813                 Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
1814                 $$ = null;
1815           }
1816         ;
1817
1818 indexer_declaration
1819         : opt_attributes opt_modifiers indexer_declarator 
1820           OPEN_BRACE 
1821           {
1822                 IndexerDeclaration decl = (IndexerDeclaration) $3;
1823
1824                 implicit_value_parameter_type = decl.type;
1825                 
1826                 lexer.PropertyParsing = true;
1827                 parsing_indexer  = true;
1828                 
1829                 indexer_parameters = decl.param_list;
1830                 oob_stack.Push (lexer.Location);
1831           }
1832           accessor_declarations 
1833           {
1834                   lexer.PropertyParsing = false;
1835                   parsing_indexer  = false;
1836           }
1837           CLOSE_BRACE
1838           { 
1839                 // The signature is computed from the signature of the indexer.  Look
1840                 // at section 3.6 on the spec
1841                 Location loc = (Location) oob_stack.Pop ();
1842                 Indexer indexer;
1843                 IndexerDeclaration decl = (IndexerDeclaration) $3;
1844                 Pair pair = (Pair) $6;
1845                 Accessor get_block = (Accessor) pair.First;
1846                 Accessor set_block = (Accessor) pair.Second;
1847
1848                 MemberName name;
1849                 if (decl.interface_type != null)
1850                         name = new MemberName (decl.interface_type, "", null);
1851                 else
1852                         name = MemberName.Null;
1853
1854                 indexer = new Indexer (current_container, decl.type, (int) $2, false,
1855                                        name, decl.param_list, (Attributes) $1,
1856                                        get_block, set_block, loc);
1857
1858                 // Note that there is no equivalent of CheckDef for this case
1859                 // We shall handle this in semantic analysis
1860                 
1861                 current_container.AddIndexer (indexer);
1862                 
1863                 current_local_parameters = null;
1864                 implicit_value_parameter_type = null;
1865                 indexer_parameters = null;
1866           }
1867         ;
1868
1869 indexer_declarator
1870         : type THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
1871           {
1872                 Parameters pars = (Parameters) $4;
1873
1874                 if (pars.FixedParameters == null && pars.ArrayParameter == null){
1875                         Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
1876                 }
1877
1878                 $$ = new IndexerDeclaration ((Expression) $1, null, pars);
1879           }
1880         | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
1881           {
1882                 Parameters pars = (Parameters) $6;
1883
1884                 if (pars.FixedParameters == null && pars.ArrayParameter == null){
1885                         Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
1886                 }
1887                 MemberName name = (MemberName) $2;
1888                 if (name.TypeArguments != null)
1889                         syntax_error (lexer.Location, "an indexer can't have type arguments");
1890
1891                 $$ = new IndexerDeclaration ((Expression) $1, name, pars);
1892           }
1893         ;
1894
1895 enum_declaration
1896         : opt_attributes
1897           opt_modifiers
1898           ENUM IDENTIFIER 
1899           opt_enum_base
1900           enum_body
1901           opt_semicolon
1902           { 
1903                 Location enum_location = lexer.Location;
1904
1905                 string full_name = MakeName ((string) $4);
1906                 Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2,
1907                                    full_name, (Attributes) $1, enum_location);
1908                 
1909                 foreach (VariableDeclaration ev in (ArrayList) $6) {
1910                         Location loc = (Location) ev.Location;
1911
1912                         CheckDef (e.AddEnumMember (ev.identifier, 
1913                                                    (Expression) ev.expression_or_array_initializer,
1914                                                    loc, ev.OptAttributes),
1915                                   ev.identifier, loc);
1916                 }
1917
1918                 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1919                 RootContext.Tree.RecordDecl (full_name, e);
1920
1921           }
1922         ;
1923
1924 opt_enum_base
1925         : /* empty */           { $$ = TypeManager.system_int32_expr; }
1926         | COLON type            { $$ = $2;   }
1927         ;
1928
1929 enum_body
1930         : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE
1931           {
1932                 $$ = $2;
1933           }
1934         ;
1935
1936 opt_enum_member_declarations
1937         : /* empty */                   { $$ = new ArrayList (4); }
1938         | enum_member_declarations opt_comma { $$ = $1; }
1939         ;
1940
1941 enum_member_declarations
1942         : enum_member_declaration 
1943           {
1944                 ArrayList l = new ArrayList (4);
1945
1946                 l.Add ($1);
1947                 $$ = l;
1948           }
1949         | enum_member_declarations COMMA enum_member_declaration
1950           {
1951                 ArrayList l = (ArrayList) $1;
1952
1953                 l.Add ($3);
1954
1955                 $$ = l;
1956           }
1957         ;
1958
1959 enum_member_declaration
1960         : opt_attributes IDENTIFIER 
1961           {
1962                 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1963           }
1964         | opt_attributes IDENTIFIER
1965           {
1966                   $$ = lexer.Location;
1967           }
1968           ASSIGN expression
1969           { 
1970                 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1971           }
1972         ;
1973
1974 delegate_declaration
1975         : opt_attributes
1976           opt_modifiers
1977           DELEGATE type IDENTIFIER
1978           opt_type_parameter_list
1979           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1980           {
1981                 Location l = lexer.Location;
1982                 Delegate del = new Delegate (current_namespace, current_container, (Expression) $4,
1983                                              (int) $2, MakeName ((string) $5), (Parameters) $8, 
1984                                              (Attributes) $1, l);
1985                   
1986                 CheckDef (current_container.AddDelegate (del), del.Name, l);
1987
1988                 current_delegate = del;
1989
1990                 lexer.ConstraintsParsing = true;
1991           }
1992           opt_type_parameter_constraints_clauses
1993           {
1994                 lexer.ConstraintsParsing = false;
1995           }
1996           SEMICOLON
1997           {
1998                 if ($11 != null && $6 == null)
1999                         Report.Error (80, lexer.Location,
2000                                       "Contraints are not allowed on non-generic declarations");
2001
2002                 if ($6 != null)
2003                         CheckDef (current_delegate.SetParameterInfo ((ArrayList) $6, (ArrayList) $11), current_delegate.Name, current_delegate.Location);
2004
2005                 current_delegate = null;
2006           }
2007         | opt_attributes
2008           opt_modifiers
2009           DELEGATE VOID IDENTIFIER
2010           opt_type_parameter_list
2011           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
2012           {
2013                 Location l = lexer.Location;
2014                 Delegate del = new Delegate (
2015                         current_namespace, current_container,
2016                         TypeManager.system_void_expr, (int) $2, MakeName ((string) $5), 
2017                         (Parameters) $8, (Attributes) $1, l);
2018
2019                 CheckDef (current_container.AddDelegate (del), del.Name, l);
2020
2021                 current_delegate = del;
2022
2023                 lexer.ConstraintsParsing = true;
2024           }
2025           opt_type_parameter_constraints_clauses
2026           {
2027                 lexer.ConstraintsParsing = false;
2028           }
2029           SEMICOLON
2030           {
2031                 if ($11 != null && $6 == null)
2032                         Report.Error (80, lexer.Location,
2033                                       "Contraints are not allowed on non-generic declarations");
2034
2035                 if ($6 != null)
2036                         CheckDef (current_delegate.SetParameterInfo ((ArrayList) $6, (ArrayList) $11), current_delegate.Name, current_delegate.Location);
2037
2038                 current_delegate = null;
2039           }
2040         ;
2041
2042 type_name
2043         : namespace_or_type_name {
2044                 $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
2045           }
2046         ;
2047
2048 namespace_or_type_name
2049         : IDENTIFIER opt_type_argument_list {
2050                 $$ = new MemberName ((string) $1, (TypeArguments) $2);
2051           }
2052         | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list {
2053                 $$ = new MemberName ((MemberName) $1, (string) $3, (TypeArguments) $4);
2054           }
2055 //      | namespace_or_type_name DOT DEFAULT
2056 //        {
2057 //              $$ = new DefaultValueExpression ((Expression) $1, lexer.Location);
2058 //        }
2059         ;
2060
2061 // 
2062 // TODO:
2063 //   Figure out what to do with the list 
2064 //
2065 opt_type_argument_list
2066         : /* empty */                { $$ = null; } 
2067         | OP_GENERICS_LT type_arguments OP_GENERICS_GT
2068           {
2069                 $$ = $2;
2070           }
2071         ;
2072
2073 type_arguments
2074         : type {
2075                 TypeArguments type_args = new TypeArguments (lexer.Location);
2076                 type_args.Add ((Expression) $1);
2077                 $$ = type_args;
2078           }
2079         | type_arguments COMMA type {
2080                 TypeArguments type_args = (TypeArguments) $1;
2081                 type_args.Add ((Expression) $3);
2082                 $$ = type_args;
2083           }
2084         ;
2085         
2086 /* 
2087  * Before you think of adding a return_type, notice that we have been
2088  * using two rules in the places where it matters (one rule using type
2089  * and another identical one that uses VOID as the return type).  This
2090  * gets rid of a shift/reduce couple
2091  */
2092 type
2093         : type_name {   /* class_type */
2094           }
2095         | builtin_types
2096         | array_type
2097         | pointer_type    
2098         ;
2099
2100
2101 pointer_type
2102         : type STAR
2103           {
2104                 //
2105                 // Note that here only unmanaged types are allowed but we
2106                 // can't perform checks during this phase - we do it during
2107                 // semantic analysis.
2108                 //
2109                 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
2110           }
2111         | VOID STAR
2112           {
2113                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);
2114           }
2115         ;
2116
2117 non_expression_type
2118         : builtin_types 
2119         | non_expression_type rank_specifier
2120           {
2121                 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2122           }
2123         | non_expression_type STAR
2124           {
2125                 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
2126           }
2127         | expression rank_specifiers 
2128           {
2129                 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2130           }
2131         | expression STAR 
2132           {
2133                 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
2134           }
2135         
2136         //
2137         // We need this because the parser will happily go and reduce IDENTIFIER STAR
2138         // through this different path
2139         //
2140         | multiplicative_expression STAR 
2141           {
2142                 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
2143           }
2144         ;
2145
2146 type_list
2147         : type
2148           {
2149                 ArrayList types = new ArrayList (4);
2150
2151                 types.Add ($1);
2152                 $$ = types;
2153           }
2154         | type_list COMMA type
2155           {
2156                 ArrayList types = (ArrayList) $1;
2157
2158                 types.Add ($3);
2159                 $$ = types;
2160           }
2161         ;
2162
2163 /*
2164  * replaces all the productions for isolating the various
2165  * simple types, but we need this to reuse it easily in local_variable_type
2166  */
2167 builtin_types
2168         : OBJECT        { $$ = TypeManager.system_object_expr; }
2169         | STRING        { $$ = TypeManager.system_string_expr; }
2170         | BOOL          { $$ = TypeManager.system_boolean_expr; }
2171         | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
2172         | FLOAT         { $$ = TypeManager.system_single_expr; }
2173         | DOUBLE        { $$ = TypeManager.system_double_expr; }
2174         | integral_type
2175         ;
2176
2177 integral_type
2178         : SBYTE         { $$ = TypeManager.system_sbyte_expr; }
2179         | BYTE          { $$ = TypeManager.system_byte_expr; }
2180         | SHORT         { $$ = TypeManager.system_int16_expr; }
2181         | USHORT        { $$ = TypeManager.system_uint16_expr; }
2182         | INT           { $$ = TypeManager.system_int32_expr; }
2183         | UINT          { $$ = TypeManager.system_uint32_expr; }
2184         | LONG          { $$ = TypeManager.system_int64_expr; }
2185         | ULONG         { $$ = TypeManager.system_uint64_expr; }
2186         | CHAR          { $$ = TypeManager.system_char_expr; }
2187         | VOID          { $$ = TypeManager.system_void_expr; }
2188         ;
2189
2190 interface_type
2191         : type_name
2192         ;
2193
2194 array_type
2195         : type rank_specifiers
2196           {
2197                 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2198           }
2199         ;
2200
2201 //
2202 // Expressions, section 7.5
2203 //
2204 primary_expression
2205         : literal
2206           {
2207                 // 7.5.1: Literals
2208           }
2209  
2210         | type_name
2211           {
2212                 $$ = $1;
2213           }
2214         | parenthesized_expression
2215         | default_value_expression
2216         | member_access
2217         | invocation_expression
2218         | element_access
2219         | this_access
2220         | base_access
2221         | post_increment_expression
2222         | post_decrement_expression
2223         | new_expression
2224         | typeof_expression
2225         | sizeof_expression
2226         | checked_expression
2227         | unchecked_expression
2228         | pointer_member_access
2229         | anonymous_method_expression
2230         ;
2231
2232 literal
2233         : boolean_literal
2234         | integer_literal
2235         | real_literal
2236         | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value); }
2237         | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value); }
2238         | NULL                  { $$ = NullLiteral.Null; }
2239         ;
2240
2241 real_literal
2242         : LITERAL_FLOAT         { $$ = new FloatLiteral ((float) lexer.Value); }
2243         | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value); }
2244         | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value); }
2245         ;
2246
2247 integer_literal
2248         : LITERAL_INTEGER       { 
2249                 object v = lexer.Value;
2250
2251                 if (v is int){
2252                         int i = (int) v;
2253
2254                         if (i == 0)
2255                                 $$ = IntLiteral.Zero;
2256                         else if (i == 1)
2257                                 $$ = IntLiteral.One;
2258                         else
2259                                 $$ = new IntLiteral (i);
2260                 } else if (v is uint)
2261                         $$ = new UIntLiteral ((UInt32) v);
2262                 else if (v is long)
2263                         $$ = new LongLiteral ((Int64) v);
2264                 else if (v is ulong)
2265                         $$ = new ULongLiteral ((UInt64) v);
2266                 else
2267                         Console.WriteLine ("OOPS.  Unexpected result from scanner");
2268           }
2269         ;
2270
2271 boolean_literal
2272         : TRUE                  { $$ = new BoolLiteral (true); }
2273         | FALSE                 { $$ = new BoolLiteral (false); }
2274         ;
2275
2276 parenthesized_expression_0
2277         : OPEN_PARENS expression CLOSE_PARENS
2278           {
2279                 $$ = $2;
2280                 lexer.Deambiguate_CloseParens ();
2281                 // After this, the next token returned is one of
2282                 // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS
2283                 // or CLOSE_PARENS_MINUS.
2284           }
2285         ;
2286
2287 parenthesized_expression
2288         : parenthesized_expression_0 CLOSE_PARENS_NO_CAST
2289           {
2290                 $$ = $1;
2291           }
2292         | parenthesized_expression_0 CLOSE_PARENS_MINUS
2293           {
2294                 // If a parenthesized expression is followed by a minus, we need to wrap
2295                 // the expression inside a ParenthesizedExpression for the CS0075 check
2296                 // in Binary.DoResolve().
2297                 $$ = new ParenthesizedExpression ((Expression) $1, lexer.Location);
2298           }
2299         ;;
2300
2301 member_access
2302         : primary_expression DOT IDENTIFIER
2303           {
2304                 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2305           }
2306         | predefined_type DOT IDENTIFIER
2307           {
2308                 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2309           }
2310         ;
2311
2312 predefined_type
2313         : builtin_types
2314         ;
2315
2316 invocation_expression
2317         : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
2318           {
2319                 if ($1 == null) {
2320                         Location l = lexer.Location;
2321                         Report.Error (1, l, "Parse error");
2322                 }
2323                 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
2324           }
2325         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS
2326           {
2327                 $$ = new Invocation ((Expression) $1, new ArrayList (), lexer.Location);
2328           }
2329         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression
2330           {
2331                 $$ = new InvocationOrCast ((Expression) $1, (Expression) $3, lexer.Location);
2332           }
2333         ;
2334
2335 opt_argument_list
2336         : /* empty */           { $$ = null; }
2337         | argument_list
2338         ;
2339
2340 argument_list
2341         : argument              
2342           { 
2343                 ArrayList list = new ArrayList (4);
2344                 list.Add ($1);
2345                 $$ = list;
2346           }
2347         | argument_list COMMA argument
2348           {
2349                 ArrayList list = (ArrayList) $1;
2350                 list.Add ($3);
2351                 $$ = list;
2352           }
2353         | argument_list error {
2354                 CheckToken (1026, yyToken, ", or ) expected");
2355           }
2356         ;
2357
2358 argument
2359         : expression
2360           {
2361                 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
2362           }
2363         | REF variable_reference 
2364           { 
2365                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
2366           }
2367         | OUT variable_reference 
2368           { 
2369                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
2370           }
2371         ;
2372
2373 variable_reference
2374         : expression { note ("section 5.4"); $$ = $1; }
2375         ;
2376
2377 element_access
2378         : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET 
2379           {
2380                 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
2381           }
2382         | primary_expression rank_specifiers
2383           {
2384                 // So the super-trick is that primary_expression
2385                 // can only be either a SimpleName or a MemberAccess. 
2386                 // The MemberAccess case arises when you have a fully qualified type-name like :
2387                 // Foo.Bar.Blah i;
2388                 // SimpleName is when you have
2389                 // Blah i;
2390                   
2391                 Expression expr = (Expression) $1;  
2392                 if (expr is ComposedCast){
2393                         $$ = new ComposedCast (expr, (string) $2, lexer.Location);
2394                 } else if (!(expr is SimpleName || expr is MemberAccess || expr is ConstructedType)){
2395                         Error_ExpectingTypeName (lexer.Location, expr);
2396                         $$ = TypeManager.system_object_expr;
2397                 } else {
2398                         //
2399                         // So we extract the string corresponding to the SimpleName
2400                         // or MemberAccess
2401                         // 
2402                         $$ = new ComposedCast (expr, (string) $2, lexer.Location);
2403                 }
2404           }
2405         ;
2406
2407 expression_list
2408         : expression
2409           {
2410                 ArrayList list = new ArrayList (4);
2411                 list.Add ($1);
2412                 $$ = list;
2413           }
2414         | expression_list COMMA expression
2415           {
2416                 ArrayList list = (ArrayList) $1;
2417                 list.Add ($3);
2418                 $$ = list;
2419           }
2420         ;
2421
2422 this_access
2423         : THIS
2424           {
2425                 $$ = new This (current_block, lexer.Location);
2426           }
2427         ;
2428
2429 base_access
2430         : BASE DOT IDENTIFIER
2431           {
2432                 $$ = new BaseAccess ((string) $3, lexer.Location);
2433           }
2434         | BASE OPEN_BRACKET expression_list CLOSE_BRACKET
2435           {
2436                 $$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location);
2437           }
2438         | BASE error {
2439                 Report.Error (175, "Use of keyword `base' is not valid in this context");
2440                 $$ = null;
2441           }
2442         ;
2443
2444 post_increment_expression
2445         : primary_expression OP_INC
2446           {
2447                 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement,
2448                                        (Expression) $1, lexer.Location);
2449           }
2450         ;
2451
2452 post_decrement_expression
2453         : primary_expression OP_DEC
2454           {
2455                 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement,
2456                                        (Expression) $1, lexer.Location);
2457           }
2458         ;
2459
2460 new_expression
2461         : object_or_delegate_creation_expression
2462         | array_creation_expression
2463         ;
2464
2465 object_or_delegate_creation_expression
2466         : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2467           {
2468                 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2469           }
2470         ;
2471
2472 array_creation_expression
2473         : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET 
2474           opt_rank_specifier
2475           opt_array_initializer
2476           {
2477                 $$ = new ArrayCreation ((Expression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, lexer.Location);
2478           }
2479         | NEW type rank_specifiers array_initializer
2480           {
2481                 $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, lexer.Location);
2482           }
2483         | NEW type error 
2484           {
2485                 Report.Error (1526, lexer.Location, "new expression requires () or [] after type");
2486           }
2487         ;
2488
2489 opt_rank_specifier
2490         : /* empty */
2491           {
2492                   $$ = "";
2493           }
2494         | rank_specifiers
2495           {
2496                         $$ = $1;
2497           }
2498         ;
2499
2500 rank_specifiers
2501         : rank_specifier opt_rank_specifier
2502           {
2503                   $$ = (string) $2 + (string) $1;
2504           }
2505         ;
2506
2507 rank_specifier
2508         : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
2509           {
2510                 $$ = "[" + (string) $2 + "]";
2511           }
2512         ;
2513
2514 opt_dim_separators
2515         : /* empty */
2516           {
2517                 $$ = "";
2518           }
2519         | dim_separators
2520           {
2521                   $$ = $1;
2522           }               
2523         ;
2524
2525 dim_separators
2526         : COMMA
2527           {
2528                 $$ = ",";
2529           }
2530         | dim_separators COMMA
2531           {
2532                 $$ = (string) $1 + ",";
2533           }
2534         ;
2535
2536 opt_array_initializer
2537         : /* empty */
2538           {
2539                 $$ = null;
2540           }
2541         | array_initializer
2542           {
2543                 $$ = $1;
2544           }
2545         ;
2546
2547 array_initializer
2548         : OPEN_BRACE CLOSE_BRACE
2549           {
2550                 ArrayList list = new ArrayList (4);
2551                 $$ = list;
2552           }
2553         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
2554           {
2555                 $$ = (ArrayList) $2;
2556           }
2557         ;
2558
2559 variable_initializer_list
2560         : variable_initializer
2561           {
2562                 ArrayList list = new ArrayList (4);
2563                 list.Add ($1);
2564                 $$ = list;
2565           }
2566         | variable_initializer_list COMMA variable_initializer
2567           {
2568                 ArrayList list = (ArrayList) $1;
2569                 list.Add ($3);
2570                 $$ = list;
2571           }
2572         ;
2573
2574 typeof_expression
2575         : TYPEOF OPEN_PARENS VOID CLOSE_PARENS
2576           {
2577                 $$ = new TypeOfVoid (lexer.Location);
2578           }
2579         | TYPEOF OPEN_PARENS type CLOSE_PARENS
2580           {
2581                 $$ = new TypeOf ((Expression) $3, lexer.Location);
2582           }
2583         ;
2584
2585 sizeof_expression
2586         : SIZEOF OPEN_PARENS type CLOSE_PARENS { 
2587                 $$ = new SizeOf ((Expression) $3, lexer.Location);
2588           }
2589         ;
2590
2591 checked_expression
2592         : CHECKED OPEN_PARENS expression CLOSE_PARENS
2593           {
2594                 $$ = new CheckedExpr ((Expression) $3, lexer.Location);
2595           }
2596         ;
2597
2598 unchecked_expression
2599         : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
2600           {
2601                 $$ = new UnCheckedExpr ((Expression) $3, lexer.Location);
2602           }
2603         ;
2604
2605 pointer_member_access 
2606         : primary_expression OP_PTR IDENTIFIER
2607           {
2608                 Expression deref;
2609
2610                 deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lexer.Location);
2611                 $$ = new MemberAccess (deref, (string) $3, lexer.Location);
2612           }
2613         ;
2614
2615 anonymous_method_expression
2616         : DELEGATE opt_anonymous_method_signature {
2617                 oob_stack.Push (current_local_parameters);
2618                 current_local_parameters = (Parameters)$2;
2619                 create_toplevel_block = true;
2620           } block {
2621                 create_toplevel_block = false;
2622                 if (!RootContext.V2){
2623                         Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2");
2624                         $$ = null;
2625                 } else 
2626                         $$ = new AnonymousMethod ((Parameters) $2, (Block) $4, lexer.Location);
2627                 current_local_parameters = (Parameters) oob_stack.Pop ();
2628           }
2629         ;
2630
2631 opt_anonymous_method_signature
2632         : /* empty */                   { $$ = Parameters.EmptyReadOnlyParameters; }
2633         | anonymous_method_signature
2634         ;
2635
2636 anonymous_method_signature
2637         : OPEN_PARENS opt_anonymous_method_parameter_list CLOSE_PARENS 
2638           {
2639                 if ($2 == null)
2640                         $$ = Parameters.EmptyReadOnlyParameters;
2641                 else {
2642                         ArrayList par_list = (ArrayList) $2;
2643                         Parameter [] pars = new Parameter [par_list.Count];
2644                         par_list.CopyTo (pars);
2645                         $$ = new Parameters (pars, null, lexer.Location);
2646                 }
2647           }
2648         ;
2649
2650 opt_anonymous_method_parameter_list
2651         : /* empty */   { $$ = null; } 
2652         | anonymous_method_parameter_list  { $$ = $1; }
2653         ;
2654
2655 anonymous_method_parameter_list
2656         : anonymous_method_parameter 
2657           {
2658                 ArrayList a = new ArrayList (4);
2659                 a.Add ($1);
2660                 $$ = a;
2661           }
2662         | anonymous_method_parameter_list COMMA anonymous_method_parameter 
2663           {
2664                 ArrayList a = (ArrayList) $1;
2665                 a.Add ($3);
2666                 $$ = a;
2667           }
2668         ; 
2669
2670 anonymous_method_parameter
2671         : opt_parameter_modifier type IDENTIFIER {
2672                 $$ = new Parameter ((Expression) $2, (string) $2, (Parameter.Modifier) $1, null);
2673           }
2674         ;
2675
2676 default_value_expression
2677         : DEFAULT_OPEN_PARENS type CLOSE_PARENS
2678           {
2679                 $$ = new DefaultValueExpression ((Expression) $2, lexer.Location);
2680           }
2681         ;
2682
2683 unary_expression
2684         : primary_expression
2685         | BANG prefixed_unary_expression
2686           {
2687                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
2688           }
2689         | TILDE prefixed_unary_expression
2690           {
2691                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location);
2692           }
2693         | cast_expression
2694         ;
2695
2696 cast_list
2697         : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression
2698           {
2699                 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
2700           }
2701         | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression
2702           {
2703                 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
2704           }     
2705         ;
2706
2707 cast_expression
2708         : cast_list
2709         | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
2710           {
2711                 $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
2712           }
2713         ;
2714
2715         //
2716         // The idea to split this out is from Rhys' grammar
2717         // to solve the problem with casts.
2718         //
2719 prefixed_unary_expression
2720         : unary_expression
2721         | PLUS prefixed_unary_expression
2722           { 
2723                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
2724           } 
2725         | MINUS prefixed_unary_expression 
2726           { 
2727                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
2728           }
2729         | OP_INC prefixed_unary_expression 
2730           {
2731                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
2732                                        (Expression) $2, lexer.Location);
2733           }
2734         | OP_DEC prefixed_unary_expression 
2735           {
2736                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
2737                                        (Expression) $2, lexer.Location);
2738           }
2739         | STAR prefixed_unary_expression
2740           {
2741                 $$ = new Unary (Unary.Operator.Indirection, (Expression) $2, lexer.Location);
2742           }
2743         | BITWISE_AND prefixed_unary_expression
2744           {
2745                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, lexer.Location);
2746           }
2747         ;
2748
2749 pre_increment_expression
2750         : OP_INC prefixed_unary_expression 
2751           {
2752                 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
2753                                        (Expression) $2, lexer.Location);
2754           }
2755         ;
2756
2757 pre_decrement_expression
2758         : OP_DEC prefixed_unary_expression 
2759           {
2760                 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
2761                                        (Expression) $2, lexer.Location);
2762           }
2763         ;
2764
2765 multiplicative_expression
2766         : prefixed_unary_expression
2767         | multiplicative_expression STAR prefixed_unary_expression
2768           {
2769                 $$ = new Binary (Binary.Operator.Multiply, 
2770                                  (Expression) $1, (Expression) $3, lexer.Location);
2771           }
2772         | multiplicative_expression DIV prefixed_unary_expression
2773           {
2774                 $$ = new Binary (Binary.Operator.Division, 
2775                                  (Expression) $1, (Expression) $3, lexer.Location);
2776           }
2777         | multiplicative_expression PERCENT prefixed_unary_expression 
2778           {
2779                 $$ = new Binary (Binary.Operator.Modulus, 
2780                                  (Expression) $1, (Expression) $3, lexer.Location);
2781           }
2782         ;
2783
2784 additive_expression
2785         : multiplicative_expression
2786         | additive_expression PLUS multiplicative_expression 
2787           {
2788                 $$ = new Binary (Binary.Operator.Addition, 
2789                                  (Expression) $1, (Expression) $3, lexer.Location);
2790           }
2791         | additive_expression MINUS multiplicative_expression
2792           {
2793                 $$ = new Binary (Binary.Operator.Subtraction, 
2794                                  (Expression) $1, (Expression) $3, lexer.Location);
2795           }
2796         ;
2797
2798 shift_expression
2799         : additive_expression
2800         | shift_expression OP_SHIFT_LEFT additive_expression
2801           {
2802                 $$ = new Binary (Binary.Operator.LeftShift, 
2803                                  (Expression) $1, (Expression) $3, lexer.Location);
2804           }
2805         | shift_expression OP_SHIFT_RIGHT additive_expression
2806           {
2807                 $$ = new Binary (Binary.Operator.RightShift, 
2808                                  (Expression) $1, (Expression) $3, lexer.Location);
2809           }
2810         ; 
2811
2812 relational_expression
2813         : shift_expression
2814         | relational_expression OP_LT shift_expression
2815           {
2816                 $$ = new Binary (Binary.Operator.LessThan, 
2817                                  (Expression) $1, (Expression) $3, lexer.Location);
2818           }
2819         | relational_expression OP_GT shift_expression
2820           {
2821                 $$ = new Binary (Binary.Operator.GreaterThan, 
2822                                  (Expression) $1, (Expression) $3, lexer.Location);
2823           }
2824         | relational_expression OP_LE shift_expression
2825           {
2826                 $$ = new Binary (Binary.Operator.LessThanOrEqual, 
2827                                  (Expression) $1, (Expression) $3, lexer.Location);
2828           }
2829         | relational_expression OP_GE shift_expression
2830           {
2831                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
2832                                  (Expression) $1, (Expression) $3, lexer.Location);
2833           }
2834         | relational_expression IS type
2835           {
2836                 $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
2837           }
2838         | relational_expression AS type
2839           {
2840                 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
2841           }
2842         ;
2843
2844 equality_expression
2845         : relational_expression
2846         | equality_expression OP_EQ relational_expression
2847           {
2848                 $$ = new Binary (Binary.Operator.Equality, 
2849                                  (Expression) $1, (Expression) $3, lexer.Location);
2850           }
2851         | equality_expression OP_NE relational_expression
2852           {
2853                 $$ = new Binary (Binary.Operator.Inequality, 
2854                                  (Expression) $1, (Expression) $3, lexer.Location);
2855           }
2856         ; 
2857
2858 and_expression
2859         : equality_expression
2860         | and_expression BITWISE_AND equality_expression
2861           {
2862                 $$ = new Binary (Binary.Operator.BitwiseAnd, 
2863                                  (Expression) $1, (Expression) $3, lexer.Location);
2864           }
2865         ;
2866
2867 exclusive_or_expression
2868         : and_expression
2869         | exclusive_or_expression CARRET and_expression
2870           {
2871                 $$ = new Binary (Binary.Operator.ExclusiveOr, 
2872                                  (Expression) $1, (Expression) $3, lexer.Location);
2873           }
2874         ;
2875
2876 inclusive_or_expression
2877         : exclusive_or_expression
2878         | inclusive_or_expression BITWISE_OR exclusive_or_expression
2879           {
2880                 $$ = new Binary (Binary.Operator.BitwiseOr, 
2881                                  (Expression) $1, (Expression) $3, lexer.Location);
2882           }
2883         ;
2884
2885 conditional_and_expression
2886         : inclusive_or_expression
2887         | conditional_and_expression OP_AND inclusive_or_expression
2888           {
2889                 $$ = new Binary (Binary.Operator.LogicalAnd, 
2890                                  (Expression) $1, (Expression) $3, lexer.Location);
2891           }
2892         ;
2893
2894 conditional_or_expression
2895         : conditional_and_expression
2896         | conditional_or_expression OP_OR conditional_and_expression
2897           {
2898                 $$ = new Binary (Binary.Operator.LogicalOr, 
2899                                  (Expression) $1, (Expression) $3, lexer.Location);
2900           }
2901         ;
2902
2903 conditional_expression
2904         : conditional_or_expression
2905         | conditional_or_expression INTERR expression COLON expression 
2906           {
2907                 $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5, lexer.Location);
2908           }
2909         ;
2910
2911 assignment_expression
2912         : prefixed_unary_expression ASSIGN expression
2913           {
2914                 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
2915           }
2916         | prefixed_unary_expression OP_MULT_ASSIGN expression
2917           {
2918                 Location l = lexer.Location;
2919
2920                 $$ = new CompoundAssign (
2921                         Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
2922           }
2923         | prefixed_unary_expression OP_DIV_ASSIGN expression
2924           {
2925                 Location l = lexer.Location;
2926
2927                 $$ = new CompoundAssign (
2928                         Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
2929           }
2930         | prefixed_unary_expression OP_MOD_ASSIGN expression
2931           {
2932                 Location l = lexer.Location;
2933
2934                 $$ = new CompoundAssign (
2935                         Binary.Operator.Modulus, (Expression) $1, (Expression) $3, l);
2936           }
2937         | prefixed_unary_expression OP_ADD_ASSIGN expression
2938           {
2939                 Location l = lexer.Location;
2940
2941                 $$ = new CompoundAssign (
2942                         Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
2943           }
2944         | prefixed_unary_expression OP_SUB_ASSIGN expression
2945           {
2946                 Location l = lexer.Location;
2947
2948                 $$ = new CompoundAssign (
2949                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
2950           }
2951         | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
2952           {
2953                 Location l = lexer.Location;
2954
2955                 $$ = new CompoundAssign (
2956                         Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, l);
2957           }
2958         | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
2959           {
2960                 Location l = lexer.Location;
2961
2962                 $$ = new CompoundAssign (
2963                         Binary.Operator.RightShift, (Expression) $1, (Expression) $3, l);
2964           }
2965         | prefixed_unary_expression OP_AND_ASSIGN expression
2966           {
2967                 Location l = lexer.Location;
2968
2969                 $$ = new CompoundAssign (
2970                         Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, l);
2971           }
2972         | prefixed_unary_expression OP_OR_ASSIGN expression
2973           {
2974                 Location l = lexer.Location;
2975
2976                 $$ = new CompoundAssign (
2977                         Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, l);
2978           }
2979         | prefixed_unary_expression OP_XOR_ASSIGN expression
2980           {
2981                 Location l = lexer.Location;
2982
2983                 $$ = new CompoundAssign (
2984                         Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, l);
2985           }
2986         ;
2987
2988 expression
2989         : conditional_expression
2990         | assignment_expression
2991         ;
2992
2993 constant_expression
2994         : expression
2995         ;
2996
2997 boolean_expression
2998         : expression
2999         ;
3000
3001 //
3002 // 10 classes
3003 //
3004 class_declaration
3005         : opt_attributes
3006           opt_modifiers
3007           CLASS IDENTIFIER
3008           {
3009                 Class new_class;
3010                 string name;
3011
3012                 name = MakeName ((string) $4);
3013
3014                 new_class = new Class (current_namespace, current_container, name, (int) $2, 
3015                                        (Attributes) $1, lexer.Location);
3016                 current_container = new_class;
3017                 RootContext.Tree.RecordDecl (name, new_class);
3018
3019                 lexer.ConstraintsParsing = true;
3020           }
3021           opt_type_parameter_list
3022           opt_class_base
3023           opt_type_parameter_constraints_clauses
3024           {
3025                 lexer.ConstraintsParsing = false;
3026           }
3027           class_body 
3028           opt_semicolon 
3029           {
3030                 Class new_class = (Class) current_container;
3031
3032                 if ($8 != null && $6 == null)
3033                         Report.Error (80, lexer.Location,
3034                                       "Contraints are not allowed on non-generic declarations");
3035
3036                 if ($6 != null)
3037                         CheckDef (new_class.SetParameterInfo ((ArrayList) $6, (ArrayList) $8), new_class.Name, new_class.Location);
3038                 if ($7 != null) {
3039                         if (new_class.Name == "System.Object") {
3040                                 Report.Error (537, new_class.Location, "The class System.Object cannot have a base class or implement an interface.");
3041                         }
3042
3043                         new_class.Bases = (ArrayList) $7;
3044                 }
3045                 current_container = current_container.Parent;
3046                 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
3047
3048                 $$ = new_class;
3049           }
3050         | opt_attributes
3051           opt_modifiers
3052           CLASS IDENTIFIER
3053           {
3054                 lexer.ConstraintsParsing = true;
3055           }
3056           WHERE {
3057                 Report.Error (80, lexer.Location,
3058                               "Contraints are not allowed on non-generic declarations");
3059                 yyErrorFlag = 0;
3060                 $$ = null;
3061           }
3062         ;       
3063
3064 opt_modifiers
3065         : /* empty */           { $$ = (int) 0; }
3066         | modifiers
3067         ;
3068
3069 modifiers
3070         : modifier
3071         | modifiers modifier
3072           { 
3073                 int m1 = (int) $1;
3074                 int m2 = (int) $2;
3075
3076                 if ((m1 & m2) != 0) {
3077                         Location l = lexer.Location;
3078                         Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
3079                 }
3080                 $$ = (int) (m1 | m2);
3081           }
3082         ;
3083
3084 modifier
3085         : NEW                   { $$ = Modifiers.NEW; }
3086         | PUBLIC                { $$ = Modifiers.PUBLIC; }
3087         | PROTECTED             { $$ = Modifiers.PROTECTED; }
3088         | INTERNAL              { $$ = Modifiers.INTERNAL; }
3089         | PRIVATE               { $$ = Modifiers.PRIVATE; }
3090         | ABSTRACT              { $$ = Modifiers.ABSTRACT; }
3091         | SEALED                { $$ = Modifiers.SEALED; }
3092         | STATIC                { $$ = Modifiers.STATIC; }
3093         | READONLY              { $$ = Modifiers.READONLY; }
3094         | VIRTUAL               { $$ = Modifiers.VIRTUAL; }
3095         | OVERRIDE              { $$ = Modifiers.OVERRIDE; }
3096         | EXTERN                { $$ = Modifiers.EXTERN; }
3097         | VOLATILE              { $$ = Modifiers.VOLATILE; }
3098         | UNSAFE                { $$ = Modifiers.UNSAFE; }
3099         ;
3100
3101 opt_class_base
3102         : /* empty */           { $$ = null; }
3103         | class_base            { $$ = $1;   }
3104         ;
3105
3106 class_base
3107         : COLON type_list { $$ = $2; }
3108         ;
3109
3110 opt_type_parameter_list
3111         : /* empty */           { $$ = null; }
3112         | type_parameter_list   { $$ = $1; }
3113         ;
3114
3115 type_parameter_list
3116         : OP_GENERICS_LT type_parameters OP_GENERICS_GT { $$ = $2; }
3117         ;
3118
3119 type_parameters
3120         : type_parameter { 
3121                 // 
3122                 // Do some profiling to find the optimal size, for now we
3123                 // assume most people will be generic on one type (saves space
3124                 //
3125                 ArrayList type_parameters = new ArrayList (1);
3126                 type_parameters.Add ($1);
3127                 $$ = type_parameters;
3128           }
3129         | type_parameters COMMA type_parameter {
3130                 ArrayList type_parameters = (ArrayList) $1;
3131
3132                 type_parameters.Add ($3);
3133                 $$ = type_parameters;
3134           }
3135         ;
3136
3137 type_parameter
3138         : IDENTIFIER
3139         ;
3140
3141 opt_type_parameter_constraints_clauses
3142         : /* empty */           { $$ = null; }
3143         | type_parameter_constraints_clauses 
3144           { $$ = $1; }
3145         ;
3146
3147 type_parameter_constraints_clauses
3148         : type_parameter_constraints_clause
3149         | type_parameter_constraints_clauses type_parameter_constraints_clause {
3150                 ArrayList constraints = (ArrayList) $1;
3151
3152                 constraints.Add ($2);
3153                 $$ = constraints;
3154           }
3155         ; 
3156
3157 type_parameter_constraints_clause
3158         : WHERE type_parameter COLON type_parameter_constraints {
3159                 ArrayList constraints = new ArrayList (1);
3160                 constraints.Add (new Constraints ((string) $2, (ArrayList) $4, lexer.Location));
3161                 $$ = constraints;
3162           }
3163         ; 
3164
3165 type_parameter_constraints
3166         : type_parameter_constraint {
3167                 ArrayList constraints = new ArrayList (1);
3168                 constraints.Add ($1);
3169                 $$ = constraints;
3170           }
3171         | type_parameter_constraints COMMA type_parameter_constraint {
3172                 ArrayList constraints = (ArrayList) $1;
3173
3174                 constraints.Add ($3);
3175                 $$ = constraints;
3176           }
3177         ;
3178
3179 type_parameter_constraint
3180         : type
3181         | NEW OPEN_PARENS CLOSE_PARENS {
3182                 $$ = true;
3183           }
3184         ;
3185
3186 //
3187 // Statements (8.2)
3188 //
3189
3190 //
3191 // A block is "contained" on the following places:
3192 //      method_body
3193 //      property_declaration as part of the accessor body (get/set)
3194 //      operator_declaration
3195 //      constructor_declaration
3196 //      destructor_declaration
3197 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
3198 //      
3199 block
3200         : OPEN_BRACE 
3201           {
3202                 if (current_block == null || create_toplevel_block){
3203                         current_block = new ToplevelBlock (current_local_parameters, lexer.Location);
3204                 } else {
3205                 current_block = new Block (current_block, current_local_parameters,
3206                                            lexer.Location, Location.Null);
3207                 }
3208           } 
3209           opt_statement_list CLOSE_BRACE 
3210           { 
3211                 while (current_block.Implicit)
3212                         current_block = current_block.Parent;
3213                 $$ = current_block;
3214                 current_block.SetEndLocation (lexer.Location);
3215                 current_block = current_block.Parent;
3216           }
3217         ;
3218
3219 opt_statement_list
3220         : /* empty */
3221         | statement_list 
3222         ;
3223
3224 statement_list
3225         : statement
3226         | statement_list statement
3227         ;
3228
3229 statement
3230         : declaration_statement
3231           {
3232                 if ($1 != null && (Block) $1 != current_block){
3233                         current_block.AddStatement ((Statement) $1);
3234                         current_block = (Block) $1;
3235                 }
3236           }
3237         | embedded_statement
3238           {
3239                 current_block.AddStatement ((Statement) $1);
3240           }
3241         | labeled_statement
3242         ;
3243
3244 embedded_statement
3245         : block
3246         | empty_statement
3247         | expression_statement
3248         | selection_statement
3249         | iteration_statement
3250         | jump_statement                  
3251         | try_statement
3252         | checked_statement
3253         | unchecked_statement
3254         | lock_statement
3255         | using_statement
3256         | unsafe_statement
3257         | fixed_statement
3258         ;
3259
3260 empty_statement
3261         : SEMICOLON
3262           {
3263                   $$ = EmptyStatement.Value;
3264           }
3265         ;
3266
3267 labeled_statement
3268         : IDENTIFIER COLON 
3269           {
3270                 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
3271
3272                 if (!current_block.AddLabel ((string) $1, labeled)){
3273                         Location l = lexer.Location;
3274                         Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
3275                 }       
3276                 current_block.AddStatement (labeled);
3277           }
3278           statement
3279         ;
3280
3281 declaration_statement
3282         : local_variable_declaration SEMICOLON
3283           {
3284                 if ($1 != null){
3285                         DictionaryEntry de = (DictionaryEntry) $1;
3286
3287                         $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3288                 }
3289           }
3290
3291         | local_constant_declaration SEMICOLON
3292           {
3293                 if ($1 != null){
3294                         DictionaryEntry de = (DictionaryEntry) $1;
3295
3296                         $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value);
3297                 }
3298           }
3299         ;
3300
3301 /* 
3302  * The following is from Rhys' grammar:
3303  * > Types in local variable declarations must be recognized as 
3304  * > expressions to prevent reduce/reduce errors in the grammar.
3305  * > The expressions are converted into types during semantic analysis.
3306  */
3307 local_variable_type
3308         : primary_expression opt_rank_specifier
3309           { 
3310                 // FIXME: Do something smart here regarding the composition of the type.
3311
3312                 // Ok, the above "primary_expression" is there to get rid of
3313                 // both reduce/reduce and shift/reduces in the grammar, it should
3314                 // really just be "type_name".  If you use type_name, a reduce/reduce
3315                 // creeps up.  If you use namespace_or_type_name (which is all we need
3316                 // really) two shift/reduces appear.
3317                 // 
3318
3319                 // So the super-trick is that primary_expression
3320                 // can only be either a SimpleName or a MemberAccess. 
3321                 // The MemberAccess case arises when you have a fully qualified type-name like :
3322                 // Foo.Bar.Blah i;
3323                 // SimpleName is when you have
3324                 // Blah i;
3325                   
3326                 Expression expr = (Expression) $1;  
3327                 if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType)) {
3328                         Error_ExpectingTypeName (lexer.Location, expr);
3329                         $$ = null;
3330                 } else {
3331                         //
3332                         // So we extract the string corresponding to the SimpleName
3333                         // or MemberAccess
3334                         // 
3335
3336                         if ((string) $2 == "")
3337                                 $$ = $1;
3338                         else
3339                                 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3340                 }
3341           }
3342         | builtin_types opt_rank_specifier
3343           {
3344                 if ((string) $2 == "")
3345                         $$ = $1;
3346                 else
3347                         $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3348           }
3349         ;
3350
3351 local_variable_pointer_type
3352         : primary_expression STAR
3353           {
3354                 Expression expr = (Expression) $1;  
3355                 Location l = lexer.Location;
3356
3357                 if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType)) {
3358                         Error_ExpectingTypeName (l, expr);
3359
3360                         $$ = null;
3361                 } else 
3362                         $$ = new ComposedCast ((Expression) $1, "*", l);
3363           }
3364         | builtin_types STAR
3365           {
3366                 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);;
3367           }
3368         | VOID STAR
3369           {
3370                 $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);;
3371           }
3372         | local_variable_pointer_type STAR
3373           {
3374                 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
3375           }
3376         ;
3377
3378 local_variable_declaration
3379         : local_variable_type variable_declarators
3380           {
3381                 if ($1 != null)
3382                         $$ = new DictionaryEntry ($1, $2);
3383                 else
3384                         $$ = null;
3385           }
3386         | local_variable_pointer_type opt_rank_specifier variable_declarators
3387         {
3388                 if ($1 != null){
3389                         Expression t;
3390
3391                         if ((string) $2 == "")
3392                                 t = (Expression) $1;
3393                         else
3394                                 t = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3395                         $$ = new DictionaryEntry (t, $3);
3396                 } else 
3397                         $$ = null;
3398         }
3399         ;
3400
3401 local_constant_declaration
3402         : CONST local_variable_type constant_declarators
3403           {
3404                 if ($2 != null)
3405                         $$ = new DictionaryEntry ($2, $3);
3406                 else
3407                         $$ = null;
3408           }
3409         ;
3410
3411 expression_statement
3412         : statement_expression SEMICOLON
3413           {
3414                 $$ = $1;
3415           }
3416         ;
3417
3418         //
3419         // We have to do the wrapping here and not in the case above,
3420         // because statement_expression is used for example in for_statement
3421         //
3422 statement_expression
3423         : invocation_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3424         | object_creation_expression    { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3425         | assignment_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3426         | post_increment_expression     { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3427         | post_decrement_expression     { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3428         | pre_increment_expression      { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3429         | pre_decrement_expression      { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3430         | error {
3431                 Report.Error (1002, lexer.Location, "Expecting `;'");
3432                 $$ = null;
3433           }
3434         ;
3435
3436 object_creation_expression
3437         : object_or_delegate_creation_expression
3438           { note ("complain if this is a delegate maybe?"); } 
3439         ;
3440
3441 selection_statement
3442         : if_statement
3443         | switch_statement
3444         ; 
3445
3446 if_statement
3447         : if_statement_open if_statement_rest
3448           {
3449                 $$ = $2;
3450           }
3451         ;
3452
3453 if_statement_open
3454         : IF OPEN_PARENS 
3455           {
3456                 oob_stack.Push (lexer.Location);
3457           }
3458         ;
3459
3460 if_statement_rest
3461         : boolean_expression CLOSE_PARENS 
3462           embedded_statement
3463           { 
3464                 Location l = (Location) oob_stack.Pop ();
3465
3466                 $$ = new If ((Expression) $1, (Statement) $3, l);
3467
3468                 if (RootContext.WarningLevel >= 3){
3469                         if ($3 == EmptyStatement.Value)
3470                                 Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
3471                 }
3472
3473           }
3474         | boolean_expression CLOSE_PARENS
3475           embedded_statement ELSE embedded_statement
3476           {
3477                 Location l = (Location) oob_stack.Pop ();
3478
3479                 $$ = new If ((Expression) $1, (Statement) $3, (Statement) $5, l);
3480           }
3481         ;
3482
3483 switch_statement
3484         : SWITCH OPEN_PARENS 
3485           { 
3486                 oob_stack.Push (lexer.Location);
3487                 switch_stack.Push (current_block);
3488           }
3489           expression CLOSE_PARENS 
3490           switch_block
3491           {
3492                 $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) oob_stack.Pop ());
3493                 current_block = (Block) switch_stack.Pop ();
3494           }
3495         ;
3496
3497 switch_block
3498         : OPEN_BRACE
3499           opt_switch_sections
3500           CLOSE_BRACE
3501           {
3502                 $$ = $2;
3503           }
3504         ;
3505
3506 opt_switch_sections
3507         : /* empty */           
3508           {
3509                 Report.Error (1522, lexer.Location, "Empty switch block"); 
3510           }
3511         | switch_sections
3512         ;
3513
3514 switch_sections
3515         : switch_section 
3516           {
3517                 ArrayList sections = new ArrayList (4);
3518
3519                 sections.Add ($1);
3520                 $$ = sections;
3521           }
3522         | switch_sections switch_section
3523           {
3524                 ArrayList sections = (ArrayList) $1;
3525
3526                 sections.Add ($2);
3527                 $$ = sections;
3528           }
3529         ;
3530
3531 switch_section
3532         : switch_labels
3533           {
3534                 current_block = current_block.CreateSwitchBlock (lexer.Location);
3535           }
3536           statement_list 
3537           {
3538                 Block topmost = current_block;
3539
3540                 while (topmost.Implicit)
3541                         topmost = topmost.Parent;
3542                 $$ = new SwitchSection ((ArrayList) $1, topmost);
3543           }
3544         ;
3545
3546 switch_labels
3547         : switch_label 
3548           {
3549                 ArrayList labels = new ArrayList (4);
3550
3551                 labels.Add ($1);
3552                 $$ = labels;
3553           }
3554         | switch_labels switch_label 
3555           {
3556                 ArrayList labels = (ArrayList) ($1);
3557                 labels.Add ($2);
3558
3559                 $$ = labels;
3560           }
3561         ;
3562
3563 switch_label
3564         : CASE constant_expression COLON        { $$ = new SwitchLabel ((Expression) $2, lexer.Location); }
3565         | DEFAULT COLON                         { $$ = new SwitchLabel (null, lexer.Location); }
3566         | error {
3567                 Report.Error (
3568                         1523, lexer.Location, 
3569                         "The keyword case or default must precede code in switch block");
3570           }
3571         ;
3572
3573 iteration_statement
3574         : while_statement
3575         | do_statement
3576         | for_statement
3577         | foreach_statement
3578         ;
3579
3580 while_statement
3581         : WHILE OPEN_PARENS 
3582         {
3583                 oob_stack.Push (lexer.Location);
3584         }
3585         boolean_expression CLOSE_PARENS embedded_statement
3586         {
3587                 Location l = (Location) oob_stack.Pop ();
3588                 $$ = new While ((Expression) $4, (Statement) $6, l);
3589         
3590                 if (RootContext.WarningLevel >= 3){
3591                         if ($6 == EmptyStatement.Value)
3592                                 Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
3593                 }
3594         }
3595         ;
3596
3597 do_statement
3598         : DO embedded_statement 
3599           WHILE OPEN_PARENS {
3600                 oob_stack.Push (lexer.Location);
3601           }
3602           boolean_expression CLOSE_PARENS SEMICOLON
3603           {
3604                 Location l = (Location) oob_stack.Pop ();
3605
3606                 $$ = new Do ((Statement) $2, (Expression) $6, l);
3607           }
3608         ;
3609
3610 for_statement
3611         : FOR OPEN_PARENS 
3612           opt_for_initializer SEMICOLON
3613           {
3614                 Block assign_block = new Block (current_block);
3615                 current_block = assign_block;
3616
3617                 if ($3 is DictionaryEntry){
3618                         DictionaryEntry de = (DictionaryEntry) $3;
3619                         
3620                         Expression type = (Expression) de.Key;
3621                         ArrayList var_declarators = (ArrayList) de.Value;
3622
3623                         foreach (VariableDeclaration decl in var_declarators){
3624
3625                                 LocalInfo vi;
3626
3627                                 vi = current_block.AddVariable (
3628                                         type, decl.identifier, current_local_parameters, decl.Location);
3629                                 if (vi == null)
3630                                         continue;
3631
3632                                 Location l = lexer.Location;
3633                                 Expression expr;
3634                                 if (decl.expression_or_array_initializer is Expression){
3635                                         expr = (Expression) decl.expression_or_array_initializer;
3636                                 } else if (decl.expression_or_array_initializer == null) {
3637                                         expr = null;
3638                                 } else {
3639                                         ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3640                                         expr = new ArrayCreation (type, "", init, decl.Location);
3641                                 }
3642                                         
3643                                 LocalVariableReference var;
3644                                 var = new LocalVariableReference (assign_block, decl.identifier, l);
3645
3646                                 if (expr != null) {
3647                                         Assign a = new Assign (var, expr, decl.Location);
3648                                         
3649                                         assign_block.AddStatement (new StatementExpression (a, lexer.Location));
3650                                 }
3651                         }
3652                         
3653                         $3 = null;
3654                 } 
3655                 oob_stack.Push (lexer.Location);
3656           } 
3657           opt_for_condition SEMICOLON
3658           opt_for_iterator CLOSE_PARENS 
3659           embedded_statement
3660           {
3661                 Location l = (Location) oob_stack.Pop ();
3662
3663                 For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l);
3664
3665                 if (RootContext.WarningLevel >= 3){
3666                         if ($10 == EmptyStatement.Value)
3667                                 Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
3668                 }
3669
3670                 current_block.AddStatement (f);
3671                 while (current_block.Implicit)
3672                         current_block = current_block.Parent;
3673                 $$ = current_block;
3674                 current_block = current_block.Parent;
3675           }
3676         ;
3677
3678 opt_for_initializer
3679         : /* empty */           { $$ = EmptyStatement.Value; }
3680         | for_initializer       
3681         ;
3682
3683 for_initializer
3684         : local_variable_declaration
3685         | statement_expression_list
3686         ;
3687
3688 opt_for_condition
3689         : /* empty */           { $$ = null; }
3690         | boolean_expression
3691         ;
3692
3693 opt_for_iterator
3694         : /* empty */           { $$ = EmptyStatement.Value; }
3695         | for_iterator
3696         ;
3697
3698 for_iterator
3699         : statement_expression_list
3700         ;
3701
3702 statement_expression_list
3703         : statement_expression  
3704           {
3705                 // CHANGE: was `null'
3706                 Block b = new Block (current_block, Block.Flags.Implicit);   
3707
3708                 b.AddStatement ((Statement) $1);
3709                 $$ = b;
3710           }
3711         | statement_expression_list COMMA statement_expression
3712           {
3713                 Block b = (Block) $1;
3714
3715                 b.AddStatement ((Statement) $3);
3716                 $$ = $1;
3717           }
3718         ;
3719
3720 foreach_statement
3721         : FOREACH OPEN_PARENS type IDENTIFIER IN 
3722           {
3723                 oob_stack.Push (lexer.Location);
3724           }
3725           expression CLOSE_PARENS 
3726           {
3727                 oob_stack.Push (current_block);
3728
3729                 Block foreach_block = new Block (current_block, Block.Flags.Implicit);
3730                 LocalVariableReference v = null;
3731                 Location l = lexer.Location;
3732                 LocalInfo vi;
3733
3734                 vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l);
3735                 if (vi != null) {
3736                         vi.ReadOnly = true;
3737
3738                         // Get a writable reference to this read-only variable.
3739                         v = new LocalVariableReference (foreach_block, (string) $4, l, vi, false);
3740                 }
3741                 current_block = foreach_block;
3742
3743                 oob_stack.Push (v);
3744                 oob_stack.Push (current_block);
3745           } 
3746           embedded_statement 
3747           {
3748                 Block foreach_block = (Block) oob_stack.Pop ();
3749                 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
3750                 Block prev_block = (Block) oob_stack.Pop ();
3751                 Location l = (Location) oob_stack.Pop ();
3752
3753                 current_block = prev_block;
3754
3755                 if (v != null) {
3756                         Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l);
3757                         foreach_block.AddStatement (f);
3758                 }
3759
3760                 $$ = foreach_block;
3761           }
3762         ;
3763
3764 jump_statement
3765         : break_statement
3766         | continue_statement
3767         | goto_statement
3768         | return_statement
3769         | throw_statement
3770         | yield_statement
3771         ;
3772
3773 break_statement
3774         : BREAK SEMICOLON
3775           {
3776                 $$ = new Break (lexer.Location);
3777           }
3778         ;
3779
3780 continue_statement
3781         : CONTINUE SEMICOLON
3782           {
3783                 $$ = new Continue (lexer.Location);
3784           }
3785         ;
3786
3787 goto_statement
3788         : GOTO IDENTIFIER SEMICOLON 
3789           {
3790                 $$ = new Goto (current_block, (string) $2, lexer.Location);
3791           }
3792         | GOTO CASE constant_expression SEMICOLON
3793           {
3794                 $$ = new GotoCase ((Expression) $3, lexer.Location);
3795           }
3796         | GOTO DEFAULT SEMICOLON 
3797           {
3798                 $$ = new GotoDefault (lexer.Location);
3799           }
3800         ; 
3801
3802 return_statement
3803         : RETURN opt_expression SEMICOLON
3804           {
3805                 $$ = new Return ((Expression) $2, lexer.Location);
3806           }
3807         ;
3808
3809 throw_statement
3810         : THROW opt_expression SEMICOLON
3811           {
3812                 $$ = new Throw ((Expression) $2, lexer.Location);
3813           }
3814         ;
3815
3816 yield_statement 
3817         : IDENTIFIER RETURN expression SEMICOLON
3818           {
3819                 string s = (string) $1;
3820                 if (s != "yield"){
3821                         Report.Error (1003, lexer.Location, "; expected");
3822                         $$ = null;
3823                 }
3824                 if (!RootContext.V2){
3825                         Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode");
3826                         $$ = null;
3827                 }
3828                 if (iterator_container == null){
3829                         Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
3830                         $$ = null;
3831                 } else {
3832                         iterator_container.SetYields ();
3833                         $$ = new Yield ((Expression) $3, lexer.Location); 
3834                 }
3835           }
3836         | IDENTIFIER BREAK SEMICOLON
3837           {
3838                 string s = (string) $1;
3839                 if (s != "yield"){
3840                         Report.Error (1003, lexer.Location, "; expected");
3841                         $$ = null;
3842                 }
3843                 if (!RootContext.V2){
3844                         Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode");
3845                         $$ = null;
3846                 }
3847                 if (iterator_container == null){
3848                         Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
3849                         $$ = null;
3850                 } else {
3851                         iterator_container.SetYields ();
3852                         $$ = new YieldBreak (lexer.Location);
3853                 }
3854           }
3855         ;
3856
3857 opt_expression
3858         : /* empty */
3859         | expression
3860         ;
3861
3862 try_statement
3863         : TRY block catch_clauses 
3864         {
3865                 Catch g = null;
3866                 ArrayList s = new ArrayList (4);
3867                 
3868                 foreach (Catch cc in (ArrayList) $3) {
3869                         if (cc.IsGeneral)
3870                                 g = cc;
3871                         else
3872                                 s.Add (cc);
3873                 }
3874
3875                 // Now s contains the list of specific catch clauses
3876                 // and g contains the general one.
3877                 
3878                 $$ = new Try ((Block) $2, s, g, null, lexer.Location);
3879         }
3880         | TRY block opt_catch_clauses FINALLY block
3881           {
3882                 Catch g = null;
3883                 ArrayList s = new ArrayList (4);
3884                 ArrayList catch_list = (ArrayList) $3;
3885
3886                 if (catch_list != null){
3887                         foreach (Catch cc in catch_list) {
3888                                 if (cc.IsGeneral)
3889                                         g = cc;
3890                                 else
3891                                         s.Add (cc);
3892                         }
3893                 }
3894
3895                 $$ = new Try ((Block) $2, s, g, (Block) $5, lexer.Location);
3896           }
3897         | TRY block error 
3898           {
3899                 Report.Error (1524, lexer.Location, "Expected catch or finally");
3900           }
3901         ;
3902
3903 opt_catch_clauses
3904         : /* empty */  { $$ = null; }
3905         | catch_clauses
3906         ;
3907
3908 catch_clauses
3909         : catch_clause 
3910           {
3911                 ArrayList l = new ArrayList (4);
3912
3913                 l.Add ($1);
3914                 $$ = l;
3915           }
3916         | catch_clauses catch_clause
3917           {
3918                 ArrayList l = (ArrayList) $1;
3919
3920                 l.Add ($2);
3921                 $$ = l;
3922           }
3923         ;
3924
3925 opt_identifier
3926         : /* empty */   { $$ = null; }
3927         | IDENTIFIER
3928         ;
3929
3930 catch_clause 
3931         : CATCH opt_catch_args 
3932         {
3933                 Expression type = null;
3934                 string id = null;
3935                 
3936                 if ($2 != null) {
3937                         DictionaryEntry cc = (DictionaryEntry) $2;
3938                         type = (Expression) cc.Key;
3939                         id   = (string) cc.Value;
3940
3941                         if (id != null){
3942                                 ArrayList one = new ArrayList (4);
3943                                 Location loc = lexer.Location;
3944
3945                                 one.Add (new VariableDeclaration (id, null, loc));
3946
3947                                 $1 = current_block;
3948                                 current_block = new Block (current_block);
3949                                 Block b = declare_local_variables (type, one, loc);
3950                                 current_block = b;
3951                         }
3952                 }
3953         } block {
3954                 Expression type = null;
3955                 string id = null;
3956
3957                 if ($2 != null){
3958                         DictionaryEntry cc = (DictionaryEntry) $2;
3959                         type = (Expression) cc.Key;
3960                         id   = (string) cc.Value;
3961
3962                         if ($1 != null){
3963                                 //
3964                                 // FIXME: I can change this for an assignment.
3965                                 //
3966                                 while (current_block != (Block) $1)
3967                                         current_block = current_block.Parent;
3968                         }
3969                 }
3970
3971
3972                 $$ = new Catch (type, id , (Block) $4, lexer.Location);
3973         }
3974         ;
3975
3976 opt_catch_args
3977         : /* empty */ { $$ = null; }
3978         | catch_args
3979         ;         
3980
3981 catch_args 
3982         : OPEN_PARENS type opt_identifier CLOSE_PARENS 
3983         {
3984                 $$ = new DictionaryEntry ($2, $3);
3985         }
3986         ;
3987
3988 checked_statement
3989         : CHECKED block
3990           {
3991                 $$ = new Checked ((Block) $2);
3992           }
3993         ;
3994
3995 unchecked_statement
3996         : UNCHECKED block
3997           {
3998                 $$ = new Unchecked ((Block) $2);
3999           }
4000         ;
4001
4002 unsafe_statement
4003         : UNSAFE 
4004         {
4005                 if (!RootContext.Unsafe){
4006                         Report.Error (227, lexer.Location, 
4007                                 "Unsafe code can only be used if --unsafe is used");
4008                 }
4009         } block {
4010                 $$ = new Unsafe ((Block) $3);
4011         }
4012         ;
4013
4014 fixed_statement
4015         : FIXED OPEN_PARENS 
4016           type fixed_pointer_declarators 
4017           CLOSE_PARENS 
4018           {
4019                 Block assign_block = new Block (current_block, Block.Flags.Implicit);
4020                 ArrayList list = (ArrayList) $4;
4021                 Expression type = (Expression) $3;
4022                 Location l = lexer.Location;
4023                 int top = list.Count;
4024
4025                 for (int i = 0; i < top; i++){
4026                         Pair p = (Pair) list [i];
4027                         LocalInfo v;
4028
4029                         v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
4030                         if (v == null)
4031                                 continue;
4032                         v.ReadOnly = true;
4033                         p.First = v;
4034                         list [i] = p;
4035                 }
4036                 current_block.AddStatement (assign_block);
4037                 current_block = assign_block;
4038                 oob_stack.Push (assign_block);
4039                 oob_stack.Push (l);
4040           }
4041           embedded_statement 
4042           {
4043                 Location l = (Location) oob_stack.Pop ();
4044                 oob_stack.Pop ();
4045
4046                 $$ = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
4047           }
4048         ;
4049
4050 fixed_pointer_declarators
4051         : fixed_pointer_declarator      { 
4052                 ArrayList declarators = new ArrayList (4); 
4053                 declarators.Add ($1);
4054                 $$ = declarators;
4055           }
4056         | fixed_pointer_declarators COMMA fixed_pointer_declarator
4057           {
4058                 ArrayList declarators = (ArrayList) $1;
4059                 declarators.Add ($3);
4060                 $$ = declarators;
4061           }
4062         ;
4063
4064 fixed_pointer_declarator
4065         : IDENTIFIER ASSIGN expression
4066           {     
4067                 $$ = new Pair ($1, $3);
4068           }
4069         ;
4070
4071 lock_statement
4072         : LOCK OPEN_PARENS expression CLOSE_PARENS 
4073           {
4074                 //
4075           } 
4076           embedded_statement
4077           {
4078                 $$ = new Lock ((Expression) $3, (Statement) $6, lexer.Location);
4079           }
4080         ;
4081
4082 using_statement
4083         : USING OPEN_PARENS resource_acquisition CLOSE_PARENS 
4084           {
4085                 Block assign_block = new Block (current_block);
4086                 current_block = assign_block;
4087
4088                 oob_stack.Push (lexer.Location);
4089                 
4090                 if ($3 is DictionaryEntry){
4091                         DictionaryEntry de = (DictionaryEntry) $3;
4092                         Location l = lexer.Location;
4093
4094                         Expression type = (Expression) de.Key;
4095                         ArrayList var_declarators = (ArrayList) de.Value;
4096
4097                         ArrayList vars = new ArrayList (4);
4098
4099                         foreach (VariableDeclaration decl in var_declarators){
4100
4101                                 LocalInfo vi    = current_block.AddVariable (
4102                                         type, decl.identifier, 
4103                                         current_local_parameters, decl.Location);
4104                                 if (vi == null)
4105                                         continue;
4106                                 vi.ReadOnly = true;
4107
4108                                 Expression expr;
4109                                 if (decl.expression_or_array_initializer is Expression){
4110                                         expr = (Expression) decl.expression_or_array_initializer;
4111                                 } else {
4112                                         ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4113                                         
4114                                         expr = new ArrayCreation (type, "", init, decl.Location);
4115                                 }
4116
4117                                 LocalVariableReference var;
4118
4119                                 // Get a writable reference to this read-only variable.
4120                                 var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
4121
4122                                 // This is so that it is not a warning on using variables
4123                                 vi.Used = true;
4124
4125                                 vars.Add (new DictionaryEntry (var, expr));                             
4126
4127                                 // Assign a = new Assign (var, expr, decl.Location);
4128                                 // assign_block.AddStatement (new StatementExpression (a, lexer.Location));
4129                         }
4130                         $3 = new DictionaryEntry (type, vars);
4131                  }
4132           } 
4133           embedded_statement
4134           {
4135                 Using u = new Using ($3, (Statement) $6, (Location) oob_stack.Pop ());
4136                 current_block.AddStatement (u);
4137                 while (current_block.Implicit)
4138                         current_block = current_block.Parent;
4139                 $$ = current_block;
4140                 current_block = current_block.Parent;
4141           }
4142         ; 
4143
4144 resource_acquisition
4145         : local_variable_declaration
4146         | expression
4147         ;
4148
4149 %%
4150
4151 // <summary>
4152 //   A class used to pass around variable declarations and constants
4153 // </summary>
4154 public class VariableDeclaration {
4155         public string identifier;
4156         public object expression_or_array_initializer;
4157         public Location Location;
4158         public Attributes OptAttributes;
4159
4160         public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs)
4161         {
4162                 this.identifier = id;
4163                 this.expression_or_array_initializer = eoai;
4164                 this.Location = l;
4165                 this.OptAttributes = opt_attrs;
4166         }
4167
4168         public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4169         {
4170         }
4171 }
4172
4173 /// <summary>
4174 ///  Used to pass around interface property information
4175 /// </summary>
4176 public class InterfaceAccessorInfo {
4177
4178         public readonly Accessor Get, Set;
4179
4180         public InterfaceAccessorInfo (bool has_get, bool has_set,
4181                                       Attributes get_attrs, Attributes set_attrs)
4182         {
4183                 if (has_get)
4184                         Get = new Accessor (null, get_attrs);
4185                 if (has_set)
4186                         Set = new Accessor (null, set_attrs);
4187         }
4188 }
4189
4190
4191 // <summary>
4192 //   A class used to hold info about an indexer declarator
4193 // </summary>
4194 public class IndexerDeclaration {
4195         public Expression type;
4196         public MemberName interface_type;
4197         public Parameters param_list;
4198
4199         public IndexerDeclaration (Expression type, MemberName interface_type,
4200                                    Parameters param_list)
4201         {
4202                 this.type = type;
4203                 this.interface_type = interface_type;
4204                 this.param_list = param_list;
4205         }
4206 }
4207
4208 //
4209 // We use this when we do not have an object in advance that is an IIteratorContainer
4210 //
4211 public class SimpleIteratorContainer : IIteratorContainer {
4212         public bool Yields;
4213
4214         public static SimpleIteratorContainer Simple = new SimpleIteratorContainer ();
4215
4216         //
4217         // Reset and return
4218         //
4219         public static SimpleIteratorContainer GetSimple () { 
4220                 Simple.Yields = false;
4221                 return Simple;
4222         }
4223
4224         public void SetYields () { Yields = true; } 
4225 }
4226
4227 // <summary>
4228 //  A class used to hold info about an operator declarator
4229 // </summary>
4230 public class OperatorDeclaration {
4231         public Operator.OpType optype;
4232         public Expression ret_type, arg1type, arg2type;
4233         public string arg1name, arg2name;
4234         public Location location;
4235
4236         public OperatorDeclaration (Operator.OpType op, Expression ret_type, 
4237                                     Expression arg1type, string arg1name,
4238                                     Expression arg2type, string arg2name, Location location)
4239         {
4240                 optype = op;
4241                 this.ret_type = ret_type;
4242                 this.arg1type = arg1type;
4243                 this.arg1name = arg1name;
4244                 this.arg2type = arg2type;
4245                 this.arg2name = arg2name;
4246                 this.location = location;
4247         }
4248
4249 }
4250
4251 void Error_ExpectingTypeName (Location l, Expression expr)
4252 {
4253         if (expr is Invocation){
4254                 Report.Error (1002, l, "; expected");
4255         } else {
4256                 Report.Error (-1, l, "Invalid Type definition");
4257         }
4258 }
4259
4260 // <summary>
4261 //   Given the @class_name name, it creates a fully qualified name
4262 //   based on the containing declaration space
4263 // </summary>
4264 string 
4265 MakeName (string class_name)
4266 {
4267         string ns = current_namespace.FullName;
4268         string container_name = current_container.Name;
4269
4270         if (container_name == ""){
4271                 if (ns != "")
4272                         return ns + "." + class_name;
4273                 else
4274                         return class_name;
4275         } else
4276                 return container_name + "." + class_name;
4277 }
4278
4279 // <summary>
4280 //   Used to report back to the user the result of a declaration
4281 //   in the current declaration space
4282 // </summary>
4283 void 
4284 CheckDef (DeclSpace.AdditionResult result, string name, Location l)
4285 {
4286         if (result == DeclSpace.AdditionResult.Success)
4287                 return;
4288
4289         switch (result){
4290         case DeclSpace.AdditionResult.NameExists:
4291                 Report.Error (102, l, "The container `" + current_container.Name + 
4292                                  "' already contains a definition for `"+
4293                                  name + "'");
4294                 break;
4295
4296
4297                 //
4298                 // This is handled only for static Constructors, because
4299                 // in reality we handle these by the semantic analysis later
4300                 //
4301         case DeclSpace.AdditionResult.MethodExists:
4302                 Report.Error (
4303                         111, l, "Class `"+current_container.Name+
4304                         "' already defines a member called '" + 
4305                         name + "' with the same parameter types (more than one default constructor)");
4306                 break;
4307
4308         case DeclSpace.AdditionResult.EnclosingClash:
4309                 Report.Error (542, l, "Member names cannot be the same as their enclosing type");
4310                 break;
4311                 
4312         case DeclSpace.AdditionResult.NotAConstructor:
4313                 Report.Error (1520, l, "Class, struct, or interface method must have a return type");
4314                 break;
4315
4316         case DeclSpace.AdditionResult.Error:
4317                 // Error has already been reported.
4318                 break;
4319         }
4320 }
4321
4322 void 
4323 CheckDef (bool result, string name, Location l)
4324 {
4325         if (result)
4326                 return;
4327         CheckDef (DeclSpace.AdditionResult.NameExists, name, l);
4328 }
4329
4330 Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
4331 {
4332         Block implicit_block;
4333         ArrayList inits = null;
4334
4335         //
4336         // We use the `Used' property to check whether statements
4337         // have been added to the current block.  If so, we need
4338         // to create another block to contain the new declaration
4339         // otherwise, as an optimization, we use the same block to
4340         // add the declaration.
4341         //
4342         // FIXME: A further optimization is to check if the statements
4343         // that were added were added as part of the initialization
4344         // below.  In which case, no other statements have been executed
4345         // and we might be able to reduce the number of blocks for
4346         // situations like this:
4347         //
4348         // int j = 1;  int k = j + 1;
4349         //
4350         if (current_block.Used) {
4351                 implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
4352                 implicit_block.AddChildVariableNames (current_block);
4353         } else
4354                 implicit_block = current_block;
4355
4356         foreach (VariableDeclaration decl in variable_declarators){
4357
4358                 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4359                         if (decl.expression_or_array_initializer != null){
4360                                 if (inits == null)
4361                                         inits = new ArrayList (4);
4362                                 inits.Add (decl);
4363                         }
4364                 }
4365         }
4366
4367         if (inits == null)
4368                 return implicit_block;
4369
4370         foreach (VariableDeclaration decl in inits){
4371                 Assign assign;
4372                 Expression expr;
4373                 
4374                 if (decl.expression_or_array_initializer is Expression){
4375                         expr = (Expression) decl.expression_or_array_initializer;
4376
4377                 } else {
4378                         ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4379                         
4380                         expr = new ArrayCreation (type, "", init, decl.Location);
4381                 }
4382
4383                 LocalVariableReference var;
4384                 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4385
4386                 assign = new Assign (var, expr, decl.Location);
4387
4388                 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4389         }
4390         
4391         return implicit_block;
4392 }
4393
4394 Block declare_local_constants (Expression type, ArrayList declarators)
4395 {
4396         Block implicit_block;
4397
4398         if (current_block.Used)
4399                 implicit_block = new Block (current_block, Block.Flags.Implicit);
4400         else
4401                 implicit_block = current_block;
4402
4403         foreach (VariableDeclaration decl in declarators){
4404                 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4405                                                   current_local_parameters, decl.Location);
4406         }
4407         
4408         return implicit_block;
4409 }
4410
4411 void CheckAttributeTarget (string a)
4412 {
4413         switch (a) {
4414
4415         case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
4416                 return;
4417                 
4418         default :
4419                 Location l = lexer.Location;
4420                 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4421                 break;
4422         }
4423
4424 }
4425
4426 void CheckUnaryOperator (Operator.OpType op)
4427 {
4428         switch (op) {
4429                 
4430         case Operator.OpType.LogicalNot: 
4431         case Operator.OpType.OnesComplement: 
4432         case Operator.OpType.Increment:
4433         case Operator.OpType.Decrement:
4434         case Operator.OpType.True: 
4435         case Operator.OpType.False: 
4436         case Operator.OpType.Addition: 
4437         case Operator.OpType.Subtraction:
4438                 
4439                 break;
4440                 
4441         default :
4442                 Location l = lexer.Location;
4443                 Report.Error (1019, l, "Overloadable unary operator expected"); 
4444                 break;
4445                 
4446         }
4447 }
4448
4449 void CheckBinaryOperator (Operator.OpType op)
4450 {
4451         switch (op) {
4452                 
4453         case Operator.OpType.Addition: 
4454         case Operator.OpType.Subtraction: 
4455         case Operator.OpType.Multiply:
4456         case Operator.OpType.Division:
4457         case Operator.OpType.Modulus: 
4458         case Operator.OpType.BitwiseAnd: 
4459         case Operator.OpType.BitwiseOr:
4460         case Operator.OpType.ExclusiveOr: 
4461         case Operator.OpType.LeftShift: 
4462         case Operator.OpType.RightShift:
4463         case Operator.OpType.Equality: 
4464         case Operator.OpType.Inequality:
4465         case Operator.OpType.GreaterThan: 
4466         case Operator.OpType.LessThan: 
4467         case Operator.OpType.GreaterThanOrEqual:
4468         case Operator.OpType.LessThanOrEqual:
4469                 break;
4470                 
4471         default :
4472                 Location l = lexer.Location;
4473                 Report.Error (1020, l, "Overloadable binary operator expected");
4474                 break;
4475         }
4476         
4477 }
4478
4479 void syntax_error (Location l, string msg)
4480 {
4481         Report.Error (1003, l, "Syntax error, " + msg);
4482 }
4483
4484 void output (string s)
4485 {
4486         Console.WriteLine (s);
4487 }
4488
4489 void note (string s)
4490 {
4491         // Used to put annotations
4492 }
4493
4494 Tokenizer lexer;
4495
4496 public Tokenizer Lexer {
4497         get {
4498                 return lexer;
4499         }
4500 }                  
4501
4502 public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
4503 {
4504         current_namespace = new NamespaceEntry (null, file, null, Location.Null);
4505         this.name = file.Name;
4506         this.file = file;
4507         current_container = RootContext.Tree.Types;
4508         current_container.NamespaceEntry = current_namespace;
4509         oob_stack = new Stack ();
4510         switch_stack = new Stack ();
4511
4512         lexer = new Tokenizer (reader, file, defines);
4513 }
4514
4515 public void parse ()
4516 {
4517         try {
4518                 if (yacc_verbose_flag)
4519                         yyparse (lexer, new yydebug.yyDebugSimple ());
4520                 else
4521                         yyparse (lexer);
4522                 Tokenizer tokenizer = lexer as Tokenizer;
4523                 tokenizer.cleanup ();           
4524         } catch (Exception e){
4525                 // Please do not remove this, it is used during debugging
4526                 // of the grammar
4527                 //
4528                 Console.WriteLine (e);
4529                 Report.Error (-25, lexer.Location, "Parsing error");
4530                 if (Driver.parser_verbose)
4531                         Console.WriteLine (e);
4532         }
4533 }
4534
4535 void CheckToken (int error, int yyToken, string msg)
4536 {
4537         if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD){
4538                 Report.Error (error, lexer.Location, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ()));
4539                 return;
4540         }               
4541         Report.Error (error, lexer.Location, msg);
4542 }
4543
4544 void CheckIdentifierToken (int yyToken)
4545 {
4546         CheckToken (1041, yyToken, "Identifier expected");
4547 }
4548
4549 /* end end end */
4550 }