Fixed overloaded constructor invocation
[mono.git] / mcs / mbas / mb-parser.jay
1 %{
2 //
3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
4 //
5 // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
6 //
7 // Licensed under the terms of the GNU GPL
8 //
9 // Copyright (C) 2001 A Rafael D Teixeira
10 //
11 // TODO:
12 //      Nearly everything
13 //
14
15 namespace Mono.MonoBASIC
16 {
17         using System.Text;
18         using System;
19         using System.Reflection;
20         using System.Collections;
21         using Mono.Languages;
22         using Mono.CSharp;
23
24         /// <summary>
25         ///    The MonoBASIC Parser
26         /// </summary>
27         public class Parser : GenericParser
28         {
29         
30
31                 /// <summary>
32                 ///   Current block is used to add statements as we find
33                 ///   them.  
34                 /// </summary>
35                 Block      current_block;
36                 
37                 /// <summary>
38                 ///   Tmp block is used to store block endings in if/select's
39                 /// </summary>
40                 Block      tmp_block;           
41
42                 /// <summary>
43                 ///   Tmp block is used to store tmp copies of expressions
44                 /// </summary>
45                 Expression      tmp_expr;       
46                 
47                 /// <summary>
48                 ///   Tmp catch is used to store catch clauses in try..catch..finally
49                 /// </summary>
50                 ArrayList      tmp_catch_clauses;                       
51                 
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                 /// <summary>
60                 ///   This is used by the unary_expression code to resolve
61                 ///   a name against a parameter.  
62                 /// </summary>
63                 Parameters current_local_parameters;
64                 
65                 /// <summary>
66                 ///   This are used when parsing parameters in property
67                 ///   declarations.
68                 /// </summary>          
69                 Parameters set_parameters;
70                 Parameters get_parameters;
71                 
72                 /// <summary>
73                 ///   This is used by the sub_header parser to store modifiers
74                 ///   to be passed to sub/constructor  
75                 /// </summary>
76                 int current_modifiers;          
77                 
78                 /// <summary>
79                 ///   This is used by the sub_header parser to store attributes
80                 ///   to be passed to sub/constructor  
81                 /// </summary>
82                 Attributes current_attributes;                          
83
84                 /// <summary>
85                 ///   Using during property parsing to describe the implicit
86                 ///   value parameter that is passed to the "set" accessor
87                 ///   method
88                 /// </summary>
89                 string get_implicit_value_parameter_name;
90                 
91                 // <summary>
92                 //   Using during property parsing to describe the implicit
93                 //   value parameter that is passed to the "set" and "get"accesor
94                 //   methods (properties and indexers).
95                 // </summary>
96                 Expression get_implicit_value_parameter_type;
97                 
98                 /// <summary>
99                 ///   Using during property parsing to describe the implicit
100                 ///   value parameter that is passed to the "set" accessor
101                 ///   method
102                 /// </summary>
103                 string set_implicit_value_parameter_name;
104                 
105                 // <summary>
106                 //   Using during property parsing to describe the implicit
107                 //   value parameter that is passed to the "set" and "get"accesor
108                 //   methods (properties and indexers).
109                 // </summary>
110                 Expression set_implicit_value_parameter_type;           
111                 
112                 // An out-of-band stack.
113                 //
114                 Stack oob_stack;
115
116                 DoOptions do_type;
117                 //
118                 // Switch stack.
119                 //
120                 Stack switch_stack;
121                 
122                 static public bool InitialOptionExplicit = false;
123                 static public bool InitialOptionStrict = false;
124                 static public bool InitialOptionCompareBinary = true;
125
126                 bool OptionExplicit;
127                 bool OptionStrict;
128                 bool OptionCompareBinary;
129
130                 static public bool UseExtendedSyntax; // for ".mbs" files
131
132                 public override string[] extensions()
133                 {
134                         string [] list = { ".vb", ".mbs" };
135                         return list;
136                 }
137
138 %}
139
140 %token EOF
141 %token NONE   /* This token is never returned by our lexer */
142 %token ERROR  // This is used not by the parser, but by the tokenizer.
143               // do not remove.
144
145 /*
146  *These are the MonoBASIC keywords
147  */
148 %token ADDHANDLER
149 %token ADDRESSOF
150 %token ALIAS
151 %token AND
152 %token ANDALSO
153 %token ANSI
154 %token AS
155 %token ASSEMBLY
156 %token AUTO
157 %token BINARY
158 %token BOOLEAN  
159 %token BYREF
160 %token BYTE
161 %token BYVAL    
162 %token CALL
163 %token CASE     
164 %token CATCH    
165 %token CBOOL
166 %token CBYTE
167 %token CCHAR    
168 %token CDATE
169 %token CDEC
170 %token CDBL
171 %token CHAR     
172 %token CINT
173 %token CLASS
174 %token CLNG
175 %token COBJ
176 %token COMPARE  
177 %token CONST    
178 %token CSHORT   
179 %token CSNG
180 %token CSTR
181 %token CTYPE
182 %token DATE
183 %token DECIMAL  
184 %token DECLARE
185 %token DEFAULT  
186 %token DELEGATE 
187 %token DIM
188 %token DO       
189 %token DOUBLE   
190 %token EACH     
191 %token ELSE
192 %token ELSEIF
193 %token END      
194 %token ENUM     
195 %token EOL
196 %token ERASE
197 %token ERROR
198 %token EVENT
199 %token EXIT     
200 %token EXPLICIT 
201 %token FALSE    
202 %token FINALLY  
203 %token FOR      
204 %token FRIEND
205 %token FUNCTION
206 %token GET
207 %token GETTYPE
208 %token GOTO     
209 %token HANDLES
210 %token IF       
211 %token IMPLEMENTS
212 %token IMPORTS  
213 %token IN       
214 %token INHERITS
215 %token INTEGER  
216 %token INTERFACE
217 %token IS
218 %token LET
219 %token LIB      
220 %token LIKE     
221 %token LONG     
222 %token LOOP
223 %token ME
224 %token MOD
225 %token MODULE
226 %token MUSTINHERIT      
227 %token MUSTOVERRIDE
228 %token MYBASE
229 %token MYCLASS
230 %token NAMESPACE
231 %token NEW
232 %token NEXT     
233 %token NOT
234 %token NOTHING
235 %token NOTINHERITABLE
236 %token NOTOVERRIDABLE
237 %token OBJECT   
238 %token OFF
239 %token ON
240 %token OPTION   
241 %token OPTIONAL 
242 %token OR
243 %token ORELSE
244 %token OVERLOADS
245 %token OVERRIDABLE      
246 %token OVERRIDES        
247 %token PARAM_ARRAY
248 %token PRESERVE
249 %token PRIVATE  
250 %token PROPERTY
251 %token PROTECTED
252 %token PUBLIC
253 %token RAISEEVENT
254 %token READONLY 
255 %token REDIM
256 %token REM
257 %token REMOVEHANDLER
258 %token RESUME   
259 %token RETURN
260 %token SELECT
261 %token SET
262 %token SHADOWS
263 %token SHARED
264 %token SHORT    
265 %token SINGLE
266 %token SIZEOF   
267 %token STATIC   
268 %token STEP
269 %token STOP
270 %token STRICT   
271 %token STRING
272 %token STRUCTURE
273 %token SUB
274 %token SYNCLOCK
275 %token TEXT
276 %token THEN
277 %token THROW
278 %token TO
279 %token TRUE     
280 %token TRY      
281 %token TYPEOF   
282 %token UNICODE
283 %token UNTIL
284 %token VARIANT  
285 %token WHEN     
286 %token WHILE    
287 %token WITH
288 %token WITHEVENTS
289 %token WRITEONLY
290 %token XOR
291 %token YIELD // MonoBASIC extension
292
293 /* MonoBASIC single character operators/punctuation. */
294
295 %token OPEN_BRACKET  "["
296 %token CLOSE_BRACKET "]"
297 %token OPEN_PARENS   "("
298 %token OPEN_BRACE    "{"
299 %token CLOSE_BRACE   "}"
300 %token CLOSE_PARENS  ")"
301 %token DOT           "."
302 %token COMMA         ","
303 %token COLON         ":"
304
305 %token PLUS           "+"
306 %token MINUS          "-"
307 %token ASSIGN         "="
308 %token OP_LT          "<"
309 %token OP_GT          ">"
310 %token STAR           "*"
311 %token PERCENT        "%"
312 %token DIV            "/"
313 %token OP_EXP         "^"
314 %token INTERR         "?"
315 %token OP_IDIV        "\\"
316 %token OP_CONCAT      "&"
317 %token ATTR_ASSIGN ":="
318
319 /* MonoBASIC multi-character operators. */
320 %token OP_LE                  "<="
321 %token OP_GE                  ">="
322 //%token OP_EQ                  "=="
323 %token OP_NE                  "<>"
324 //%token OP_AND                 "and"
325 //%token OP_OR                  "or"
326 %token OP_XOR                 "xor"
327 %token OP_MODULUS             //"mod"
328 %token OP_MULT_ASSIGN         "*="
329 %token OP_DIV_ASSIGN          "/="
330 %token OP_IDIV_ASSIGN         "\\="
331 %token OP_ADD_ASSIGN          "+="
332 %token OP_SUB_ASSIGN          "-="
333 %token OP_CONCAT_ASSIGN       "&="
334 %token OP_EXP_ASSIGN          "^="
335
336 /* Numbers */
337 %token LITERAL_INTEGER           "int literal"
338 %token LITERAL_SINGLE            "float literal"
339 %token LITERAL_DOUBLE            "double literal"
340 %token LITERAL_DECIMAL           "decimal literal"
341 %token LITERAL_CHARACTER         "character literal"
342 %token LITERAL_STRING            "string literal"
343
344 %token IDENTIFIER
345
346 /* Add precedence rules to solve dangling else s/r conflict */
347 %nonassoc LOWPREC
348 %nonassoc IF
349 %nonassoc ELSE
350 %right ASSIGN
351 %left OP_OR
352 %left OP_AND
353 %left BITWISE_OR
354 %left BITWISE_AND
355 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
356 %left PLUS MINUS
357 %left STAR DIV PERCENT
358 %right BITWISE_NOT CARRET UMINUS
359 %nonassoc OP_INC OP_DEC
360 %left OPEN_PARENS
361 %left OPEN_BRACKET OPEN_BRACE
362 %left DOT
363 %right NOT
364 %nonassoc HIGHPREC
365
366 %start compilation_unit
367 %%
368
369 compilation_unit
370         : opt_option_directives
371           opt_imports_directives 
372           opt_attributes
373           opt_declarations 
374           EOF
375           {
376                 $$ = $4;
377           }
378         ;
379           
380 opt_option_directives
381         : /* empty */
382         | option_directives
383         ;
384         
385 option_directives
386         : option_directive
387         | option_directives option_directive
388         ;
389         
390 option_directive
391         : option_explicit_directive
392         | option_strict_directive
393         | option_compare_directive
394         ;
395         
396 on_off
397         : /* empty */
398           {
399                   $$ = (object)true;
400           }
401         | ON
402           {
403                   $$ = (object)true;
404           }
405         | OFF
406           {
407                   $$ = (object)false;
408           }
409         ;
410           
411 text_or_binary
412         : BINARY
413           {
414                   $$ = (object)true;
415           }
416         | TEXT
417           {
418                   $$ = (object)false;
419           }
420         ;
421           
422 option_explicit_directive
423         : OPTION EXPLICIT on_off EOL
424           {
425                 if (!UseExtendedSyntax)
426                         OptionExplicit = (bool)$3;
427                 else
428                         Report.Warning (
429                                 9999, lexer.Location, 
430                                 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
431           }
432         ;
433           
434                         
435 option_strict_directive
436         : OPTION STRICT on_off EOL
437           {
438                 if (!UseExtendedSyntax)
439                         OptionStrict = (bool)$3;
440                 else
441                         Report.Warning (
442                                 9999, lexer.Location, 
443                                 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
444           }
445         ;
446           
447 option_compare_directive
448         : OPTION COMPARE text_or_binary EOL
449           {
450                 OptionCompareBinary = (bool)$3;
451           }
452         ;
453
454 opt_declarations
455         : /* empty */
456         | declarations
457         ;
458
459 declarations
460         : declaration
461         | declarations declaration
462         ;
463         
464 declaration
465         : namespace_declaration
466         | type_declaration
467           {
468                 string name = "";
469                 int mod_flags;
470
471                 if ($1 is Class){
472                         Class c = (Class) $1;
473                         mod_flags = c.ModFlags;
474                         name = c.Name;
475                 } else if ($1 is Struct){
476                         Struct s = (Struct) $1;
477                         mod_flags = s.ModFlags;
478                         name = s.Name;
479                 } else if ($1 is Module){
480                         Module m = (Module) $1;
481                         mod_flags = m.ModFlags;
482                         name = m.Name;                  
483                 } else
484                         break;
485
486                 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
487                         Report.Error (
488                                 1527, lexer.Location, 
489                                 "Namespace elements cannot be explicitly " +
490                                 "declared private or protected in '" + name + "'");
491                 }
492           }
493         ;
494
495 identifier
496         : IDENTIFIER
497         | BINARY
498         | TEXT
499         | COMPARE
500         | EXPLICIT
501         | OFF
502         ;
503           
504 qualified_identifier
505         : identifier
506         | qualified_identifier DOT identifier 
507           { 
508             $$ = (($1).ToString ()) + "." + ($3.ToString ()); 
509           }
510         ;
511 opt_imports_directives
512         : /* empty */
513         | imports_directives
514         ;
515
516 imports_directives
517         : imports_directive 
518         | imports_directives imports_directive 
519         ;
520
521 imports_directive
522         : IMPORTS imports_terms EOL
523         ;
524
525 imports_terms
526         : imports_term
527         | imports_terms COMMA imports_terms
528         ;
529         
530 imports_term
531         : qualified_identifier
532           {
533                 current_namespace.Using ((string) $1, lexer.Location);
534           }
535         | qualified_identifier ASSIGN qualified_identifier
536           {
537                 current_namespace.UsingAlias ((string) $1, (string) $3, lexer.Location);
538           }
539         ;
540
541 opt_attributes
542         : /* empty */
543         | attribute_sections    { $$ = $1; }
544         ;
545
546 attribute_sections
547         : attribute_section
548           { 
549                 AttributeSection sect = (AttributeSection) $1;
550
551                 if (sect.Target == "assembly") 
552                         RootContext.AddGlobalAttributeSection (current_container, sect);
553                 
554                 $$ = new Attributes ((AttributeSection) $1, lexer.Location);
555                 
556           }     
557           /* 
558              FIXME: we should check if extended syntax is enabled;
559                     otherwise an exception should be thrown since VB.NET 
560                     only allows one attribute section 
561           */  
562         | attribute_sections attribute_section
563           {
564                 Attributes attrs = null;
565                 AttributeSection sect = (AttributeSection) $2;
566
567                 if (sect.Target == "assembly")
568                         RootContext.AddGlobalAttributeSection (current_container, sect);
569
570                 if ($1 != null) {
571                         attrs = (Attributes) $1;
572                         attrs.AddAttributeSection (sect);
573                 }
574                 
575                 $$ = attrs;
576           }     
577         ;
578         
579 attribute_section
580         : OP_LT attribute_target_specifier attribute_list OP_GT
581           { 
582                 string target = null;
583                 
584                 if ($2 != null)
585                         target = (string) $2;
586                 
587                 $$ = new AttributeSection (target, (ArrayList) $3);
588           }     
589         | OP_LT attribute_list OP_GT
590           {
591                 $$ = new AttributeSection (null, (ArrayList) $2);
592           }     
593         ; 
594
595 attribute_target_specifier
596         : attribute_target COLON
597           {
598                 $$ = $1;
599           }
600         ;
601
602 attribute_target
603         : identifier
604           {
605                 CheckAttributeTarget ((string) $1);
606                 $$ = $1;
607           }
608         | EVENT  { $$ = "event"; }        
609         | RETURN { $$ = "return"; }
610         ;
611         
612 attribute_list
613         : attribute 
614           {
615                 ArrayList attrs = new ArrayList ();
616                 attrs.Add ($1);
617
618                 $$ = attrs;
619                
620           }     
621         | attribute_list COMMA attribute
622           {
623                 ArrayList attrs = (ArrayList) $1;
624                 attrs.Add ($3);
625
626                 $$ = attrs;
627           }     
628         ;
629         
630 attribute 
631         : attribute_name
632           {
633                 $$ = lexer.Location;
634           }
635           opt_attribute_arguments
636           {
637                 $$ = new Mono.CSharp.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
638           }       
639         ;
640         
641 attribute_name
642         : type_name 
643         ;
644                         
645 opt_attribute_arguments
646         : /* empty */   { $$ = null; }
647         | OPEN_PARENS attribute_arguments CLOSE_PARENS
648           {
649                 $$ = $2;
650           }     
651         ;
652         
653 attribute_arguments
654         : opt_positional_argument_list
655           {
656                 if ($1 == null)
657                         $$ = null;
658                 else {
659                         ArrayList args = new ArrayList ();
660                         args.Add ($1);
661                 
662                         $$ = args;
663                 }
664           }
665         | positional_argument_list COMMA named_argument_list
666           {
667                 ArrayList args = new ArrayList ();
668                 args.Add ($1);
669                 args.Add ($3);
670
671                 $$ = args;
672           }
673         | named_argument_list
674           {
675                 ArrayList args = new ArrayList ();
676                 args.Add (null);
677                 args.Add ($1);
678                 
679                 $$ = args;
680           }
681         ;
682
683
684 opt_positional_argument_list
685         : /* empty */           { $$ = null; } 
686         | positional_argument_list
687         ;
688
689 positional_argument_list
690         : expression
691           {
692                 ArrayList args = new ArrayList ();
693                 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
694
695                 $$ = args;
696           }
697         | positional_argument_list COMMA expression
698          {
699                 ArrayList args = (ArrayList) $1;
700                 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
701
702                 $$ = args;
703          }
704         ;
705
706 named_argument_list
707         : named_argument
708           {
709                 ArrayList args = new ArrayList ();
710                 args.Add ($1);
711
712                 $$ = args;
713           }
714         | named_argument_list COMMA named_argument
715           {       
716                 ArrayList args = (ArrayList) $1;
717                 args.Add ($3);
718
719                 $$ = args;
720           }
721         ;
722
723 named_argument
724         : identifier ATTR_ASSIGN expression
725           {
726                 $$ = new DictionaryEntry (
727                         (string) $1, 
728                         new Argument ((Expression) $3, Argument.AType.Expression));
729           }
730         ;
731                                 
732 namespace_declaration
733         : opt_attributes NAMESPACE qualified_identifier EOL
734           {
735                 Attributes attrs = (Attributes) $1;
736
737                 if (attrs != null) {
738                         foreach (AttributeSection asec in attrs.AttributeSections)
739                                 if (asec.Target == "assembly")
740                                         RootContext.AddGlobalAttributeSection (current_container, asec);
741                 }
742                           
743                 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
744           } 
745           opt_imports_directives
746           opt_declarations
747           END NAMESPACE EOL
748           { 
749                 current_namespace = current_namespace.Parent;
750           }
751         ;
752
753 type_declaration
754         : opt_attributes 
755           opt_modifiers 
756           { 
757                 current_attributes = (Attributes) $1; 
758                 current_modifiers = (int) $2; 
759           }       
760           type_spec_declaration
761         ;
762
763 type_spec_declaration
764         : class_declaration
765         | module_declaration
766         | interface_declaration
767         | delegate_declaration
768         | struct_declaration
769         | enum_declaration
770         ;
771
772 class_declaration
773         : CLASS identifier EOL opt_class_base
774           {
775                 Class new_class;
776                 string name;
777                 
778                 name = MakeName ((string) $2);
779                 new_class = new Class (current_container, name, current_modifiers, 
780                                        (Attributes) current_attributes, lexer.Location);
781
782                 current_container = new_class;
783                 current_container.Namespace = current_namespace;
784                 RootContext.Tree.RecordDecl (name, new_class);
785           }
786           opt_class_member_declarations
787           END CLASS EOL
788           {
789                 Class new_class = (Class) current_container;
790                 new_class.Bases = (ArrayList) $4;       
791         
792                 current_container = current_container.Parent;
793                 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
794
795                 $$ = new_class;
796           }
797         ;
798
799 opt_class_base
800         : /* empty */           { $$ = null; }
801         | class_base            { $$ = $1; }
802         ;
803
804 class_base
805         : inherits_or_implements type_list EOL { $$ = $2; }
806         ;
807
808 inherits_or_implements
809         : INHERITS
810         | IMPLEMENTS
811         ;
812         
813 opt_modifiers
814         : /* empty */           { $$ = (int) 0; current_modifiers = 0; }
815         | modifiers             { $$ = $1; current_modifiers = (int) $1; }
816         ;
817         
818 modifiers
819         : modifier
820         | modifiers modifier
821           { 
822                 int m1 = (int) $1;
823                 int m2 = (int) $2;
824
825                 if ((m1 & m2) != 0) {
826                         Location l = lexer.Location;
827                         Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
828                 }
829                 $$ = (int) (m1 | m2);
830           }
831         ;
832
833 modifier
834         : PUBLIC                { $$ = Modifiers.PUBLIC; }
835         | PROTECTED             { $$ = Modifiers.PROTECTED; }
836         | PRIVATE               { $$ = Modifiers.PRIVATE; }
837         | SHARED                { $$ = Modifiers.STATIC; }
838         | FRIEND                { $$ = Modifiers.INTERNAL; }
839         | OVERRIDES             { $$ = Modifiers.OVERRIDE; }
840         | OVERRIDABLE           { $$ = Modifiers.VIRTUAL; }
841         | NOTOVERRIDABLE        { $$ = 0; }
842         | OVERLOADS             { $$ = 0; }
843         | MUSTINHERIT           { $$ = Modifiers.ABSTRACT; }
844         ;
845
846 module_declaration
847         : MODULE identifier EOL
848           { 
849                 Module new_module;
850                 string name;
851                 name = MakeName((string) $2);
852                 new_module = new Module(current_container, 
853                                                                 name, 
854                                                                 current_modifiers, // already checks then
855                                                                 (Attributes) current_attributes,
856                                                                 lexer.Location);
857                 current_container = new_module;
858                 current_container.Namespace = current_namespace;
859                 RootContext.Tree.RecordDecl(name, new_module);
860           }
861           opt_module_member_declarations
862           END MODULE EOL
863           {
864                 Module new_module = (Module)current_container;
865
866                 current_container = current_container.Parent;
867                 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
868
869                 $$ = new_module;
870           }
871         ;
872
873 opt_module_member_declarations
874         : /* empty */
875         | module_member_declarations
876         ;
877
878 module_member_declarations
879         : module_member_declaration
880         | module_member_declarations module_member_declaration
881         ;
882
883 module_member_declaration
884         :  opt_attributes
885            opt_modifiers
886            { 
887                 current_attributes = (Attributes) $1;
888                 current_modifiers = (int) $2 | (int)Modifiers.STATIC; // FIXME: for type_declaration it can result in trouble
889            }
890            module_member_declarator
891            {
892                 $$ = $3;
893            }
894         ;
895
896 module_member_declarator
897         :  static_constructor_declaration
898         |  method_declaration
899            { 
900                 Method method = (Method) $1;
901                 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
902            }    
903         |  field_declaration
904         |  withevents_declaration       /* This is a field but must be treated specially, see below */
905         |  constant_declaration
906         |  property_declaration                 
907         |  event_declaration    
908         |  type_declaration                     
909         ;
910         
911 constant_declaration // TODO: implement truly the logic
912         : CONST identifier ASSIGN constant_expression
913         | CONST identifier AS qualified_identifier ASSIGN constant_expression
914         ;
915            
916 opt_class_member_declarations
917         : /* empty */
918         | class_member_declarations
919         ;
920
921 class_member_declarations
922         : class_member_declaration
923         | class_member_declarations class_member_declaration
924         ;
925
926 class_member_declaration
927         :  opt_attributes
928            opt_modifiers
929            { 
930                 current_attributes = (Attributes) $1;
931                 current_modifiers = (int) $2; 
932            }
933            class_member_declarator
934            {
935                 $$ = $3;
936            }
937         ;
938
939 class_member_declarator
940         :  constructor_declaration
941         |  method_declaration
942            { 
943                 Method method = (Method) $1;
944                 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
945            }    
946         |  field_declaration
947         |  constant_declaration
948         |  property_declaration                 
949         |  event_declaration    
950         |  withevents_declaration       /* This is a field but must be treated specially, see below */
951         /*|  type_declaration  */
952         |  class_declaration            
953         |  enum_declaration             
954         ;
955         
956         
957 method_declaration
958         : sub_declaration
959         | func_declaration 
960         | must_override_declaration
961         ;
962         
963 must_override_declaration
964         : must_override_sub_declaration
965         | must_override_func_declaration        
966         ;
967         
968 must_override_sub_declaration
969         : MUSTOVERRIDE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
970           {     
971                 if (current_container is Module)
972                         Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
973                         
974                 if (current_container is Struct)
975                         Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
976                 
977                 current_modifiers |= Modifiers.ABSTRACT;
978                                         
979                 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
980                                             (Parameters) $5, null, null, lexer.Location);
981                                             
982                 if (!(current_container is Class))
983                         Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");               
984                         
985                 // FIXME ASAP: This will crash the compiler at resolution time                  
986                 $$ = method;                        
987           }
988         ;
989         
990 must_override_func_declaration
991         : MUSTOVERRIDE FUNCTION identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type EOL
992           {     
993                 if (current_container is Module)
994                         Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
995                         
996                 if (current_container is Struct)
997                         Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
998                                 
999                 current_modifiers |= Modifiers.ABSTRACT;
1000                                                         
1001                 Method method = new Method ((Expression) $8, (int) current_modifiers, (string) $3,
1002                                             (Parameters) $5, null, null, lexer.Location);
1003                                             
1004                 if (!(current_container is Class))
1005                         Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1006                         
1007                 // FIXME ASAP: This will crash the compiler at resolution time                  
1008                 $$ = method;                                    
1009           }     
1010         ;
1011         
1012 sub_declaration
1013         : SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler opt_implement_clause EOL
1014           { 
1015                 current_local_parameters = (Parameters) $4;
1016                 start_block(); 
1017
1018                 /* This is WEIRD: declaring a method (sub) in a module as static will
1019                    trigger a syntax error, but the same methods MUST be static in order
1020                    to be properly called
1021                 */
1022                 /* THIS SHOULD NOT BE NEEDED ANYMORE
1023                 if (current_container is Module) {
1024                         if ((current_modifiers & Modifiers.STATIC) != 0) {
1025                                 Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
1026                         }
1027                         else
1028                         {
1029                                 current_modifiers = Modifiers.STATIC;
1030                         }
1031                 
1032                 }
1033                 */
1034                 // Structure members are Public by default                      
1035                 if ((current_container is Struct) && (current_modifiers == 0))
1036                         current_modifiers = Modifiers.PUBLIC;                   
1037           }
1038           opt_statement_list 
1039           END SUB EOL
1040           {
1041                 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1042                                             (Parameters) current_local_parameters, null, (Expression) $7, 
1043                                             lexer.Location);
1044         
1045                 method.Block = (Block) end_block();
1046                 $$ = method;
1047
1048                 if ($6 != null) { /* we have an event handler to take care of */
1049                         // This wouldn't work: AddHandler ((Expression)$6, (string) $2);
1050                         string evt_def = ((MemberAccess)$6).ToString();
1051                         int pos = evt_def.LastIndexOf (".");
1052                         string evt_target = ((string) $2).Substring (0, pos);
1053
1054                         foreach (Property p in current_container.Properties) {
1055                                 if (p.Name == evt_target) {
1056                                         // FIXME: See below 
1057                                         // RemoveHandler (p.Set.Block, (Expression)$6, (string) $2);
1058                                         AddHandler (p.Set.Block, (Expression)$6, (string) $2);
1059                                         break;
1060                                 }
1061                         }                               
1062                 }       
1063           }       
1064         ;
1065         
1066 func_declaration
1067         : FUNCTION identifier 
1068           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type opt_implement_clause EOL
1069           { 
1070                 
1071                 current_local_parameters = (Parameters) $4;
1072                 start_block(); 
1073         
1074                 /* This is WEIRD: declaring a method (sub) in a module as static will
1075                    trigger a syntax error, but the same methods MUST be static in order
1076                    to be properly called
1077                 */
1078                 /* THIS SHOULD NOT BE NEEDED ANYMORE
1079                 if (current_container is Module) {
1080                         if ((current_modifiers & Modifiers.STATIC) != 0) {
1081                                 Report.Error (30810, lexer.Location, "Methods cannot be declared 'Static'");
1082                         }
1083                         else
1084                         {
1085                                 current_modifiers |= Modifiers.STATIC;
1086                         }                       
1087                 }
1088                 */
1089                 // Structure members are Public by default                      
1090                 if ((current_container is Struct) && (current_modifiers == 0))
1091                         current_modifiers = Modifiers.PUBLIC;                           
1092                 // Add local var declaration
1093                 // for return value
1094                 ArrayList retval = new ArrayList ();
1095                 retval.Add (new VariableDeclaration ((string) $2, (Expression) $7, lexer.Location));
1096                 declare_local_variables ((Expression) $7, retval, lexer.Location);
1097           }       
1098           opt_statement_list
1099           END FUNCTION EOL
1100           {
1101                 Method method = new Method ((Expression) $7, (int) current_modifiers, (string) $2,
1102                                             (Parameters) current_local_parameters, null, 
1103                                             (Expression) $7, lexer.Location);
1104                 method.Block = end_block();
1105                 $$ = method;
1106         /*Console.WriteLine ("Declaring Function '{0}' with {1} statements and {2} arguments", 
1107                                 current_container.Name + "." + (string) $2, 
1108                                 method.Block.statements.Count,
1109                                 current_local_parameters.FixedParameters != null ? current_local_parameters.FixedParameters.Length : 0);
1110 */
1111           }       
1112         ;               
1113
1114 struct_declaration
1115         : STRUCTURE identifier EOL
1116           opt_implement_clause
1117           {
1118                 Struct new_struct;
1119                 string full_struct_name = MakeName ((string) $2);
1120
1121                 new_struct = new Struct (current_container, full_struct_name, 
1122                                          (int) current_modifiers,
1123                                          (Attributes) current_attributes, lexer.Location);
1124                 current_container = new_struct;
1125                 current_container.Namespace = current_namespace;
1126                 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1127           }
1128           opt_struct_member_declarations
1129           {
1130                 Struct new_struct = (Struct) current_container;
1131
1132                 if ($4 != null)
1133                         new_struct.Bases = (ArrayList) $4;
1134
1135                 current_container = current_container.Parent;
1136                 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1137                 $$ = new_struct;
1138           }
1139           END STRUCTURE EOL
1140         ;
1141         
1142 opt_struct_member_declarations
1143         : /* empty */
1144         | struct_member_declarations
1145         ;
1146
1147 struct_member_declarations
1148         : struct_member_declaration
1149         | struct_member_declarations struct_member_declaration
1150         ;
1151
1152 struct_member_declaration
1153         : opt_modifiers
1154           struct_member_declarator
1155         ;
1156 struct_member_declarator        
1157         : field_declaration
1158         //| constant_declaration
1159         | method_declaration
1160         | property_declaration
1161         | event_declaration
1162         | constructor_declaration
1163         | type_declaration
1164
1165         /*
1166          * This is only included so we can flag error 575:
1167          * destructors only allowed on class types
1168          */
1169         //| destructor_declaration
1170         ;
1171         
1172 event_declaration
1173         : EVENT identifier AS type EOL
1174           {
1175                 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1176
1177                 Event e = new Event ((Expression) $4, var.identifier, 
1178                                      null, current_modifiers, null, null, 
1179                                      current_attributes, lexer.Location);
1180
1181                 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1182
1183           }
1184 //      | EVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1185 //        {
1186 //              throw new NotSupportedException();
1187 //        }
1188         ;       
1189
1190 enum_declaration
1191         : ENUM identifier opt_type_spec EOL
1192           opt_enum_member_declarations
1193           { 
1194                 Location enum_location = lexer.Location;
1195                 string full_name = MakeName ((string) $2);
1196                 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1197                 ArrayList enum_members = (ArrayList) $5;
1198                 
1199                 Mono.CSharp.Enum e = new Mono.CSharp.Enum (current_container, enum_type, 
1200                                         (int) current_modifiers, full_name, 
1201                                         (Attributes) current_attributes, enum_location);
1202                 
1203                 foreach (VariableDeclaration ev in enum_members) {
1204                         Location loc = (Location) ev.Location;
1205
1206                         CheckDef (e.AddEnumMember (ev.identifier, 
1207                                                    (Expression) ev.expression_or_array_initializer,
1208                                                    loc, ev.OptAttributes), ev.identifier, loc);
1209                 }
1210
1211                 e.Namespace = current_namespace;
1212
1213                 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1214                 RootContext.Tree.RecordDecl (full_name, e);
1215
1216           }
1217           END ENUM EOL
1218         ;
1219
1220 opt_enum_member_declarations
1221         : /* empty */                   { $$ = new ArrayList (); }
1222         | enum_member_declarations      { $$ = $1; }
1223         ;
1224
1225 enum_member_declarations
1226         : enum_member_declaration 
1227           {
1228                 ArrayList l = new ArrayList ();
1229
1230                 l.Add ($1);
1231                 $$ = l;
1232           }
1233         | enum_member_declarations  enum_member_declaration
1234           {
1235                 ArrayList l = (ArrayList) $1;
1236
1237                 l.Add ($2);
1238
1239                 $$ = l;
1240           }
1241         ;
1242
1243 enum_member_declaration
1244         : opt_attributes identifier EOL
1245           {
1246                 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1247           }
1248         | opt_attributes identifier
1249           {
1250                   $$ = lexer.Location;
1251           }
1252           ASSIGN expression EOL
1253           { 
1254                 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1255           }
1256         ;
1257                 
1258 interface_declaration
1259         : INTERFACE identifier EOL
1260           {
1261                 Interface new_interface;
1262                 string full_interface_name = MakeName ((string) $2);
1263
1264                 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1265                                                (Attributes) current_attributes, lexer.Location);
1266                 if (current_interface != null) {
1267                         Location l = lexer.Location;
1268                         Report.Error (-2, l, "Internal compiler error: interface inside interface");
1269                 }
1270                 current_interface = new_interface;
1271                 new_interface.Namespace = current_namespace;
1272                 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1273           }
1274           opt_interface_base
1275           interface_body
1276           { 
1277                 Interface new_interface = (Interface) current_interface;
1278
1279                 if ($5 != null)
1280                         new_interface.Bases = (ArrayList) $5;
1281
1282                 current_interface = null;
1283                 CheckDef (current_container.AddInterface (new_interface),
1284                           new_interface.Name, new_interface.Location);
1285
1286           }
1287           END INTERFACE EOL
1288         ;
1289
1290 opt_interface_base
1291         : /* empty */                     { $$ = null; }
1292         | interface_base
1293         ;
1294
1295 interface_base
1296         : INHERITS interface_type_list    { $$ = $2; }
1297         ;
1298
1299 interface_type_list
1300         : interface_type
1301           {
1302                 ArrayList interfaces = new ArrayList ();
1303
1304                 interfaces.Add ($1);
1305                 $$ = interfaces;
1306           }
1307         | interface_type_list COMMA interface_type
1308           {
1309                 ArrayList interfaces = (ArrayList) $1;
1310                 interfaces.Add ($3);
1311                 $$ = interfaces;
1312           }
1313         ;
1314
1315 interface_body
1316         : opt_interface_member_declarations
1317         ;
1318
1319 opt_interface_member_declarations
1320         : /* empty */
1321         | interface_member_declarations
1322         ;
1323
1324 interface_member_declarations
1325         : interface_member_declaration
1326         | interface_member_declarations interface_member_declaration
1327         ;
1328
1329 interface_member_declaration
1330         : interface_method_declaration          
1331           { 
1332                 InterfaceMethod m = (InterfaceMethod) $1;
1333
1334                 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1335           }
1336         | interface_property_declaration        
1337           { 
1338                 InterfaceProperty p = (InterfaceProperty) $1;
1339                 
1340                 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1341           }
1342         | interface_event_declaration 
1343           { 
1344                 InterfaceEvent e = (InterfaceEvent) $1;
1345
1346                 CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1347           }
1348         ;
1349
1350 opt_new
1351         : /* empty */   { $$ = false; }
1352         | NEW           { $$ = true; }
1353         ;
1354         
1355 interface_method_declaration
1356         : SUB identifier
1357           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1358           {
1359                 $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
1360                                           (Parameters) $4, current_attributes, lexer.Location);
1361           }
1362         | FUNCTION identifier
1363           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
1364           {
1365                 $$ = new InterfaceMethod (
1366                                           (Expression) $7, (string) $2, false, (Parameters) $4,
1367                                           current_attributes, lexer.Location);
1368           }
1369         ;
1370
1371 interface_property_declaration
1372         : PROPERTY identifier
1373           OPEN_PARENS
1374           opt_formal_parameter_list
1375           CLOSE_PARENS opt_type_spec EOL
1376           {
1377                 // FIXME we MUST pass property parameters
1378                 $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
1379                                             true, true, current_attributes,
1380                                             lexer.Location);
1381           }
1382         ;
1383         
1384 opt_access_specifier
1385         : /* empty */
1386         | READONLY      { $$ = Modifiers.READONLY; }
1387         | WRITEONLY     { $$ = 0; }
1388         | DEFAULT       { $$ = 0; }
1389         ;       
1390
1391 interface_event_declaration
1392         : opt_attributes opt_new EVENT type identifier EOL
1393           {
1394                 $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
1395                                          lexer.Location);
1396           }
1397         ;
1398
1399 property_declaration
1400           : opt_access_specifier PROPERTY identifier opt_property_parameters AS type opt_implement_clause EOL
1401           {
1402                 get_implicit_value_parameter_type = (Expression) $6;
1403                 get_implicit_value_parameter_name = (string) $3;
1404                 
1405                 current_local_parameters = (Parameters) $4;
1406                 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
1407                         get_parameters = current_local_parameters.Copy (lexer.Location);
1408                         set_parameters = current_local_parameters.Copy (lexer.Location);
1409                 }
1410                 else
1411                 {
1412                         get_parameters = Parameters.EmptyReadOnlyParameters;
1413                         set_parameters = new Parameters (null, null ,lexer.Location);           
1414                 }
1415                 lexer.PropertyParsing = true;
1416
1417                 $$ = lexer.Location;
1418           }
1419           accessor_declarations 
1420           END PROPERTY EOL
1421           {
1422                 lexer.PropertyParsing = false;
1423
1424                 Property prop;
1425                 Pair pair = (Pair) $10;
1426                 Accessor get_block = (Accessor) pair.First;
1427                 Accessor set_block = (Accessor) pair.Second;
1428
1429                 Location loc = lexer.Location;
1430                 
1431                 // Structure members are Public by default                      
1432                 if ((current_container is Struct) && (current_modifiers == 0))
1433                         current_modifiers = Modifiers.PUBLIC;                           
1434                         
1435                 prop = new Property ((Expression) $6, (string) $3, current_modifiers, get_block, set_block,
1436                                      current_attributes, loc, set_implicit_value_parameter_name, 
1437                                      get_parameters, set_parameters, (Expression) $7);
1438                 
1439                 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1440                 get_implicit_value_parameter_type = null;
1441                 set_implicit_value_parameter_type = null;
1442                 get_parameters = null;
1443                 set_parameters = null;
1444                 current_local_parameters = null;
1445           }
1446         ;
1447
1448 opt_property_parameters
1449         : /* empty */
1450           {
1451                 $$ = Parameters.EmptyReadOnlyParameters;
1452           }
1453         | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1454           {
1455                 $$ = $2;
1456           }
1457         ;
1458         
1459 opt_implement_clause
1460         : /* empty */
1461           {
1462                 $$ = null;
1463           }
1464         | IMPLEMENTS qualified_identifier
1465           {
1466                 $$ = DecomposeQI ((string)$2, lexer.Location);
1467           }     
1468         ;
1469         
1470 accessor_declarations
1471         : get_accessor_declaration opt_set_accessor_declaration
1472           { 
1473                 $$ = new Pair ($1, $2);
1474           }
1475         | set_accessor_declaration opt_get_accessor_declaration
1476           {
1477                 $$ = new Pair ($2, $1);
1478           }
1479         ;
1480
1481 opt_get_accessor_declaration
1482         : /* empty */                   { $$ = null; }
1483         | get_accessor_declaration
1484         ;
1485
1486 opt_set_accessor_declaration
1487         : /* empty */                   { $$ = null; }
1488         | set_accessor_declaration
1489         ;
1490
1491 get_accessor_declaration
1492         : opt_attributes GET EOL
1493           {
1494                 current_local_parameters = get_parameters;
1495                 
1496                 lexer.PropertyParsing = false;
1497                 
1498                 start_block();  
1499                 // Add local var declaration
1500                 // for return value
1501                 ArrayList retval = new ArrayList ();
1502                 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1503                 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);    
1504                 
1505           }
1506           opt_statement_list
1507           END GET EOL
1508           {
1509                 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1510                 current_local_parameters = null;
1511                 lexer.PropertyParsing = true;
1512           }
1513         ;
1514
1515 set_accessor_declaration
1516         : opt_attributes SET opt_set_parameter EOL
1517           {
1518                 Parameter implicit_value_parameter = new Parameter (
1519                         set_implicit_value_parameter_type, 
1520                         set_implicit_value_parameter_name, 
1521                         Parameter.Modifier.NONE, null);
1522
1523                 current_local_parameters = set_parameters;
1524                 current_local_parameters.AppendParameter (implicit_value_parameter);
1525                 
1526                 start_block();
1527                 lexer.PropertyParsing = false;
1528           }
1529           opt_statement_list
1530           END SET EOL
1531           {
1532                 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1533                 current_local_parameters = null;
1534                 lexer.PropertyParsing = true;
1535           }
1536         ;
1537                 
1538 opt_set_parameter
1539         : /* empty */
1540         {
1541                 set_implicit_value_parameter_type = (Expression) TypeManager.system_object_expr;
1542                 set_implicit_value_parameter_name = "Value";
1543         }       
1544         | OPEN_PARENS opt_identifier opt_type_spec CLOSE_PARENS
1545         {
1546                 /* FIXME: possible syntax error which must be caught
1547                    Set ( As <type>) is currently (and wrongly so) legal
1548                 */
1549                 set_implicit_value_parameter_type = (Expression) $3;
1550                 if ($2 != null)
1551                         set_implicit_value_parameter_name = (string) $2;
1552                 else
1553                         set_implicit_value_parameter_name = "Value";
1554         }
1555         ;
1556                         
1557 field_declaration
1558         : opt_dim_stmt 
1559           variable_declarators EOL
1560           {               
1561                 int mod = (int) current_modifiers;
1562                 
1563
1564                 VariableDeclaration.FixupTypes ((ArrayList) $2);
1565                 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1566                 
1567                 if (current_container is Module)
1568                         mod = mod | Modifiers.STATIC;
1569                         
1570                 // Structure members are Public by default                      
1571                 if ((current_container is Struct) && (mod == 0))
1572                         mod = Modifiers.PUBLIC;                 
1573                                         
1574                 foreach (VariableDeclaration var in (ArrayList) $2){
1575                         Location l = var.Location;
1576
1577                         Field field = new Field (var.type, mod, var.identifier, 
1578                                                  var.expression_or_array_initializer, 
1579                                                  (Attributes) null, l);
1580
1581                         CheckDef (current_container.AddField (field), field.Name, l);
1582                 }
1583           }
1584         ;
1585         
1586 withevents_declaration
1587         : WITHEVENTS variable_declarators EOL
1588           {
1589                 /* WithEvents Fields must be resolved into properties
1590                    with a bit of magic behind the scenes */
1591                   
1592                 VariableDeclaration.FixupTypes ((ArrayList) $2);
1593                 
1594                 foreach (VariableDeclaration var in (ArrayList) $2) {
1595                         // 1 - We create a private field
1596                         Location l = var.Location;
1597                         Property prop;
1598                         if ((current_modifiers & Modifiers.STATIC) > 0) 
1599                                 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
1600                         
1601                         Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier, 
1602                                                  var.expression_or_array_initializer, 
1603                                                  (Attributes) null, l);
1604
1605                         CheckDef (current_container.AddField (field), field.Name, l);   
1606                         
1607                         // 2 - Public property
1608                                 
1609                         prop = BuildSimpleProperty (var.type, (string) var.identifier, 
1610                                                 field, (int) current_modifiers, 
1611                                                 (Attributes) current_attributes, l);
1612                         
1613                         CheckDef (current_container.AddProperty (prop), prop.Name, l);
1614                 }               
1615           }
1616         ;
1617         
1618 opt_dim_stmt 
1619         : /* empty */
1620         | DIM
1621         ; 
1622                 
1623 delegate_declaration
1624         : DELEGATE SUB  
1625           identifier OPEN_PARENS 
1626           opt_formal_parameter_list
1627           CLOSE_PARENS 
1628           EOL
1629           {
1630                 Location l = lexer.Location;
1631                 Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (current_container, TypeManager.system_void_expr, 
1632                                              (int) current_modifiers, 
1633                                              MakeName ((string) $3), (Parameters) $5, 
1634                                              (Attributes) current_attributes, l);
1635                                                   
1636                 del.Namespace = current_namespace;
1637                 CheckDef (current_container.AddDelegate (del), del.Name, l);
1638           }     
1639         | DELEGATE FUNCTION       
1640           identifier OPEN_PARENS 
1641           opt_formal_parameter_list
1642           CLOSE_PARENS AS type
1643           {
1644                 Location l = lexer.Location;
1645                 Mono.CSharp.Delegate del = new Mono.CSharp.Delegate (
1646                         current_container,
1647                         (Expression) $8, (int) current_modifiers, MakeName ((string) $3), 
1648                         (Parameters) $5, (Attributes) current_attributes, l);
1649
1650                 del.Namespace = current_namespace;
1651                 CheckDef (current_container.AddDelegate (del), del.Name, l);
1652           }
1653         ;
1654         
1655 opt_evt_handler
1656         : /* empty */
1657           {     $$ = null; }
1658         | HANDLES qualified_identifier
1659           {
1660                 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);     
1661           }
1662         | HANDLES MYBASE DOT qualified_identifier
1663           {
1664                 // FIXME: this is blatantly wrong and crash-prone
1665                 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
1666           }
1667         ;       
1668
1669 opt_empty_parens
1670         : /* empty */
1671         | OPEN_PARENS CLOSE_PARENS
1672         ;       
1673         
1674 static_constructor_declaration
1675         : SHARED SUB NEW opt_empty_parens EOL
1676           {
1677                 current_local_parameters = Parameters.EmptyReadOnlyParameters;
1678                 start_block();
1679                 oob_stack.Push (lexer.Location);
1680
1681                 Location l = (Location) oob_stack.Pop ();
1682                 $$ = new Constructor ((string) "New", Parameters.EmptyReadOnlyParameters, (ConstructorInitializer) null, l);
1683           }
1684           opt_statement_list
1685           { 
1686                 Constructor c = (Constructor) $1;
1687                 c.Block = (Block) end_block();
1688                 c.ModFlags = (int) current_modifiers;
1689                 c.OptAttributes = current_attributes;
1690                 
1691                 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1692                 current_local_parameters = null;
1693           }
1694           END SUB EOL
1695         
1696 constructor_declaration
1697         : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1698           {
1699                 current_local_parameters = (Parameters) $4;
1700                 start_block();
1701                 oob_stack.Push (lexer.Location);
1702
1703                 Location l = (Location) oob_stack.Pop ();
1704                 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
1705                 $1 = $$;
1706           }
1707           opt_statement_list
1708           { 
1709                 Constructor c = (Constructor) $1;
1710                 c.Block = (Block) end_block();
1711                 c.ModFlags = (int) current_modifiers;
1712                 c.OptAttributes = current_attributes;
1713                 
1714                 // FIXME: This should happen at grammar level, but doing it
1715                 // triggers a lot of conflicts/problems.
1716                 c.Initializer = FixConstructorInitializer (ref c.Block.statements);
1717
1718                 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1719                 current_local_parameters = null;
1720           }
1721           END SUB EOL
1722         ;
1723         
1724 opt_formal_parameter_list
1725         : /* empty */                   
1726           { 
1727                 $$ = Parameters.EmptyReadOnlyParameters; 
1728           }
1729         | formal_parameter_list 
1730           { 
1731                 $$ = $1;        
1732                 //Parameter p = ((Parameters) $1).FixedParameters[0];
1733           }
1734         ;
1735         
1736 formal_parameter_list
1737         : fixed_parameters              
1738           { 
1739                 ArrayList pars_list = (ArrayList) $1;
1740
1741                 Parameter [] pars = new Parameter [pars_list.Count];
1742                 pars_list.CopyTo (pars);
1743                 $$ = new Parameters (pars, null, lexer.Location); 
1744           } 
1745         | fixed_parameters COMMA parameter_array
1746           {
1747                 ArrayList pars_list = (ArrayList) $1;
1748
1749                 Parameter [] pars = new Parameter [pars_list.Count];
1750                 pars_list.CopyTo (pars);
1751
1752                 $$ = new Parameters (pars, (Parameter) $3, lexer.Location); 
1753           }
1754         | parameter_array 
1755           {
1756                 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1757           }
1758         ;
1759
1760 fixed_parameters
1761         : fixed_parameter       
1762           {
1763                 ArrayList pars = new ArrayList ();
1764
1765                 pars.Add ($1);
1766                 $$ = pars;
1767           }
1768         | fixed_parameters COMMA fixed_parameter
1769           {
1770                 ArrayList pars = (ArrayList) $1;
1771
1772                 pars.Add ($3);
1773                 $$ = $1;
1774           }
1775         ;
1776
1777 fixed_parameter
1778         : opt_attributes
1779           opt_parameter_modifier
1780           identifier opt_rank_specifier opt_type_spec opt_variable_initializer
1781           {
1782                 Parameter.Modifier pm = (Parameter.Modifier)$2;
1783                 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
1784                 Expression ptype;
1785                 
1786                 if (opt_parm && ($6 == null))
1787                         Report.Error (999, "Optional parameters must have a default value");
1788                 
1789                 if (opt_parm) {
1790                         if ((pm & Parameter.Modifier.REF) !=0)
1791                                 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
1792                         else
1793                                 pm = Parameter.Modifier.NONE;   //FIXME: should take into account BYREF
1794                 }       
1795                 
1796                 if ($4 == null)
1797                         ptype = (Expression) $5;
1798                 else
1799                 {
1800                         string t = ((Expression) $5).ToString() + (string) $4;
1801                         ptype = DecomposeQI (t, lexer.Location);
1802                 }                       
1803                 $$ = new Parameter (ptype, (string) $3, pm,
1804                                         (Attributes) $1, (Expression) $6, opt_parm);
1805           }
1806         ;
1807         
1808 parameter_array
1809         : PARAM_ARRAY identifier opt_parens AS type 
1810           { 
1811                 $$ = new Parameter ((Expression) $5, (string) $2, Parameter.Modifier.PARAMS, null);
1812                 // note  ("type must be a single-dimension array type"); 
1813           }
1814         ;
1815                 
1816 opt_parens
1817         : /* empty */
1818         | OPEN_PARENS CLOSE_PARENS
1819         ;
1820         
1821 opt_parameter_modifier
1822         : /* empty */           { $$ = Parameter.Modifier.VAL;  }
1823         | parameter_modifiers   { $$ = $1;                      }
1824         ;
1825
1826 parameter_modifiers
1827         : parameter_modifiers parameter_modifier        { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
1828         | parameter_modifier                            { $$ = $1;      }
1829         ;
1830         
1831 parameter_modifier
1832         : BYREF                 { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
1833         | BYVAL                 { $$ = Parameter.Modifier.VAL; }
1834         | OPTIONAL              { $$ = Parameter.Modifier.OPTIONAL; } 
1835         ;       
1836
1837 opt_statement_list
1838         : /* empty */
1839         | statement_list EOL
1840         ;
1841
1842 statement_list
1843         : statement 
1844         | statement_list EOL statement
1845         ;
1846         
1847 statement : 
1848             declaration_statement
1849             {
1850                 if ($1 != null && (Block) $1 != current_block){
1851                         current_block.AddStatement ((Statement) $1);
1852                         current_block = (Block) $1;
1853                 }
1854             }
1855           | embedded_statement 
1856             {
1857                 Statement s = (Statement) $1;
1858
1859                 current_block.AddStatement ((Statement) $1);
1860             } 
1861           | labeled_statement 
1862           | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
1863            {
1864                 AddHandler ((Expression) $2, (string) $5);
1865            }
1866           | RAISEEVENT identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1867             {
1868                 RaiseEvent ((string) $2, (ArrayList) $4);
1869             }
1870           ;     
1871
1872 labeled_statement
1873         : identifier COLON 
1874           {
1875                 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
1876
1877                 if (!current_block.AddLabel ((string) $1, labeled)){
1878                         Location l = lexer.Location;
1879                         Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
1880                 }       
1881                 current_block.AddStatement (labeled);
1882           }
1883           statement
1884         ;
1885
1886 embedded_statement
1887         : expression_statement
1888         | selection_statement
1889         | iteration_statement
1890         | try_statement
1891         | jump_statement 
1892         ;
1893         
1894 jump_statement
1895         : /*break_statement
1896         | continue_statement
1897         | goto_statement
1898         | throw_statement
1899         | */return_statement
1900         | exit_statement
1901         | yield_statement
1902         ;
1903                 
1904 exit_statement
1905         : EXIT exit_type
1906           {
1907                 $$ = new Exit ((ExitType)$2, lexer.Location);           
1908           }
1909         ;
1910         
1911 exit_type
1912         : DO            { $$ = ExitType.DO;             }
1913         | FOR           { $$ = ExitType.FOR;            }
1914         | WHILE         { $$ = ExitType.WHILE;          }
1915         | SELECT        { $$ = ExitType.SELECT;         }
1916         | SUB           { $$ = ExitType.SUB;            }
1917         | FUNCTION      { $$ = ExitType.FUNCTION;       }
1918         | PROPERTY      { $$ = ExitType.PROPERTY;       }
1919         | TRY           { $$ = ExitType.TRY;            }
1920         ;
1921 return_statement
1922         : RETURN opt_expression 
1923           {       
1924                 $$ = new Return ((Expression) $2, lexer.Location);
1925           }
1926         ;
1927                 
1928 iteration_statement
1929         : while_statement
1930         | do_statement
1931         | for_statement
1932         | foreach_statement
1933         ;
1934
1935 foreach_statement
1936         : FOR EACH identifier IN 
1937           {
1938                 oob_stack.Push (lexer.Location);
1939           }       
1940           expression EOL
1941           {
1942                 
1943                 start_block();
1944                 Block foreach_block = current_block;
1945                 Location l = lexer.Location;            
1946                 LocalVariableReference v = null;
1947                 VariableInfo vi;
1948
1949                 vi = foreach_block.GetVariableInfo ((string) $3);
1950                 if (vi != null) {
1951                         // Get a reference to this variable.
1952                         v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
1953                 }
1954         
1955                 oob_stack.Push (v);
1956           }       
1957           opt_statement_list
1958           NEXT opt_identifier
1959           {
1960                 Block foreach_block = current_block;
1961                 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
1962                 Block prev_block = end_block();
1963                 Location l = (Location) oob_stack.Pop ();
1964
1965                 Foreach f = null;
1966                 if (v != null) {
1967                         f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
1968                 }
1969                 
1970                 $$ = f;
1971           }       
1972         ;
1973
1974 yield_statement 
1975         : YIELD expression
1976           {
1977                 if (!UseExtendedSyntax)
1978                 {
1979                         ReportError9998();
1980                         $$ = null;
1981                 }
1982 /*              else
1983                         if (iterator_container == null){
1984                                 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
1985                                 $$ = null;
1986                         } else {
1987                                 iterator_container.SetYields ();
1988                                 $$ = new Yield ((Expression) $2, lexer.Location);
1989                         } */
1990           }
1991         | YIELD STOP
1992           {
1993                 if (!UseExtendedSyntax)
1994                 {
1995                         ReportError9998();
1996                         $$ = null;
1997                 }
1998 /*              else
1999                         if (iterator_container == null){
2000                                 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2001                                 $$ = null;
2002                         } else {
2003                                 iterator_container.SetYields ();
2004                                 $$ = new YieldBreak (lexer.Location);
2005                         } */
2006           }
2007         ;
2008
2009
2010
2011 try_statement
2012         : try_catch
2013         | try_catch_finally
2014         ;
2015                                 
2016 try_header
2017         : TRY EOL
2018           {   
2019                 start_block();  
2020           }
2021           opt_statement_list 
2022           opt_catch_clauses
2023           {
2024                 tmp_catch_clauses = (ArrayList) $5;
2025           }
2026         ;
2027                                         
2028 try_catch
2029         : try_header 
2030           END TRY
2031           { 
2032                 Catch g = null;
2033                 ArrayList s = new ArrayList ();
2034
2035                 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2036                         if (cc.IsGeneral)
2037                                 g = cc;
2038                         else
2039                                 s.Add (cc);
2040                 }
2041
2042                 // Now s contains the list of specific catch clauses
2043                 // and g contains the general one.
2044                 Block b = end_block();
2045
2046                 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2047           }       
2048         ;       
2049           
2050 try_catch_finally
2051         : try_header 
2052           { 
2053                 tmp_block = end_block(); 
2054           }     
2055           FINALLY EOL
2056           { 
2057                 start_block(); 
2058           }       
2059           opt_statement_list 
2060           END TRY
2061           {
2062                 Catch g = null;
2063                 ArrayList s = new ArrayList ();
2064                 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2065
2066                 if (catch_list != null){
2067                         foreach (Catch cc in catch_list) {
2068                                 if (cc.IsGeneral)
2069                                         g = cc;
2070                                 else
2071                                         s.Add (cc);
2072                         }
2073                 }
2074
2075                 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2076         
2077           }     
2078           ;             
2079
2080 opt_catch_clauses
2081         : /* empty */  {  $$ = null;  }
2082         | catch_clauses
2083         ;
2084
2085 catch_clauses
2086         : catch_clause 
2087           {
2088                 ArrayList l = new ArrayList ();
2089
2090                 l.Add ($1);
2091                 $$ = l;
2092           }
2093         | catch_clauses catch_clause
2094           {
2095                 ArrayList l = (ArrayList) $1;
2096
2097                 l.Add ($2);
2098                 $$ = l;
2099           }
2100         ;
2101
2102 opt_identifier
2103         : /* empty */   {  $$ = null;  }
2104         | identifier
2105         ;
2106
2107 catch_clause 
2108         : CATCH opt_catch_args EOL
2109         {
2110                 Expression type = null;
2111                 string id = null;
2112                 
2113                 if ($2 != null) {
2114                         DictionaryEntry cc = (DictionaryEntry) $2;
2115                         type = (Expression) cc.Key;
2116                         id   = (string) cc.Value;
2117                         
2118                         if (id != null){
2119                                 ArrayList one = new ArrayList ();
2120                                 Location loc = lexer.Location;
2121
2122                                 one.Add (new VariableDeclaration (id, null, loc));
2123
2124
2125                                 $1 = current_block;
2126                                 current_block = new Block (current_block);
2127                                 Block b = declare_local_variables (type, one, loc);
2128                                 current_block = b;
2129                         }
2130                 }
2131         
2132         } 
2133         opt_statement_list {
2134                 Expression type = null;
2135                 string id = null;
2136                 Block b_catch = current_block;
2137                 
2138                 if ($2 != null){
2139                         DictionaryEntry cc = (DictionaryEntry) $2;
2140                         type = (Expression) cc.Key;
2141                         id   = (string) cc.Value;
2142                         
2143                         if ($1 != null) {
2144                                 //
2145                                 // FIXME: I can change this for an assignment.
2146                                 //
2147                                 while (current_block != (Block) $1)
2148                                         current_block = current_block.Parent;
2149                         }
2150                 }
2151
2152                 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2153         }
2154         ;
2155
2156 opt_catch_args
2157         : /* empty */ {  $$ = null; }
2158         | catch_args
2159         ;         
2160
2161 catch_args 
2162         : identifier AS type
2163         {
2164                  $$ = new DictionaryEntry ($3, $1); 
2165         }
2166         ;
2167         
2168         
2169 do_statement
2170         : DO opt_do_construct EOL
2171           {
2172                 start_block();
2173                 oob_stack.Push (lexer.Location);
2174           }     
2175           opt_statement_list
2176           LOOP opt_do_construct
2177           {
2178                 Expression t_before = (Expression) $2;
2179                 Expression t_after = (Expression) $7;
2180                 Expression t;
2181
2182                 if  ((t_before != null) && (t_after != null))
2183                         Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2184
2185                 if ((t_before == null) && (t_after == null))
2186                         t = new BoolLiteral (true);
2187                 else
2188                         t = (t_before != null) ? t_before : t_after;
2189                         
2190                 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2191                 
2192                 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2193                     ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2194                          t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2195                          
2196                 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2197           }
2198           ;
2199
2200 opt_do_construct
2201         : /* empty */ { $$ = null; }
2202         | while_or_until boolean_expression
2203           {
2204                 do_type = (DoOptions)$1;
2205                 $$ = (Expression) $2;
2206           }
2207         ;
2208
2209 while_or_until
2210         : WHILE { $$ = DoOptions.WHILE; }
2211         | UNTIL { $$ = DoOptions.UNTIL; }
2212         ;
2213
2214 while_statement
2215         : WHILE
2216         {
2217                 start_block();
2218                 oob_stack.Push (lexer.Location);
2219         }
2220         boolean_expression EOL
2221         opt_statement_list
2222         END WHILE
2223         {
2224                 Location l = (Location) oob_stack.Pop ();
2225                 Block b = end_block();
2226                 Expression e = (Expression) $3;
2227                 $$ = new While ((Expression) e, (Statement) b, l);
2228         }
2229         ;
2230         
2231                 
2232 for_statement
2233         : FOR qualified_identifier ASSIGN expression TO expression opt_step EOL
2234           {
2235                 start_block();
2236           }
2237           opt_statement_list
2238           NEXT opt_identifier 
2239           {
2240                 Block statement = end_block();
2241                 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2242                 
2243                 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2244                 Expression test_expr =  new Binary (Binary.Operator.LessThanOrEqual,
2245                                                 for_var, (Expression) $6, lexer.Location);
2246                 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2247                                  for_var, (Expression) $7, lexer.Location), lexer.Location);
2248                                  
2249                 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);                     
2250                 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2251                 
2252                 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);            
2253           }       
2254         ;
2255
2256 opt_step
2257         : /* empty */           { $$ = new IntLiteral ((Int32) 1); }
2258         | STEP expression       { $$ = $2; }
2259         ;
2260
2261 opt_next_identifier
2262         : /* empty */
2263         | qualified_identifier
2264         ;
2265
2266 selection_statement
2267         : if_statement
2268         | select_statement
2269         ;
2270
2271 if_statement
2272         : if_statement_open opt_then if_statement_rest
2273           {
2274                 $$ = $3;
2275           }
2276         | if_statement_open THEN embedded_statement
2277           {
2278                 Location l = (Location) oob_stack.Pop ();
2279                 $$ = new If ((Expression) tmp_expr, end_block(), l);
2280           }
2281         ;
2282         
2283 if_statement_open
2284         : IF boolean_expression 
2285           {
2286                 oob_stack.Push (lexer.Location);
2287                 start_block();
2288                 tmp_expr = (Expression) $2;
2289           }
2290          ;
2291
2292 opt_then
2293         : /* empty */
2294         | THEN
2295         ;
2296         
2297 if_statement_rest
2298         : EOL
2299           opt_statement_list
2300           END IF
2301           { 
2302                 Location l = (Location) oob_stack.Pop ();
2303
2304                 $$ = new If ((Expression) tmp_expr, (Statement) end_block(), l);
2305
2306           }       
2307         | EOL
2308           opt_statement_list
2309           ELSE EOL 
2310           { 
2311                 tmp_block = end_block();
2312                 start_block();
2313           }
2314           opt_statement_list
2315           END IF        
2316           {
2317                 Location l = (Location) oob_stack.Pop ();
2318
2319                 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2320           }        
2321         ;
2322         
2323 select_statement
2324         : SELECT opt_case expression EOL
2325           { 
2326                 oob_stack.Push (lexer.Location);
2327                 switch_stack.Push (current_block);
2328           }     
2329           opt_case_sections
2330           END SELECT 
2331           {
2332                 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2333                 current_block = (Block) switch_stack.Pop ();
2334           }       
2335         ;
2336
2337 opt_case_sections
2338         : /* empty */   { $$ = null; }
2339         | case_sections { $$ = $1; }
2340         ;
2341         
2342 case_sections
2343         : case_sections case_section
2344           {
2345                 ArrayList sections = (ArrayList) $1;
2346
2347                 sections.Add ($2);
2348                 $$ = sections;
2349           }
2350         | case_section
2351           {
2352                 ArrayList sections = new ArrayList ();
2353
2354                 sections.Add ($1);
2355                 $$ = sections;
2356           }
2357         ;
2358
2359 case_section
2360         : CASE case_clauses EOL
2361           { 
2362                 start_block();
2363           }
2364           opt_statement_list
2365           {
2366                 Block topmost = current_block;
2367
2368                 while (topmost.Implicit)
2369                         topmost = topmost.Parent;
2370                         
2371                 // FIXME: This is a horrible hack which MUST go                 
2372                 topmost.statements.Add (new Break (lexer.Location));
2373                 $$ = new SwitchSection ((ArrayList) $2, topmost);
2374           }
2375           | CASE ELSE EOL
2376             /* FIXME: we should somehow flag an error 
2377                (BC30321 'Case' cannot follow a 'Case Else' 
2378                in the same 'Select' statement.) 
2379                if Case Else is not the last of the Case clauses
2380             */
2381           { 
2382                 start_block();
2383           }     
2384           opt_statement_list
2385           { 
2386                 Block topmost = current_block;
2387
2388                 while (topmost.Implicit)
2389                         topmost = topmost.Parent;
2390                         
2391                 // FIXME: This is a horrible hack which MUST go                 
2392                 topmost.statements.Add (new Break (lexer.Location));
2393                 
2394                 ArrayList a = new ArrayList();
2395                 a.Add (new SwitchLabel (null, lexer.Location));                 
2396                 $$ = new SwitchSection ((ArrayList) a, topmost);                
2397           }
2398         ;         
2399         
2400 case_clauses
2401         : case_clause
2402           {
2403                 ArrayList labels = new ArrayList ();
2404
2405                 labels.Add ($1);
2406                 $$ = labels;
2407           }     
2408         | case_clauses COMMA case_clause
2409           {
2410                 ArrayList labels = (ArrayList) ($1);
2411                 labels.Add ($2);
2412
2413                 $$ = labels;
2414           }     
2415         ;
2416         
2417 case_clause
2418         : opt_is comparison_operator expression
2419         | expression
2420           {
2421                 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
2422           }
2423         ;
2424         
2425 opt_is 
2426         : /* empty */
2427         | IS
2428         ;
2429
2430 comparison_operator
2431         : OP_LT
2432         | OP_GT
2433         | OP_LE
2434         | OP_NE
2435         /*| OP_EQ */
2436         ;
2437
2438 opt_case
2439         : /* empty */
2440         | CASE
2441         ;
2442
2443 expression_statement
2444         : statement_expression 
2445           {
2446                  $$ = $1; 
2447           }
2448         ;
2449
2450
2451 statement_expression
2452         : invocation_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
2453         | object_creation_expression    { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
2454         | assignment_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
2455         ;
2456
2457 object_creation_expression
2458         : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2459           {
2460                 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2461           }
2462         | NEW type
2463           {
2464                 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
2465           }
2466         ;
2467         
2468 array_creation_expression
2469         : object_creation_expression array_initializer
2470           {
2471                 New n = (New) $1;
2472                 string dims = "";
2473                 
2474                 if (n.Arguments != null) {
2475                         foreach (Argument a in n.Arguments) {
2476                                 if (a.Expr is EmptyExpression)
2477                                         dims += ",";
2478                                 else
2479                                         dims += (((IntLiteral)a.Expr).AsString() + ",");
2480                         }
2481                         dims = "[" + dims.Substring (0, dims.Length - 1) + "]";
2482                 }
2483                 else
2484                         dims = "[]";
2485                         
2486                 Expression atype = n.RequestedType;
2487         
2488                 if (VariableDeclaration.IndexesSpecified(dims)) {
2489                         ArrayList dimlist = VariableDeclaration.ParseIndexList (dims);
2490                         dims = VariableDeclaration.StripIndexesFromDims (dims);
2491                         //$$ = new ArrayCreation (atype, dimlist, dims, (ArrayList) $2, lexer.Location); 
2492                         $$ = new ArrayCreation (atype, dimlist, "", (ArrayList) $2, lexer.Location); 
2493                 }
2494                 else
2495                 {
2496                         //$$ = new ArrayCreation (atype, dims, (ArrayList) $2, lexer.Location); 
2497                         $$ = new ArrayCreation (atype, dims, (ArrayList) $2, lexer.Location); 
2498                 }
2499                 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
2500           }
2501         ;       
2502
2503 new_expression
2504         : object_creation_expression
2505         | array_creation_expression
2506         ;
2507
2508 declaration_statement
2509         : local_variable_declaration 
2510           {
2511                 if ($1 != null){
2512                         DictionaryEntry de = (DictionaryEntry) $1;
2513
2514                         $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2515                 }
2516           }
2517
2518         | local_constant_declaration 
2519           {
2520                 if ($1 != null){
2521                         DictionaryEntry de = (DictionaryEntry) $1;
2522
2523                         $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
2524                 }
2525           }
2526         ;        
2527         
2528 local_variable_declaration
2529         : DIM variable_declarators
2530           {
2531                 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);             
2532           }
2533         ;
2534
2535         
2536 local_constant_declaration
2537         : CONST constant_declarator
2538           {
2539                 if ($2 != null)
2540                         $$ = new DictionaryEntry ($1, $2);
2541                 else
2542                         $$ = null;
2543           }
2544         ;        
2545         
2546 constant_declarator
2547         : identifier ASSIGN constant_expression
2548           {
2549                 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
2550           }
2551         ;               
2552
2553 variable_declarators
2554         : variable_declarator 
2555           {
2556                 ArrayList decl = new ArrayList ();
2557                 decl.Add ($1);
2558                 $$ = decl;
2559           }
2560         | variable_declarators COMMA variable_declarator
2561           {
2562                 ArrayList decls = (ArrayList) $1;
2563                 decls.Add ($3);
2564                 $$ = $1;
2565           }
2566         ;
2567
2568 variable_declarator
2569         : variable_identifier opt_type_decl opt_variable_initializer
2570           {
2571                 string varname = (string)$1;
2572                 string dims = "[]";
2573                 object varinit = $3;
2574                 Expression vartype;
2575                 
2576                 // Some checking is required for particularly weird declarations
2577                 if ($2 is Pair) {
2578                         vartype = (Expression) ((Pair) $2).First;
2579                         if ($3 != null && $3 is ArrayList)
2580                                 Report.Error (205, "End of statement expected.");
2581                                 
2582                         ArrayList args = (ArrayList) ((Pair) $2).Second;
2583                         if (VariableDeclaration.HasExplicitIndexes (args))        
2584                                 Report.Error (638, "Array bounds cannot appear in type specifiers.");   
2585                                 
2586                         varname += "[";
2587                         if (args != null)
2588                                 for (int x = 0; x < args.Count; x++)
2589                                         varname += ",";
2590                                 
2591                         varname += "]";                                                 
2592                 }
2593                 else
2594                         vartype = (Expression) $2;
2595                 /*
2596                    Check for a declaration like Dim a(2) or Dim a(2,3)
2597                    If this is the case, we must generate an ArrayCreationExpression
2598                    and, in case, add the initializer after the array has been created.
2599                 */
2600                 if (VariableDeclaration.IsArrayDecl (varname)) {
2601                         if (VariableDeclaration.IndexesSpecified(varname)) { 
2602                                 varname = VariableDeclaration.StripDims (varname, ref dims);
2603                                 ArrayList a_dims = VariableDeclaration.ParseIndexList(dims);
2604                                 varinit = new ArrayCreation (vartype, a_dims,"", (ArrayList) varinit, lexer.Location);
2605                         }
2606                         else
2607                                 varname = VariableDeclaration.StripDims (varname, ref dims);
2608                                 
2609                         vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.GetRank (dims), lexer.Location);
2610                 }
2611
2612                 if (vartype is New) {
2613                         if (varinit != null) {
2614                                 Report.Error (30205, lexer.Location, "End of statement expected");
2615                                 $$ = null;
2616                         }
2617                         else
2618                         {
2619                                 varinit = vartype;
2620                                 vartype = ((New)vartype).RequestedType;
2621                         }
2622                 }
2623                 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
2624                 //Console.WriteLine ("varname: {0} - vartype: {1} - init: {2}", varname, vartype, varinit);
2625           }
2626         ;
2627
2628 variable_identifier
2629         : identifier opt_array_name_modifier 
2630           {
2631                 $$ = $1; 
2632                 if ($2 != null)
2633                         $$ = (string)$$ + (string)$2;
2634           }
2635         ;               
2636                 
2637 opt_type_spec
2638         : /* empty */   
2639           { 
2640                 $$ = null;              
2641           }
2642         | AS type       
2643           { 
2644                 $$ = (Expression) $2;
2645           }
2646         ;
2647                         
2648 opt_type_decl
2649         : opt_type_spec
2650           {
2651                 $$ = $1;
2652           }
2653         | AS type OPEN_PARENS opt_argument_list CLOSE_PARENS
2654           {
2655                 // Report.Error (30638, "Array bounds cannot appear in type specifiers");
2656                 $$ = new Pair ($2, $4);;
2657           }
2658         | AS NEW type
2659           {
2660                 New n = new New ((Expression)$3, null, lexer.Location);
2661                 $$ = (Expression) n;
2662           }
2663         | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS 
2664           {
2665                 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
2666                 $$ = (Expression) n;
2667           }
2668         ;
2669                 
2670 opt_array_name_modifier
2671         : /* empty */                           { $$ = null; }
2672         | array_type_modifier                   { $$ = $1;   }
2673         ;
2674         
2675 array_type_modifier
2676         : rank_specifiers  { $$ = $1; }
2677         ;
2678         
2679 opt_variable_initializer
2680         : /* empty */                   { $$ = null; }
2681         | ASSIGN variable_initializer   { $$ = $2; }
2682         ;
2683                 
2684 variable_initializer
2685         : expression
2686           {
2687                 $$ = $1;
2688           }
2689         | array_initializer
2690           {
2691                 $$ = $1;
2692           }
2693         
2694         ;       
2695         
2696 array_initializer
2697         : OPEN_BRACE CLOSE_BRACE
2698           {
2699                 ArrayList list = new ArrayList ();
2700                 $$ = list;
2701           }
2702         | OPEN_BRACE variable_initializer_list CLOSE_BRACE
2703           {
2704                 $$ = (ArrayList) $2;
2705           }
2706         ;
2707
2708 variable_initializer_list
2709         : variable_initializer
2710           {
2711                 ArrayList list = new ArrayList ();
2712                 list.Add ($1);
2713                 $$ = list;
2714           }
2715         | variable_initializer_list COMMA variable_initializer
2716           {
2717                 ArrayList list = (ArrayList) $1;
2718                 list.Add ($3);
2719                 $$ = list;
2720           }
2721         ;       
2722                 
2723 /* 
2724  * The following is from Rhys' grammar:
2725  * > Types in local variable declarations must be recognized as 
2726  * > expressions to prevent reduce/reduce errors in the grammar.
2727  * > The expressions are converted into types during semantic analysis.
2728  */
2729 local_variable_type
2730         : primary_expression opt_rank_specifier
2731           { 
2732                 // FIXME: Do something smart here regarding the composition of the type.
2733
2734                 // Ok, the above "primary_expression" is there to get rid of
2735                 // both reduce/reduce and shift/reduces in the grammar, it should
2736                 // really just be "type_name".  If you use type_name, a reduce/reduce
2737                 // creeps up.  If you use qualified_identifier (which is all we need
2738                 // really) two shift/reduces appear.
2739                 // 
2740
2741                 // So the super-trick is that primary_expression
2742                 // can only be either a SimpleName or a MemberAccess. 
2743                 // The MemberAccess case arises when you have a fully qualified type-name like :
2744                 // Foo.Bar.Blah i;
2745                 // SimpleName is when you have
2746                 // Blah i;
2747                   
2748                 Expression expr = (Expression) $1;  
2749                 if (!(expr is SimpleName || expr is MemberAccess)) {
2750                         Error_ExpectingTypeName (lexer.Location, expr);
2751                         $$ = null;
2752                 } else {
2753                         //
2754                         // So we extract the string corresponding to the SimpleName
2755                         // or MemberAccess
2756                         // 
2757                         if ((string) $2 == "")
2758                                 $$ = $1;
2759                         else
2760                                 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2761                 }
2762           }
2763         | builtin_types opt_rank_specifier
2764           {
2765                 if ((string) $2 == "")
2766                         $$ = $1;
2767                 else
2768                         $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2769           }
2770         ;
2771                 
2772 rank_specifiers
2773         : rank_specifier
2774           {
2775                   $$ = $1;
2776           }
2777         | rank_specifiers rank_specifier
2778           {
2779                   $$ = (string) $2 + (string) $1;
2780           }             
2781         ;
2782
2783 rank_specifier
2784         : OPEN_PARENS opt_dim_separators CLOSE_PARENS
2785           {
2786                 $$ = "[" + (string) $2 + "]";
2787           }
2788         ;
2789                         
2790 opt_rank_specifier
2791         : /* empty */
2792           {
2793                   $$ = "";
2794           }
2795         | rank_specifiers
2796           {
2797                         $$ = $1;
2798           }
2799         ;               
2800         
2801 opt_dim_separators
2802         : /* empty */
2803           {
2804                 $$ = "";
2805           }
2806         | dim_separators
2807           {
2808                 $$ = $1;
2809           }     
2810         | dim_specifiers
2811           {
2812                 $$ = $1;
2813           }       
2814         ;
2815
2816 dim_separators
2817         : COMMA
2818           {
2819                 $$ = ",";
2820           }
2821         | dim_separators COMMA
2822           {
2823                 $$ = (string) $1 + ",";
2824           }
2825         ;
2826
2827 dim_specifiers
2828         : integer_literal                       { $$ = ((IntLiteral)$1).AsString(); }
2829         | dim_specifiers COMMA integer_literal  { $$ = $1 + "," + ((IntLiteral)$3).AsString(); }
2830         ;
2831
2832
2833         
2834 /* Expressions */
2835 primary_expression
2836         : literal
2837           {
2838                 // 7.5.1: Literals
2839           }
2840
2841         | qualified_identifier
2842           {
2843                 string name = (string) $1;
2844
2845                 $$ = DecomposeQI (name, lexer.Location);
2846           }
2847         | parenthesized_expression
2848         | member_access
2849         | invocation_expression
2850         //| element_access
2851         | this_access
2852         | base_access
2853         | new_expression
2854         | cast_expression
2855         ;
2856
2857 literal
2858         : boolean_literal
2859         | integer_literal
2860         | real_literal
2861         | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value); }
2862         | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value); }
2863         | NOTHING                       { $$ = NullLiteral.Null; }
2864         ;
2865
2866 real_literal
2867         : LITERAL_SINGLE        { $$ = new FloatLiteral ((float) lexer.Value); }
2868         | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value); }
2869         | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value); }
2870         ;
2871
2872 integer_literal
2873         : LITERAL_INTEGER       {
2874                 object v = lexer.Value;
2875
2876                 if (v is int)
2877                         $$ = new IntLiteral ((Int32) v); 
2878                 else if (v is uint)
2879                         $$ = new UIntLiteral ((UInt32) v);
2880                 else if (v is long)
2881                         $$ = new LongLiteral ((Int64) v);
2882                 else if (v is ulong)
2883                         $$ = new ULongLiteral ((UInt64) v);
2884                 else
2885                         Console.WriteLine ("OOPS.  Unexpected result from scanner");
2886                         
2887           }
2888         ;
2889
2890 boolean_literal
2891         : TRUE                  { $$ = new BoolLiteral (true); }
2892         | FALSE                 { $$ = new BoolLiteral (false); }
2893         ;
2894
2895 parenthesized_expression
2896         : OPEN_PARENS expression CLOSE_PARENS
2897           { $$ = $2; }
2898         ;
2899
2900 member_access
2901         : primary_expression DOT identifier
2902           {
2903                 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2904           }
2905         | primary_expression DOT NEW
2906           {
2907                 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
2908           }       
2909         | predefined_type DOT identifier
2910           {
2911                 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2912           }
2913         ;
2914
2915 predefined_type
2916         : builtin_types
2917         ;
2918
2919 invocation_expression
2920         : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
2921           {
2922                 if ($1 == null) {
2923                         Location l = lexer.Location;
2924                         Report.Error (1, l, "THIS IS CRAZY");
2925                 }
2926                 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
2927 //              Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
2928           } 
2929         | GETTYPE OPEN_PARENS expression CLOSE_PARENS
2930           {
2931                 Expression GetTypeExpr = DecomposeQI("System.Type.GetType", lexer.Location);
2932                 ArrayList args = new ArrayList();
2933                 Argument arg = new Argument ((Expression) $3, Argument.AType.Expression);
2934                 args.Add (arg);
2935                 $$ = new Invocation (GetTypeExpr, args, lexer.Location);
2936           }
2937         ;
2938         
2939 base_access
2940         : MYBASE DOT IDENTIFIER
2941           {
2942                 $$ = new BaseAccess ((string) $3, lexer.Location);
2943           }
2944         | MYBASE DOT NEW
2945           {
2946                 $$ = new BaseAccess ("New", lexer.Location);
2947           }
2948         ;       
2949
2950 opt_argument_list
2951         : argument_list
2952           { 
2953                 /*
2954                    The 'argument' rule returns an 'empty' argument
2955                    of type NoArg (used for default arguments in invocations)
2956                    if no arguments are actually passed.
2957
2958                    If there is only one argument and it is o type NoArg,
2959                    we return a null (empty) list
2960                 */
2961                 ArrayList args = (ArrayList) $1;
2962                 if (args.Count == 1 &&
2963                     ((Argument)args[0]).ArgType == Argument.AType.NoArg)
2964                         $$ = null;
2965                 else
2966                         $$ = $1;
2967           }
2968         ;
2969
2970 argument_list
2971         : argument
2972           {
2973                 ArrayList list = new ArrayList ();
2974                 list.Add ($1);
2975                 $$ = list;
2976           }
2977         | argument_list COMMA argument
2978           {
2979                 ArrayList list = (ArrayList) $1;
2980                 list.Add ($3);
2981                 $$ = list;
2982           }
2983         ;
2984
2985 argument
2986         : expression
2987           {
2988                 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
2989           }
2990         | BYREF variable_reference
2991           {
2992                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
2993           }
2994         | /* empty */
2995           {
2996                 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
2997           }
2998         ;
2999
3000 variable_reference
3001         : expression {/* note ("section 5.4"); */  $$ = $1;  }
3002         ;
3003 /*
3004 element_access
3005         : primary_expression OPEN_PARENS expression_list CLOSE_PARENS
3006           {
3007                 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
3008           }
3009         | primary_expression rank_specifiers
3010           {
3011                 // So the super-trick is that primary_expression
3012                 // can only be either a SimpleName or a MemberAccess.
3013                 // The MemberAccess case arises when you have a fully qualified type-name like :
3014                 // Foo.Bar.Blah i;
3015                 // SimpleName is when you have
3016                 // Blah i;
3017                 Expression expr = (Expression) $1;
3018                 
3019                 if (!(expr is SimpleName || expr is MemberAccess)) {
3020                         Error_ExpectingTypeName (lexer.Location, expr);
3021                         $$ = TypeManager.system_object_expr;
3022                 } else {
3023                         //
3024                         // So we extract the string corresponding to the SimpleName
3025                         // or MemberAccess
3026                         //
3027                         $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
3028                 }
3029           }
3030         ;
3031 */
3032
3033 negation_expression
3034         : NOT expression 
3035           {
3036                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3037           }
3038         ;
3039                 
3040 expression
3041         : conditional_expression { $$ = $1; }
3042         | negation_expression
3043         /*| assignment_expression*/
3044         ;
3045
3046 opt_expression
3047         : /* empty */
3048         | expression
3049         ;
3050         
3051 expression_list
3052         : expression
3053           {
3054                 ArrayList list = new ArrayList ();
3055                 list.Add ($1);
3056                 $$ = list;
3057           }
3058         | expression_list COMMA expression
3059           {
3060                 ArrayList list = (ArrayList) $1;
3061                 list.Add ($3);
3062                 $$ = list;
3063           }
3064         ;
3065
3066 opt_expression_list
3067         : /*empty */ { $$ = null; }
3068         | expression_list
3069         ;
3070         
3071 this_access
3072         : ME
3073           {
3074                 $$ = new This (current_block, lexer.Location);
3075           }
3076         | MYCLASS
3077           {
3078                 // FIXME: This is actually somewhat different from Me
3079                 $$ = new This (current_block, lexer.Location);
3080           }
3081         ;
3082
3083 unary_expression
3084         : primary_expression
3085         /*| NOT prefixed_unary_expression
3086           {
3087                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3088           }
3089         | cast_expression */
3090         ;
3091         
3092 cast_expression
3093         : cast_operator OPEN_PARENS expression CLOSE_PARENS
3094           {
3095                   $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3096           }     
3097         | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3098           {
3099                   $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3100           }                       
3101         ;
3102         
3103 cast_operator
3104         : CBOOL         { $$ = TypeManager.system_boolean_expr;         }
3105         | CBYTE         { $$ = TypeManager.system_byte_expr;            }
3106         | CCHAR         { $$ = TypeManager.system_char_expr;            }
3107         | CDATE         { $$ = TypeManager.system_decimal_expr;         } //FIXME
3108         | CDBL          { $$ = TypeManager.system_double_expr;          }
3109         | CDEC          { $$ = TypeManager.system_decimal_expr;         }
3110         | CINT          { $$ = TypeManager.system_int32_expr;           }
3111         | CLNG          { $$ = TypeManager.system_int64_expr;           }
3112         | COBJ          { $$ = TypeManager.system_object_expr;          }
3113         | CSHORT        { $$ = TypeManager.system_int16_expr;           }
3114         | CSNG          { $$ = TypeManager.system_single_expr;          }
3115         | CSTR          { $$ = TypeManager.system_string_expr;  }
3116         ;
3117         
3118         //
3119         // The idea to split this out is from Rhys' grammar
3120         // to solve the problem with casts.
3121         //
3122 prefixed_unary_expression
3123         : unary_expression
3124         | PLUS prefixed_unary_expression
3125           {
3126                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3127           }
3128         | MINUS prefixed_unary_expression
3129           {
3130                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3131           }
3132         | ADDRESSOF prefixed_unary_expression
3133           {
3134                 // FIXME: We should generate an error if AddressOf is NOT used
3135                 // during delegate creation
3136                 $$ = $2;
3137           }       
3138         ;
3139
3140 multiplicative_expression
3141         : prefixed_unary_expression
3142         | multiplicative_expression STAR prefixed_unary_expression
3143           {
3144                 $$ = new Binary (Binary.Operator.Multiply,
3145                                  (Expression) $1, (Expression) $3, lexer.Location);
3146           }
3147         | multiplicative_expression DIV prefixed_unary_expression
3148           {
3149                 $$ = new Binary (Binary.Operator.Division,
3150                                  (Expression) $1, (Expression) $3, lexer.Location);
3151           }
3152         | multiplicative_expression OP_MODULUS prefixed_unary_expression
3153           {
3154                 $$ = new Binary (Binary.Operator.Modulus,
3155                                  (Expression) $1, (Expression) $3, lexer.Location);
3156           }
3157         ;
3158
3159 additive_expression
3160         : multiplicative_expression
3161         | additive_expression PLUS multiplicative_expression
3162           {
3163                 $$ = new Binary (Binary.Operator.Addition,
3164                                  (Expression) $1, (Expression) $3, lexer.Location);
3165           }
3166         | additive_expression MINUS multiplicative_expression
3167           {
3168                 $$ = new Binary (Binary.Operator.Subtraction,
3169                                  (Expression) $1, (Expression) $3, lexer.Location);
3170           }
3171         | additive_expression OP_CONCAT multiplicative_expression
3172           {
3173                 // FIXME: This should only work for String expressions
3174                 // We probably need to use something from the runtime
3175                 $$ = new Binary (Binary.Operator.Addition,
3176                                  (Expression) $1, (Expression) $3, lexer.Location);
3177           }       
3178         ;
3179
3180 relational_expression
3181         : additive_expression
3182         | relational_expression OP_LT additive_expression
3183           {
3184                 $$ = new Binary (Binary.Operator.LessThan,
3185                                  (Expression) $1, (Expression) $3, lexer.Location);
3186           }
3187         | relational_expression OP_GT additive_expression
3188           {
3189                 $$ = new Binary (Binary.Operator.GreaterThan,
3190                                  (Expression) $1, (Expression) $3, lexer.Location);
3191           }
3192         | relational_expression OP_LE additive_expression
3193           {
3194                 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3195                                  (Expression) $1, (Expression) $3, lexer.Location);
3196           }
3197         | relational_expression OP_GE additive_expression
3198           {
3199                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3200                                  (Expression) $1, (Expression) $3, lexer.Location);
3201           }
3202         | relational_expression IS unary_expression
3203           {
3204                 $$ = new Binary (Binary.Operator.Equality,
3205                         (Expression) $1, (Expression) $3, lexer.Location);
3206           }
3207         | relational_expression AS type_name
3208           {
3209                 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3210           }
3211         ;
3212
3213 equality_expression
3214         : relational_expression
3215         | equality_expression ASSIGN relational_expression
3216           {
3217                 $$ = new Binary (Binary.Operator.Equality,
3218                                  (Expression) $1, (Expression) $3, lexer.Location);
3219           }
3220         | equality_expression OP_NE relational_expression
3221           {
3222                 $$ = new Binary (Binary.Operator.Inequality, 
3223                                  (Expression) $1, (Expression) $3, lexer.Location);
3224           }       
3225         ;
3226
3227 and_expression
3228         : equality_expression
3229         | and_expression AND equality_expression
3230           {
3231                 $$ = new Binary (Binary.Operator.BitwiseAnd,
3232                                  (Expression) $1, (Expression) $3, lexer.Location);
3233           }
3234         ;
3235
3236 exclusive_or_expression
3237         : and_expression
3238         | exclusive_or_expression OP_XOR and_expression
3239           {
3240                 $$ = new Binary (Binary.Operator.ExclusiveOr,
3241                                  (Expression) $1, (Expression) $3, lexer.Location);
3242           }
3243         ;
3244
3245 conditional_and_expression
3246         : exclusive_or_expression
3247         | conditional_and_expression AND exclusive_or_expression
3248           {
3249                 $$ = new Binary (Binary.Operator.LogicalAnd,
3250                                  (Expression) $1, (Expression) $3, lexer.Location);
3251           }
3252         | conditional_and_expression ANDALSO exclusive_or_expression
3253           {     // FIXME: this is likely to be broken
3254                 $$ = new Binary (Binary.Operator.LogicalAnd,
3255                                  (Expression) $1, (Expression) $3, lexer.Location);
3256           }
3257         ;
3258
3259 conditional_or_expression
3260         : conditional_and_expression
3261         | conditional_or_expression OR conditional_and_expression
3262           {
3263                 $$ = new Binary (Binary.Operator.LogicalOr,
3264                                  (Expression) $1, (Expression) $3, lexer.Location);
3265           }
3266         | conditional_or_expression ORELSE conditional_and_expression
3267           {     // FIXME: this is likely to be broken
3268                 $$ = new Binary (Binary.Operator.LogicalOr,
3269                                  (Expression) $1, (Expression) $3, lexer.Location);
3270           }
3271         ;
3272
3273 conditional_expression
3274         : conditional_or_expression
3275         ;
3276
3277 assignment_expression
3278         : prefixed_unary_expression ASSIGN expression
3279           { 
3280                 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3281           }
3282         | prefixed_unary_expression OP_MULT_ASSIGN expression
3283           {
3284                 Location l = lexer.Location;
3285
3286                 $$ = new CompoundAssign (
3287                         Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3288           }
3289         | prefixed_unary_expression OP_DIV_ASSIGN expression
3290           {
3291                 Location l = lexer.Location;
3292
3293                 $$ = new CompoundAssign (
3294                         Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3295           }
3296         | prefixed_unary_expression OP_ADD_ASSIGN expression
3297           {
3298                 Location l = lexer.Location;
3299
3300                 $$ = new CompoundAssign (
3301                         Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3302           }
3303         | prefixed_unary_expression OP_SUB_ASSIGN expression
3304           {
3305                 Location l = lexer.Location;
3306
3307                 $$ = new CompoundAssign (
3308                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3309           }       
3310         ;
3311
3312 constant_expression
3313         : expression
3314         ;
3315
3316 boolean_expression
3317         : expression
3318         ;
3319
3320 type
3321         : type_name {   /* class_type */
3322                 /*
3323                    This does interfaces, delegates, struct_types, class_types,
3324                    parent classes, and more! 4.2
3325                  */
3326                 $$ = DecomposeQI ((string) $1, lexer.Location); 
3327           }
3328         | builtin_types 
3329         /*| array_type 
3330          | pointer_type */
3331         ;
3332
3333 type_list
3334         : type
3335           {
3336                 ArrayList types = new ArrayList ();
3337
3338                 types.Add ($1);
3339                 $$ = types;
3340           }
3341         | type_list COMMA type
3342           {
3343                 ArrayList types = (ArrayList) $1;
3344
3345                 types.Add ($3);
3346                 $$ = types;
3347           }
3348         ;
3349
3350 type_name
3351         : namespace_or_type_name
3352         ;
3353         
3354 namespace_or_type_name
3355         : qualified_identifier
3356         ;
3357
3358 array_type
3359         : type bracketed_rank_specifiers
3360           {
3361                 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3362           }
3363         ;
3364         
3365 bracketed_rank_specifiers
3366         : bracketed_rank_specifier bracketed_opt_rank_specifier
3367           {
3368                   $$ = (string) $2 + (string) $1;
3369           }
3370         ;
3371
3372 bracketed_rank_specifier
3373         : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
3374           {
3375                 $$ = "[" + (string) $2 + "]";
3376           }
3377         ;
3378
3379 bracketed_opt_rank_specifier
3380         : /* empty */
3381           {
3382                   $$ = "";
3383           }
3384         | bracketed_rank_specifiers
3385           {
3386                 $$ = $1;
3387           }
3388         ;               
3389
3390 /* Built-in / Integral types */
3391 builtin_types
3392         : OBJECT        { $$ = TypeManager.system_object_expr; }
3393         | STRING        { $$ = TypeManager.system_string_expr; }
3394         | BOOLEAN       { $$ = TypeManager.system_boolean_expr; }
3395         | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
3396         | SINGLE        { $$ = TypeManager.system_single_expr; }
3397         | DOUBLE        { $$ = TypeManager.system_double_expr; }
3398         | integral_type
3399         ;
3400
3401 integral_type
3402         : 
3403         | BYTE          { $$ = TypeManager.system_byte_expr; }
3404         | SHORT         { $$ = TypeManager.system_int16_expr; }
3405         | LONG          { $$ = TypeManager.system_int64_expr; }
3406         | INTEGER       { $$ = TypeManager.system_int32_expr; }
3407         | CHAR          { $$ = TypeManager.system_char_expr; }
3408 /*
3409         | SBYTE         { $$ = TypeManager.system_sbyte_expr; }
3410         | UINT          { $$ = TypeManager.system_uint32_expr; }
3411         | ULONG         { $$ = TypeManager.system_uint64_expr; }
3412         | USHORT        { $$ = TypeManager.system_uint16_expr; }
3413         | CHAR          { $$ = TypeManager.system_char_expr; }
3414         | VOID          { $$ = TypeManager.system_void_expr; }
3415 */
3416         ;
3417
3418 interface_type
3419         : type_name
3420         ;
3421 %%
3422
3423
3424 Tokenizer lexer;
3425
3426 public Tokenizer Lexer {
3427         get {
3428                 return lexer;
3429         }
3430 }                  
3431
3432 public static Expression DecomposeQI (string name, Location loc)
3433 {
3434         Expression o;
3435
3436         if (name.IndexOf ('.') == -1){
3437                 return new SimpleName (name, loc);
3438         } else {
3439                 int pos = name.LastIndexOf (".");
3440                 string left = name.Substring (0, pos);
3441                 string right = name.Substring (pos + 1);
3442
3443                 o = DecomposeQI (left, loc);
3444
3445                 return new MemberAccess (o, right, loc);
3446         }
3447 }
3448
3449 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
3450 {
3451         Block implicit_block;
3452         ArrayList inits = null;
3453
3454         //
3455         // We use the `Used' property to check whether statements
3456         // have been added to the current block.  If so, we need
3457         // to create another block to contain the new declaration
3458         // otherwise, as an optimization, we use the same block to
3459         // add the declaration.
3460         //
3461         // FIXME: A further optimization is to check if the statements
3462         // that were added were added as part of the initialization
3463         // below.  In which case, no other statements have been executed
3464         // and we might be able to reduce the number of blocks for
3465         // situations like this:
3466         //
3467         // int j = 1;  int k = j + 1;
3468         //
3469         
3470         VariableDeclaration.FixupTypes (variable_declarators);
3471         
3472         if (current_block.Used) {
3473                 implicit_block = new Block (current_block, true, loc, Location.Null);
3474                 implicit_block.AddChildVariableNames (current_block);
3475         } else
3476                 implicit_block = current_block;
3477
3478         foreach (VariableDeclaration decl in variable_declarators){
3479                 Expression type = decl.type;
3480                 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
3481                         if (decl.expression_or_array_initializer != null){
3482                                 if (inits == null)
3483                                         inits = new ArrayList ();
3484                                 inits.Add (decl);
3485                         }
3486                 }
3487         }
3488
3489         if (inits == null)
3490                 return implicit_block;
3491
3492         foreach (VariableDeclaration decl in inits){
3493                 Assign assign;
3494                 Expression expr;
3495                 Expression type = decl.type;
3496                 
3497                 if ((decl.expression_or_array_initializer is Expression) || 
3498                     (decl.expression_or_array_initializer is New)) {
3499                         expr = (Expression) decl.expression_or_array_initializer;
3500                 } else {
3501                         ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3502                         
3503                         expr = new ArrayCreation (type, "", init, decl.Location);
3504                 }
3505
3506                 LocalVariableReference var;
3507                 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
3508
3509                 assign = new Assign (var, expr, decl.Location);
3510
3511                 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
3512         }
3513         
3514         return implicit_block;
3515 }
3516
3517
3518 Block declare_local_constant (Expression type, VariableDeclaration decl)
3519 {
3520         Block implicit_block;
3521
3522         if (current_block.Used)
3523                 implicit_block = new Block (current_block, true);
3524         else
3525                 implicit_block = current_block;
3526
3527         if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
3528                                           current_local_parameters, decl.Location))){
3529         }
3530         
3531         return implicit_block;
3532 }
3533
3534 // <summary>
3535 //   A class used to pass around variable declarations and constants
3536 // </summary>
3537 public class VariableDeclaration {
3538         public string identifier;
3539         public object expression_or_array_initializer;
3540         public Location Location;
3541         public Attributes OptAttributes;
3542         public Expression type;
3543         public ArrayList dims;
3544                 
3545         public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
3546         {
3547                 this.identifier = id;
3548                 this.expression_or_array_initializer = eoai;
3549                 this.Location = l;
3550                 this.OptAttributes = opt_attrs;
3551                 this.type = t;
3552                 this.dims = null;
3553         }       
3554
3555         public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
3556         {
3557         }
3558         
3559         public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
3560         {
3561         }       
3562         
3563         public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this 
3564                                         (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
3565         {
3566         }       
3567         
3568         public static void FixupTypes (ArrayList vars)
3569         {
3570                 int varcount =  vars.Count;
3571                 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
3572                         
3573                 if (last_var.type == null)
3574                         last_var.type = TypeManager.system_object_expr;
3575                         
3576                 Expression cur_type = last_var.type;
3577                 int n = varcount - 1;
3578                 
3579                 while (n >= 0) {
3580                         VariableDeclaration var = (VariableDeclaration) vars[n--];
3581                         if (var.type == null)
3582                                 var.type = cur_type;
3583                         else
3584                                 cur_type = var.type;
3585                 }
3586         }
3587         
3588         public static bool IndexesSpecified (string varname)
3589         {
3590                 bool res = false;
3591                 
3592                 if (varname.IndexOf("[") >= 0) {
3593                         char[] ds = {'1','2','3','4','5','6','7','8','9'};
3594                         
3595                         string dimpart = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
3596                         if (dimpart.IndexOfAny (ds) >= 0) 
3597                                 res = true;
3598                 }
3599                 return (res);
3600         }
3601         
3602         public static string StripDims (string varname, ref string d)
3603         {
3604                 string res = varname;
3605                 string dres = "";
3606                 
3607                 if (varname.IndexOf("[") >= 0) {
3608                         dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
3609                         res = varname.Substring(0, varname.IndexOf("["));
3610                 }
3611                 d = dres;
3612                 return (res);
3613         }       
3614         
3615         public static string StripDims (string varname)
3616         {
3617                 string dres = "";
3618                 
3619                 return (StripDims(varname, ref dres));
3620         }       
3621         
3622         public static string StripIndexesFromDims (string dims)
3623         {
3624                 StringBuilder sb = new StringBuilder();
3625                 //  
3626                 foreach (char c in dims) 
3627                         if (c == ',' || c == ']' || c == '[')
3628                                 sb.Append (c);
3629                                 
3630                 return sb.ToString();                           
3631         }
3632         
3633         public static string GetRank (string dims)
3634         {
3635                 string res = "";
3636                 int x;
3637                 
3638                 for (x = 0; x < dims.Length; x++) {
3639                         if (dims[x] == '[' || dims[x] == ']' || dims[x] == ',')
3640                                 res = res + dims[x];
3641                 }                               
3642                 return (res);
3643         }       
3644         
3645         public static bool HasExplicitIndexes (ArrayList a)
3646         {
3647                 bool res = false;
3648                 
3649                 if (a != null) {
3650                         foreach (Expression e in a) 
3651                                 if (!(e is EmptyExpression)) {
3652                                         res = true;
3653                                         break;
3654                                 }
3655                 }                       
3656                 return res;                     
3657         }
3658         
3659         public static ArrayList ParseIndexList (string dims)
3660         {
3661                 ArrayList res = new ArrayList();
3662                 string d = dims.Substring (1, dims.Length -2);
3663                 Array a = d.Split (',');
3664                 
3665                 if (a.GetLength(0) > 32) {
3666                         Report.Error (999, "Arrays cannot have more than 32 dimensions");
3667                 }
3668                 
3669                 foreach (string s in a) 
3670                         if (s != "")
3671                                 res.Add (new IntLiteral ((Int32) Convert.ToInt32(s) + 1));
3672                         else
3673                                 res.Add (new IntLiteral ((Int32) 0));
3674                 
3675                 return (res);
3676         }               
3677         
3678         public static bool IsArrayDecl (string varname)
3679         {
3680                 return (varname.IndexOf("[") >= 0);
3681         }                       
3682         
3683         public static void FixupArrayTypes (ArrayList vars)
3684         {
3685                 int varcount =  vars.Count;
3686                 string dims;
3687                 
3688                 foreach (VariableDeclaration var in vars) {
3689                         if (var.identifier.EndsWith(",")) {
3690                                 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","), 
3691                                                                 var.identifier.LastIndexOf(",")) + "]";
3692                                 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
3693                                 var.type = new ComposedCast (var.type, (string) dims, var.Location);
3694                         }
3695                 }
3696         }                               
3697 }
3698
3699 public Property BuildSimpleProperty (Expression p_type, string name, 
3700                                         Field p_fld, int mod_flags,
3701                                         Attributes attrs, Location loc) 
3702 {
3703         Property p;
3704         Block get_block, set_block;
3705         Accessor acc_set, acc_get;
3706         StatementExpression a_set;
3707         Statement a_get;
3708         Parameter [] args;
3709         
3710         // Build SET Block
3711         Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);    
3712         args  = new Parameter [1];
3713         args [0] = implicit_value_parameter;
3714                 
3715         Parameters set_params = new Parameters (args, null, loc);
3716         a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc), 
3717                             (Expression) new SimpleName("value", loc), loc), loc);
3718                             
3719         set_block = new Block (current_block, set_params, loc, Location.Null);
3720         set_block.AddStatement ((Statement) a_set);                                         
3721         acc_set = new Accessor (set_block, attrs);
3722         
3723         // Build GET Block
3724         a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
3725         get_block = new Block (current_block, null, loc, Location.Null);
3726         get_block.AddStatement ((Statement) a_get);                                         
3727         acc_get = new Accessor (get_block, attrs);
3728                 
3729         p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
3730         
3731         return (p);
3732 }
3733                 
3734 void start_block () 
3735 {
3736         current_block = new Block (current_block, current_local_parameters,
3737                            lexer.Location, Location.Null);
3738
3739
3740 Block end_block ()
3741
3742         Block res;
3743         
3744         while (current_block.Implicit)
3745                 current_block = current_block.Parent;
3746
3747         res = current_block;
3748
3749         current_block.SetEndLocation (lexer.Location);
3750         current_block = current_block.Parent;
3751         
3752         return (res);
3753 }
3754
3755 private void AddHandler (Expression evt_definition, string handler_name)
3756 {
3757         AddHandler (current_block, evt_definition, handler_name);
3758 }
3759
3760 void CheckAttributeTarget (string a)
3761 {
3762         switch (a) {
3763
3764         case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
3765                 return;
3766                 
3767         default :
3768                 Location l = lexer.Location;
3769                 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
3770                 break;
3771         }
3772 }
3773
3774 private void AddHandler (Block b, Expression evt_id, string handler_name)
3775 {
3776         Location loc = lexer.Location;
3777         string evt_target = evt_id.ToString();
3778         evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
3779         Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
3780         b.AddStatement (s);
3781 }
3782
3783 private void RaiseEvent (string evt_name, ArrayList args)
3784 {
3785         Location loc = lexer.Location;
3786         
3787         Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
3788         Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc)); 
3789         current_block.AddStatement (s); 
3790 }
3791
3792 // FIXME: THIS DOES NOT WORK!!!
3793 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
3794 {
3795         Location loc = lexer.Location;
3796         ArrayList neh_args = new ArrayList();
3797         neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
3798         
3799         ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
3800         
3801         CompoundAssign ca = new CompoundAssign (
3802                         Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
3803                         
3804         Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc)); 
3805         b.AddStatement (s);     
3806 }
3807
3808 // <summary>
3809 //  This method is used to get at the complete string representation of
3810 //  a fully-qualified type name, hiding inside a MemberAccess ;-)
3811 //  This is necessary because local_variable_type admits primary_expression
3812 //  as the type of the variable. So we do some extra checking
3813 // </summary>
3814 string GetQualifiedIdentifier (Expression expr)
3815 {
3816         if (expr is SimpleName)
3817                 return ((SimpleName)expr).Name;
3818         else if (expr is MemberAccess)
3819                 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
3820         else 
3821                 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
3822         
3823 }
3824
3825 private void RemoveHandler (Expression evt_definition, string handler_name)
3826 {
3827         RemoveHandler (current_block, evt_definition, handler_name);
3828 }
3829
3830 private ConstructorInitializer FixConstructorInitializer (ref ArrayList s)
3831 {
3832         ConstructorInitializer ci = null;
3833         
3834         if (s.Count > 0) {
3835                 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
3836                         Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
3837                         
3838                         if (i.expr is BaseAccess) {
3839                                 BaseAccess ba = (BaseAccess) i.expr;
3840                                 if (ba.member == "New" || ba.member == ".ctor") {
3841                                         ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
3842                                         s.Remove(0);
3843                                 }
3844                         }
3845                         if (i.expr.ToString() == "Mono.CSharp.This..ctor") {
3846                                 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location); 
3847                                 s.Remove(0);
3848                         }
3849                 }
3850         }
3851         return ci;
3852 }
3853
3854 void Error_ExpectingTypeName (Location l, Expression expr)
3855 {
3856         if (expr is Invocation){
3857                 Report.Error (1002, l, "; expected");
3858         } else {
3859                 Report.Error (-1, l, "Invalid Type definition");
3860         }
3861 }
3862
3863 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
3864         return true;
3865 }
3866
3867 private void ReportError9998()
3868 {
3869         Report.Error (9998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
3870 }
3871
3872 public override int parse ()
3873 {
3874         current_namespace = new Namespace (null, RootContext.RootNamespace);
3875         current_container = RootContext.Tree.Types;
3876         current_container.Namespace = current_namespace;
3877         oob_stack = new Stack ();
3878         switch_stack = new Stack ();
3879         
3880         UseExtendedSyntax = name.EndsWith(".mbs");
3881         OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
3882         OptionStrict = InitialOptionStrict || UseExtendedSyntax;
3883         OptionCompareBinary = InitialOptionCompareBinary;
3884
3885         lexer = new Tokenizer (input, name, defines);
3886         StringBuilder value = new StringBuilder ();
3887         //yacc_verbose_flag=true;
3888         try 
3889         {
3890                 if (yacc_verbose_flag)
3891                         yyparse (lexer, new yydebug.yyDebugSimple ());
3892                 else
3893                         yyparse (lexer);
3894         } 
3895         catch (Exception e)
3896         {
3897                 Console.WriteLine (lexer.location + "  : Parsing error in " + lexer.ref_name);
3898                 Report.Error (9999, lexer.Location, "");
3899                 Console.WriteLine (e);
3900         }
3901         
3902         return Report.Errors;
3903 }
3904
3905 /* end end end */
3906 }
3907