* convert.cs (ObjectTypeToPrimitiveTypes): Added. Converts an
[mono.git] / mcs / bmcs / mb-parser.jay
1 %{
2 //
3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
4 //
5 // Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
6 //          Anirban Bhattacharjee (banirban@novell.com)
7 //          Jambunathan K (kjambunathan@novell.com)
8 //
9 // Licensed under the terms of the GNU GPL
10 //
11 // Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
12 // Copyright (C) 2003, 2004 Novell
13 //
14 //
15
16 namespace Mono.CSharp
17 {
18         using System.Text;
19         using System;
20         using System.Reflection;
21         using System.Collections;
22         using Mono.CSharp;
23
24         /// <summary>
25         ///    The MonoBASIC Parser
26         /// </summary>
27 //      [DefaultParser]
28 //      public class Parser : GenericParser
29 //      {
30         
31
32 //              /// <summary>
33 //              ///   Current block is used to add statements as we find
34 //              ///   them.  
35 //              /// </summary>
36 //              Block      current_block;
37                 
38 //              /// <summary>
39 //              ///   Tmp block is used to store block endings in if/select's
40 //              /// </summary>
41 //              Block      tmp_block;           
42
43 //              /// <summary>
44 //              ///   Tmp block is used to store tmp copies of expressions
45 //              /// </summary>
46 //              Expression      tmp_expr;       
47                 
48 //              /// <summary>
49 //              ///   Tmp catch is used to store catch clauses in try..catch..finally
50 //              /// </summary>
51 //              ArrayList      tmp_catch_clauses;                       
52                 
53 //              /// <summary>
54 //              ///   Current interface is used by the various declaration
55 //              ///   productions in the interface declaration to "add"
56 //              ///   the interfaces as we find them.
57 //              /// </summary>
58 //              Interface  current_interface;
59
60 //              /// <summary>
61 //              ///   This is used by the unary_expression code to resolve
62 //              ///   a name against a parameter.  
63 //              /// </summary>
64 //              Parameters current_local_parameters;
65                 
66 //              /// <summary>
67 //              ///   This are used when parsing parameters in property
68 //              ///   declarations.
69 //              /// </summary>          
70 //              Parameters set_parameters;
71 //              Parameters get_parameters;
72                 
73 //              /// <summary>
74 //              ///   This is used by the sub_header parser to store modifiers
75 //              ///   to be passed to sub/constructor  
76 //              /// </summary>
77 //              int current_modifiers;          
78                         
79 //              /// <summary>
80 //              ///   This is used by the sub_header parser to store attributes
81 //              ///   to be passed to sub/constructor  
82 //              /// </summary>
83 //              Attributes current_attributes;                          
84
85 //              /// <summary>
86 //              ///   Using during property parsing to describe the implicit
87 //              ///   value parameter that is passed to the "set" accessor
88 //              ///   method
89 //              /// </summary>
90 //              string get_implicit_value_parameter_name;
91                 
92 //              // <summary>
93 //              //   Using during property parsing to describe the implicit
94 //              //   value parameter that is passed to the "set" and "get"accesor
95 //              //   methods (properties and indexers).
96 //              // </summary>
97 //              Expression get_implicit_value_parameter_type;
98                 
99 //              /// <summary>
100 //              ///   Using during property parsing to describe the implicit
101 //              ///   value parameter that is passed to the "set" accessor
102 //              ///   method
103 //              /// </summary>
104 //              string set_implicit_value_parameter_name;
105                 
106 //              // <summary>
107 //              //   Using during property parsing to describe the implicit
108 //              //   value parameter that is passed to the "set" and "get"accesor
109 //              //   methods (properties and indexers).
110 //              // </summary>
111 //              Expression set_implicit_value_parameter_type;           
112                 
113 //              Location member_location;
114                 
115 //              // An out-of-band stack.
116 //              //
117 //              Stack oob_stack;
118                 
119 //              ArrayList current_rank_specifiers;
120
121 //              DoOptions do_type;
122 //              //
123 //              // Switch stack.
124 //              //
125 //              Stack switch_stack;
126                 
127 //              // Expression stack for nested ifs
128 //              Stack expr_stack; 
129                 
130 //              Stack tmp_blocks;
131 //              Stack statement_stack;
132
133 //              // A stack for With expressions.
134 //              //
135 //              Stack with_stack;
136         
137                 
138 //              static public bool InitialOptionExplicit = false;
139 //              static public bool InitialOptionStrict = false;
140 //              static public bool InitialOptionCompareBinary = true;
141 //              static public ArrayList ImportsList = null;
142
143 //              bool OptionExplicit;
144 //              bool OptionStrict;
145 //              bool OptionCompareBinary;
146
147 //              static public bool UseExtendedSyntax; // for ".mbs" files
148
149 //              bool implicit_modifiers;
150                 
151 //              public override string[] extensions()
152 //              {
153 //                      string [] list = { ".vb", ".mbs" };
154 //                      return list;
155 //              }
156
157
158         /// <summary>
159         ///    The C# Parser
160         /// </summary>
161         public class CSharpParser {
162                 NamespaceEntry  current_namespace;
163                 TypeContainer   current_container;
164                 TypeContainer   current_class;
165         
166                 IIteratorContainer iterator_container;
167
168                 /// <summary>
169                 ///   Current block is used to add statements as we find
170                 ///   them.  
171                 /// </summary>
172                 Block      current_block, top_current_block;
173
174                 /// <summary>
175                 ///   This is used by the unary_expression code to resolve
176                 ///   a name against a parameter.  
177                 /// </summary>
178                 Parameters current_local_parameters;
179
180                 /// <summary>
181                 ///   Using during property parsing to describe the implicit
182                 ///   value parameter that is passed to the "set" and "get"accesor
183                 ///   methods (properties and indexers).
184                 /// </summary>
185                 Expression implicit_value_parameter_type;
186                 Parameters indexer_parameters;
187
188                 /// <summary>
189                 ///   Used to determine if we are parsing the get/set pair
190                 ///   of an indexer or a property
191                 /// </summmary>
192                 bool  parsing_indexer;
193
194                 ///
195                 /// An out-of-band stack.
196                 ///
197                 Stack oob_stack;
198
199                 ///
200                 /// Switch stack.
201                 ///
202                 Stack switch_stack;
203
204                 static public int yacc_verbose_flag;
205
206                 // Name of the file we are parsing
207                 public string name;
208
209                 ///
210                 /// The current file.
211                 ///
212                 SourceFile file;
213                 
214                 ///   This is used by the sub_header parser to store modifiers
215                 ///   to be passed to sub/constructor  
216                 int current_modifiers;          
217                         
218                 ///   This is used by the sub_header parser to store attributes
219                 ///   to be passed to sub/constructor  
220                 Attributes current_attributes;                          
221
222                 ///   This is used by the attributes parser to syntactically
223                 ///   validate the attribute rules  
224                 bool allow_global_attribs = true;
225
226                 bool expecting_global_attribs = false;
227                 bool expecting_local_attribs = false;
228
229                 bool local_attrib_section_added = false;
230
231                 ///FIXME
232                 ArrayList current_rank_specifiers;
233
234                 /// <summary>
235                 ///   Using during property parsing to describe the implicit
236                 ///   value parameter that is passed to the "set" accessor
237                 ///   method
238                 /// </summary>
239                 string get_implicit_value_parameter_name;
240                 
241                 // <summary>
242                 //   Using during property parsing to describe the implicit
243                 //   value parameter that is passed to the "set" and "get"accesor
244                 //   methods (properties and indexers).
245                 // </summary>
246                 Expression get_implicit_value_parameter_type;
247                 
248                 /// <summary>
249                 ///   Using during property parsing to describe the implicit
250                 ///   value parameter that is passed to the "set" accessor
251                 ///   method
252                 /// </summary>
253                 string set_implicit_value_parameter_name;
254                 
255                 // <summary>
256                 //   Using during property parsing to describe the implicit
257                 //   value parameter that is passed to the "set" and "get"accesor
258                 //   methods (properties and indexers).
259                 // </summary>
260                 Expression set_implicit_value_parameter_type;           
261
262                 /// <summary>
263                 ///   This are used when parsing parameters in property
264                 ///   declarations.
265                 /// </summary>          
266                 Parameters set_parameters;
267                 Parameters get_parameters;
268
269 //              static public ArrayList ImportsList = null;
270
271                 bool implicit_modifiers;
272
273
274                 /// <summary>
275                 ///   This is used as a helper class for handling of
276                 ///   pre-processor statements.
277                 /// </summary>          
278
279                 // FIXME: This class MBASException is actually a kludge 
280                 // It can be done away with a more elegant replacement.
281
282                 public class MBASException : ApplicationException
283                 {
284                         public int code;
285                         public Location loc;
286
287                         public MBASException(int code, Location loc, string text) : base(text)
288                         {
289                                 this.code = code;
290                                 this.loc = loc;
291                         }
292                 }
293
294
295
296                 public class IfElseStateMachine {
297                         
298                         public enum State {
299                                 START,
300                                 IF_SEEN,
301                                 ELSEIF_SEEN,
302                                 ELSE_SEEN,
303                                 ENDIF_SEEN,
304                                 MAX
305                         }
306                 
307                         public enum Token {
308                                 START,
309                                 IF,
310                                 ELSEIF,
311                                 ELSE,
312                                 ENDIF,
313                                 EOF,
314                                 MAX
315                         }
316
317                         State state;
318                         Stack stateStack;
319
320                         public static Hashtable errStrings = new Hashtable();
321
322                         int err=0;
323                         static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
324                 
325                         static IfElseStateMachine()
326                         {
327                                 // FIXME: Fix both the error nos and the error strings. 
328                                 // Currently the error numbers and the error strings are 
329                                 // just placeholders for getting the state-machine going.
330
331                                 errStrings.Add(0, "");
332                                 errStrings.Add(30012, "#If must end with a matching #End If");
333                                 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
334                                 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
335                                 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
336                                 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
337
338                                 errTable[(int)State.START, (int)Token.IF] = 0;
339                                 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
340                                 errTable[(int)State.START, (int)Token.ELSE] = 30028;
341                                 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
342                                 errTable[(int)State.START, (int)Token.EOF] = 0;
343
344                                 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
345                                 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
346                                 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
347                                 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
348                                 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
349
350                                 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
351                                 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
352                                 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
353                                 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
354                                 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
355
356                                 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
357                                 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
358                                 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
359                                 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
360                                 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
361
362                                 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
363                                 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
364                                 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
365                                 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
366                                 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
367                         }
368
369                         public IfElseStateMachine()
370                         {
371                                 state = State.START;
372
373                                 stateStack = new Stack();
374                                 stateStack.Push(state);
375                         }
376
377                         // The parameter here need not be qualified with IfElseStateMachine
378                         // But it hits a bug in mcs. So temporarily scoping it so that builds
379                         // are not broken.
380
381                         public void HandleToken(IfElseStateMachine.Token tok)
382                         {       
383                                 err = (int) errTable[(int)state, (int)tok];
384
385                                 if(err != 0)
386                                         throw new ApplicationException("Unexpected pre-processor directive #"+tok); 
387                                 
388                                 if(tok == Token.IF) {
389                                         stateStack.Push(state);
390                                         state = (State) tok;
391                                 }
392                                 else if(tok == Token.ENDIF) {
393                                         state = (State)stateStack.Pop();
394                                 }
395                                 else
396                                         state = (State)tok;
397                         }
398
399                         public int Error {
400                                 get {
401                                         return err;
402                                 }
403                         }
404
405                         public string ErrString {
406                                 get {
407                                         return (string) errStrings[err];
408                                 }
409                         }
410                 }
411
412                 
413                 public class TokenizerController {
414                         
415                         struct State
416                         {
417                                 public bool CanAcceptTokens;
418                                 public bool CanSelectBlock;
419
420                         }
421
422                         State currentState;
423                         Stack stateStack;
424                         Tokenizer lexer;
425
426                         public TokenizerController(Tokenizer lexer)
427                         {
428                                 this.lexer = lexer;
429                                 stateStack = new Stack();
430
431                                 currentState.CanAcceptTokens = true;
432                                 currentState.CanSelectBlock = true;
433
434                                 stateStack.Push(currentState);
435                         }
436
437                         State parentState {
438                                 get {
439                                         return (State)stateStack.Peek();
440                                 }
441                         }
442
443                         public bool IsAcceptingTokens {
444                                 get {
445                                         return currentState.CanAcceptTokens;
446                                 }
447                         }
448
449                         public void PositionCursorAtNextPreProcessorDirective()
450                         {
451                                 lexer.PositionCursorAtNextPreProcessorDirective();
452                         }
453
454                         public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
455                         {
456                                 if(tok == IfElseStateMachine.Token.ENDIF) {
457                                         currentState = (State)stateStack.Pop();
458
459                                         if(currentState.CanAcceptTokens)
460                                                 return;
461                                         else {
462                                                 PositionCursorAtNextPreProcessorDirective();
463                                                 return;
464                                         }
465                                 }
466                                 
467                                 if(tok == IfElseStateMachine.Token.IF) {
468                                         stateStack.Push(currentState);
469                                         
470                                         currentState.CanAcceptTokens = parentState.CanAcceptTokens;
471                                         currentState.CanSelectBlock = true;
472                                 }
473                         
474                                 if(parentState.CanAcceptTokens && 
475                                    currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
476                                     
477                                         currentState.CanAcceptTokens = true;
478                                         currentState.CanSelectBlock = false; 
479                                         return;
480                                 }
481                                 else {
482                                         currentState.CanAcceptTokens = false;
483                                         PositionCursorAtNextPreProcessorDirective();
484                                         return;
485                                 }
486                         }
487                 }
488
489                 bool in_external_source = false;
490                 int in_marked_region = 0;
491
492                 TokenizerController tokenizerController;
493                 IfElseStateMachine ifElseStateMachine;
494
495
496
497 %}
498
499 %token EOF
500 %token NONE   /* This token is never returned by our lexer */
501 %token ERROR  // This is used not by the parser, but by the tokenizer.
502               // do not remove.
503
504 /*
505  *These are the MonoBASIC keywords
506  */
507 %token ADDHANDLER
508 %token ADDRESSOF
509 %token ALIAS
510 %token AND
511 %token ANDALSO
512 %token ANSI
513 %token AS
514 %token ASSEMBLY
515 %token AUTO
516 %token BINARY
517 %token BOOLEAN  
518 %token BYREF
519 %token BYTE
520 %token BYVAL    
521 %token CALL
522 %token CASE     
523 %token CATCH    
524 %token CBOOL
525 %token CBYTE
526 %token CCHAR    
527 %token CDATE
528 %token CDEC
529 %token CDBL
530 %token CHAR     
531 %token CINT
532 %token CLASS
533 %token CLNG
534 %token COBJ
535 %token COMPARE  
536 %token CONST    
537 %token CSHORT   
538 %token CSNG
539 %token CSTR
540 %token CTYPE
541 %token DATE
542 %token DECIMAL  
543 %token DECLARE
544 %token DEFAULT  
545 %token DELEGATE 
546 %token DIM
547 %token DIRECTCAST
548 %token DO       
549 %token DOUBLE   
550 %token EACH     
551 %token ELSE
552 %token ELSEIF
553 %token END
554 %token ENDIF
555 %token ENUM     
556 %token EOL
557 %token ERASE
558 %token ERROR
559 %token EVENT
560 %token EXIT     
561 %token EXPLICIT 
562 %token FALSE    
563 %token FINALLY  
564 %token FOR      
565 %token FRIEND
566 %token FUNCTION
567 %token GET
568 %token GETTYPE
569 %token GOSUB
570 %token GOTO     
571 %token HANDLES
572 %token IF       
573 %token IMPLEMENTS
574 %token IMPORTS  
575 %token IN       
576 %token INHERITS
577 %token INTEGER  
578 %token INTERFACE
579 %token IS
580 %token LET
581 %token LIB      
582 %token LIKE     
583 %token LONG     
584 %token LOOP
585 %token ME
586 %token MOD
587 %token MODULE
588 %token MUSTINHERIT      
589 %token MUSTOVERRIDE
590 %token MYBASE
591 %token MYCLASS
592 %token NAMESPACE
593 %token NEW
594 %token NEXT     
595 %token NOT
596 %token NOTHING
597 %token NOTINHERITABLE
598 %token NOTOVERRIDABLE
599 %token OBJECT   
600 %token OFF
601 %token ON
602 %token OPTION   
603 %token OPTIONAL 
604 %token OR
605 %token ORELSE
606 %token OVERLOADS
607 %token OVERRIDABLE      
608 %token OVERRIDES        
609 %token PARAM_ARRAY
610 %token PRESERVE
611 %token PRIVATE  
612 %token PROPERTY
613 %token PROTECTED
614 %token PUBLIC
615 %token RAISEEVENT
616 %token READONLY 
617 %token REDIM
618 %token REM
619 %token REMOVEHANDLER
620 %token RESUME   
621 %token RETURN
622 %token SELECT
623 %token SET
624 %token SHADOWS
625 %token SHARED
626 %token SHORT    
627 %token SINGLE
628 %token SIZEOF   
629 %token STATIC   
630 %token STEP
631 %token STOP
632 %token STRICT   
633 %token STRING
634 %token STRUCTURE
635 %token SUB
636 %token SYNCLOCK
637 %token TEXT
638 %token THEN
639 %token THROW
640 %token TO
641 %token TRUE     
642 %token TRY      
643 %token TYPEOF   
644 %token UNICODE
645 %token UNTIL
646 %token VARIANT  
647 %token WEND
648 %token WHEN     
649 %token WHILE    
650 %token WITH
651 %token WITHEVENTS
652 %token WRITEONLY
653 %token XOR
654 %token YIELD // MonoBASIC extension
655
656 %token HASH
657
658 /* MonoBASIC single character operators/punctuation. */
659
660 %token OPEN_BRACKET  "["
661 %token CLOSE_BRACKET "]"
662 %token OPEN_PARENS   "("
663 %token OPEN_BRACE    "{"
664 %token CLOSE_BRACE   "}"
665 %token CLOSE_PARENS  ")"
666 %token DOT           "."
667 %token COMMA         ","
668 %token COLON         ":"
669
670 %token PLUS           "+"
671 %token MINUS          "-"
672 %token ASSIGN         "="
673 %token OP_LT          "<"
674 %token OP_GT          ">"
675 %token STAR           "*"
676 %token DIV            "/"
677 %token OP_EXP         "^"
678 %token INTERR         "?"
679 %token OP_IDIV        "\\" //FIXME: This should be "\"
680 %token OP_CONCAT      "&"
681 %token EXCLAMATION    "!"
682
683 %token PERCENT        "%"
684 %token LONGTYPECHAR   "&"
685 %token AT_SIGN            "@"
686 %token SINGLETYPECHAR "!"
687 %token NUMBER_SIGN    "#"
688 %token DOLAR_SIGN     "$"
689
690 %token ATTR_ASSIGN        ":="
691
692 /* MonoBASIC multi-character operators. */
693 %token OP_LE                  "<="
694 %token OP_GE                  ">="
695 %token OP_NE                  "<>"
696 %token OP_XOR                 "xor"
697 //%token OP_MODULUS             //"mod"
698
699 /* VB.NET 2003 new bit-shift operators */
700 %token OP_SHIFT_LEFT              "<<"
701 %token OP_SHIFT_RIGHT         ">>"
702
703 /* Numbers */
704 %token LITERAL_INTEGER           "int literal"
705 %token LITERAL_SINGLE            "float literal"
706 %token LITERAL_DOUBLE            "double literal"
707 %token LITERAL_DECIMAL           "decimal literal"
708 %token LITERAL_CHARACTER         "character literal"
709 %token LITERAL_STRING            "string literal"
710 %token LITERAL_DATE              "datetime literal"
711
712 %token IDENTIFIER
713
714 /* Add precedence rules to solve dangling else s/r conflict */
715 %nonassoc LOWPREC
716 %nonassoc IF
717 %nonassoc ELSE
718 %right ASSIGN
719 %left OP_OR
720 %left OP_AND
721 %left BITWISE_OR
722 %left BITWISE_AND
723 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
724 %left PLUS MINUS
725 %left STAR DIV PERCENT
726 %right BITWISE_NOT CARRET UMINUS
727 %nonassoc OP_INC OP_DEC
728 %left OPEN_PARENS
729 %left OPEN_BRACKET OPEN_BRACE
730 %left DOT
731 %right NOT
732 %nonassoc HIGHPREC
733
734 %start compilation_unit
735 %%
736
737 end_of_stmt
738         : logical_end_of_line
739         | COLON
740         ;       
741
742 logical_end_of_line
743         : EOL
744         | logical_end_of_line pp_directive 
745         ;
746
747 compilation_unit
748         : logical_end_of_line
749           opt_option_directives
750           opt_imports_directives 
751           declarations 
752           EOF
753           {
754                 $$=$4;
755           }
756         |logical_end_of_line
757           opt_option_directives
758           opt_imports_directives 
759           opt_attributes
760           EOF
761           {
762                 /* ????? */ ;
763           }
764         ;
765           
766 opt_option_directives
767         : /* empty */
768         | option_directives
769         ;
770         
771 option_directives
772         : option_directive
773         | option_directives option_directive
774         ;
775         
776 option_directive
777         : option_explicit_directive
778         | option_strict_directive
779         | option_compare_directive
780         ;
781         
782 on_off
783         : /* empty */
784           {
785                   $$ = (object)true;
786           }
787         | ON
788           {
789                   $$ = (object)true;
790           }
791         | OFF
792           {
793                   $$ = (object)false;
794           }
795         ;
796           
797 text_or_binary
798         : BINARY
799           {
800                   $$ = (object)true;
801           }
802         | TEXT
803           {
804                   $$ = (object)false;
805           }
806         ;
807           
808 option_explicit_directive
809         : OPTION EXPLICIT on_off logical_end_of_line
810           {
811 //              if (!UseExtendedSyntax)
812 //                      OptionExplicit = (bool)$3;
813 //              else
814 //                      Report.Warning (
815 //                              9999, lexer.Location, 
816 //                              "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
817           }
818         ;
819           
820                         
821 option_strict_directive
822         : OPTION STRICT on_off logical_end_of_line
823           {
824 //              if (!UseExtendedSyntax)
825 //                      OptionStrict = (bool)$3;
826 //              else
827 //                      Report.Warning (
828 //                              9999, lexer.Location, 
829 //                              "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
830           }
831         ;
832           
833 option_compare_directive
834         : OPTION COMPARE text_or_binary logical_end_of_line
835           {
836 //              OptionCompareBinary = (bool)$3;
837           }
838         ;
839
840 opt_declarations
841         : /* empty */
842         | declarations
843         ;               
844
845 declarations
846         : declaration
847         | declarations declaration
848         ;
849         
850 declaration
851         : declaration_qualifiers
852           {
853 //              FIXME: Need to check declaration qualifiers for multi-file compilation
854 //              FIXME: Qualifiers cannot be applied to namespaces
855                 allow_global_attribs = false;
856           }
857           namespace_declaration
858           {
859                 current_namespace.DeclarationFound = true;
860           }
861         | declaration_qualifiers
862           {
863                   // FIXME: Need to check declaration qualifiers for multi-file compilation
864                   allow_global_attribs = false;
865           }
866           type_spec_declaration
867           {
868                 string name = "";
869                 int mod_flags;
870
871                 if ($3 is Class){
872                         Class c = (Class) $3;
873                         mod_flags = c.ModFlags;
874                         name = c.Name;
875                 } else if ($3 is Struct){
876                         Struct s = (Struct) $3;
877                         mod_flags = s.ModFlags;
878                         name = s.Name;
879                 } else
880                         break;
881
882                 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
883                         Report.Error (
884                                 1527, lexer.Location, 
885                                 "Namespace elements cant be explicitly " +
886                                 "declared private or protected in `" + name + "'");
887                 }
888                 current_namespace.DeclarationFound = true;
889           }
890         ;
891
892 identifier
893         : IDENTIFIER
894         | BINARY
895         | TEXT
896         | COMPARE
897         | EXPLICIT
898         | OFF
899         ;
900
901 type_character
902         : PERCENT                       { $$ = TypeManager.system_int32_expr; }
903         | LONGTYPECHAR                  { $$ = TypeManager.system_int64_expr; }
904         | AT_SIGN                       { $$ = TypeManager.system_decimal_expr; }
905         | SINGLETYPECHAR                { $$ = TypeManager.system_single_expr; }
906         | NUMBER_SIGN                   { $$ = TypeManager.system_double_expr; }
907         | DOLAR_SIGN                    { $$ = TypeManager.system_string_expr; }
908         ;       
909         
910 opt_type_character
911         : /* empty */                   { $$ = null; }
912         | type_character                { $$ = $1; }
913         ;
914         
915
916 qualified_identifier
917         : identifier
918         {
919                 $$ = new MemberName ((string) $1);
920         }
921         | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
922         {
923                 $$ = new MemberName ((MemberName) $1, (string) $3, null);
924           }
925         ;
926         
927 opt_imports_directives
928         : /* empty */
929         | imports_directives
930         ;
931
932 imports_directives
933         : imports_directive 
934         | imports_directives imports_directive 
935         ;
936
937 imports_directive
938         : IMPORTS imports_terms logical_end_of_line
939         ;
940
941 imports_terms
942         : imports_term
943         | imports_terms COMMA imports_term
944         ;
945         
946 imports_term
947         : namespace_or_type_name 
948         {
949                 MemberName ns_name = (MemberName) $1;
950                 current_namespace.Using (ns_name.GetTypeExpression (lexer.Location), lexer.Location);
951         }
952         | identifier ASSIGN namespace_or_type_name 
953         {
954                 MemberName name = (MemberName) $3;
955                 current_namespace.UsingAlias ((string) $1, name.GetTypeExpression (lexer.Location), lexer.Location);
956         }
957         ;
958         
959
960 opt_params
961         : /* empty */   { $$ = Parameters.EmptyReadOnlyParameters; }
962         | OPEN_PARENS CLOSE_PARENS      { $$ = Parameters.EmptyReadOnlyParameters; }
963         | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS    { $$ = $2; }
964         ;
965
966 opt_attributes
967         : /* empty */
968           { 
969                   current_attributes = null;
970           }
971         | attribute_sections    
972           { 
973                 $$ = $1; 
974                 local_attrib_section_added = false;
975                 current_attributes = (Attributes) $1;
976           }
977         ;
978
979 attribute_sections
980         :  attribute_section    
981           { 
982                 $$ = $1;
983                 if ($1 == null) {
984                         expecting_local_attribs = false;
985                         expecting_global_attribs = false;
986                         break;
987                 }
988                 
989                 if (expecting_local_attribs) {
990                         local_attrib_section_added = true;
991                         allow_global_attribs = false;
992
993                         $$ = new Attributes ((ArrayList) $1);
994                 }       
995
996                 if (expecting_global_attribs) {
997                         $$ = null;
998                         CodeGen.AddGlobalAttributes ((ArrayList) $1);
999                 }
1000
1001                 expecting_local_attribs = false;
1002                 expecting_global_attribs = false;
1003           }
1004         | attribute_sections  
1005            {
1006                 $$ = lexer.Location;
1007            }
1008            attribute_section    
1009           {
1010                 $$ = $1;
1011                 if ($3 != null) {
1012                         ArrayList attrs = (ArrayList) $3;
1013
1014                         if (expecting_local_attribs) {
1015                                 if (local_attrib_section_added) {
1016                                         expecting_local_attribs = false;
1017                                         expecting_global_attribs = false;
1018                                         Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
1019                                         break;
1020                                 }
1021
1022                                 if ($1 == null)
1023                                         $$ = new Attributes (attrs);
1024                                 else 
1025                                         ((Attributes) $1).AddAttributes (attrs);
1026
1027                                 local_attrib_section_added = true;
1028                                 allow_global_attribs = false;
1029                         }
1030
1031                         if (expecting_global_attribs) {
1032                                 $$ = null;
1033                                 CodeGen.AddGlobalAttributes ((ArrayList) $3);
1034                         }
1035                 }       
1036
1037                 expecting_local_attribs = false;
1038                 expecting_global_attribs = false;
1039           }
1040         ;
1041
1042 attribute_section
1043         : OP_LT attribute_list OP_GT opt_end_of_stmt
1044           {
1045                 $$ = null;
1046                 if ($2 != null) {
1047                         if (expecting_global_attribs && !(bool) $4) {
1048                                 Report.Error (30205, lexer.Location, "End of statement expected");
1049                                 break;
1050                         }
1051                         
1052                         if (expecting_local_attribs)  {
1053                                 if ((bool) $4) {
1054                                         Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
1055                                         break;
1056                                 }
1057                         }
1058
1059                         $$ = $2;
1060                 }
1061           }
1062         ; 
1063
1064 opt_end_of_stmt
1065         : /* empty */ { $$ = false; }
1066         | end_of_stmt   { $$ = true; }
1067         ;
1068
1069 attribute_list
1070         : attribute 
1071           {
1072                 ArrayList attrs = null;
1073                 if ($1 != null) {
1074                         attrs = new ArrayList ();
1075                         attrs.Add ($1);
1076                 }
1077                 $$ = attrs;
1078           }     
1079         | attribute_list COMMA attribute
1080           {
1081                 ArrayList attrs = null;
1082                 
1083                 if ($3 != null) {
1084                         attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
1085                         attrs.Add ($3);
1086                 }
1087
1088                 $$ = attrs;
1089           }     
1090         ;
1091
1092 attribute 
1093         :  namespace_or_type_name
1094            {
1095                 $$ = lexer.Location;
1096            }
1097            opt_attribute_arguments
1098            {
1099                 $$ = null;
1100                 
1101                 if (expecting_global_attribs)
1102                         Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
1103                 else {
1104                         expecting_local_attribs = true;
1105                         MemberName mname = (MemberName) $1;
1106
1107                         MemberName left = mname.Left;
1108                         string identifier = mname.Name;
1109
1110                         Expression left_expr = left == null ? null : left.GetTypeExpression ((Location)$2);
1111
1112                         $$ = new Attribute (null, left_expr, identifier, (ArrayList) $3, (Location)$2);
1113                 }
1114            }
1115           | attribute_target_specifier 
1116             {
1117                 $$ = lexer.Location;
1118             }
1119             COLON 
1120             namespace_or_type_name
1121            {
1122                   $$ = lexer.Location;
1123            }
1124            opt_attribute_arguments
1125            {
1126                 $$ = null;
1127
1128                 string attribute_target = (string) $1;
1129                 if (attribute_target != "assembly" && attribute_target != "module") {
1130                         Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
1131                         break;
1132                 }
1133                 if (!allow_global_attribs) {
1134                         Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
1135                         break;
1136                 }
1137
1138                 if (expecting_local_attribs) {
1139                         Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
1140                         break;
1141                 }                       
1142
1143                 expecting_global_attribs = true;
1144
1145                 MemberName mname = (MemberName) $4;
1146                 MemberName left = mname.Left;
1147                 string identifier = mname.Name;
1148
1149                 Expression left_expr = left == null ? null : left.GetTypeExpression ((Location) $5);
1150
1151                 $$ = new GlobalAttribute (current_container, attribute_target, left_expr, identifier, (ArrayList) $6, (Location) $5);
1152             }   
1153         ;
1154
1155
1156 attribute_target_specifier
1157         :  ASSEMBLY     { $$ = "assembly"; }
1158         | MODULE        { $$ = "module"; }
1159         | namespace_or_type_name
1160         ;
1161         
1162                         
1163 opt_attribute_arguments
1164         : /* empty */   { $$ = null; }
1165         | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
1166           {
1167                 $$ = $2;
1168           }     
1169         ;
1170
1171 opt_attribute_arguments_list
1172         : /* empty */
1173         | attribute_arguments_list
1174         ;               
1175         
1176 attribute_arguments_list
1177         : positional_argument_list
1178           {
1179                 ArrayList args = new ArrayList (4);
1180                 args.Add ($1);
1181         
1182                 $$ = args;
1183           }
1184         | positional_argument_list COMMA named_argument_list
1185           {
1186                 ArrayList args = new ArrayList (4);
1187                 args.Add ($1);
1188                 args.Add ($3);
1189
1190                 $$ = args;
1191           }
1192         | named_argument_list
1193           {
1194                 ArrayList args = new ArrayList (4);
1195                 args.Add (null);
1196                 args.Add ($1);
1197                 
1198                 $$ = args;
1199           }
1200         ;
1201
1202 positional_argument_list
1203         : constant_expression
1204           {
1205                 ArrayList args = new ArrayList ();
1206                 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
1207
1208                 $$ = args;
1209           }
1210         | positional_argument_list COMMA constant_expression
1211          {
1212                 ArrayList args = (ArrayList) $1;
1213                 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
1214
1215                 $$ = args;
1216          }
1217         ;
1218
1219 named_argument_list
1220         : named_argument
1221           {
1222                 ArrayList args = new ArrayList ();
1223                 args.Add ($1);
1224
1225                 $$ = args;
1226           }
1227         | named_argument_list COMMA named_argument
1228           {       
1229                 ArrayList args = (ArrayList) $1;
1230                 args.Add ($3);
1231
1232                 $$ = args;
1233           }
1234         ;
1235
1236 named_argument
1237         : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
1238           {
1239                 $$ = new DictionaryEntry (
1240                         (string) $1, 
1241                         new Argument ((Expression) $3, Argument.AType.Expression));
1242           }
1243         ;
1244                                 
1245 namespace_declaration
1246         : NAMESPACE qualified_identifier logical_end_of_line
1247         {
1248                 if (current_attributes != null) {
1249                         Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces."
1250                                         + " Expected class, delegate, enum, interface, or struct");
1251                 }
1252
1253                 MemberName name = (MemberName) $2;
1254
1255                 if ((current_namespace.Parent != null) && (name.Left != null)) {
1256                         Report.Error (134, lexer.Location,
1257                                       "Cannot use qualified namespace names in nested " +
1258                                       "namespace declarations");
1259                 }
1260
1261                 current_namespace = new NamespaceEntry (
1262                         current_namespace, file, name.GetName (), lexer.Location);
1263           } 
1264           opt_declarations
1265           END NAMESPACE logical_end_of_line
1266           { 
1267                 current_namespace = current_namespace.Parent;
1268           }
1269
1270         ;
1271
1272 declaration_qualifiers
1273         : opt_attributes opt_modifiers 
1274         ;
1275
1276 type_spec_declaration
1277         : class_declaration
1278         | module_declaration
1279         | interface_declaration
1280         | delegate_declaration
1281         | struct_declaration
1282         | enum_declaration
1283         ;
1284
1285 class_declaration
1286         : CLASS identifier logical_end_of_line 
1287           {
1288                 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1289                         current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1290
1291                 MemberName name = MakeName (new MemberName ((string) $2));
1292                 int mod_flags = current_modifiers;
1293
1294
1295                 current_class = new Class (current_namespace, current_container, name,
1296                                            mod_flags, (Attributes) current_attributes, lexer.Location);
1297
1298
1299                 current_container = current_class;
1300                 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
1301           }
1302           opt_inherits opt_implements
1303
1304           {
1305                 ArrayList bases = (ArrayList) $5;
1306                 ArrayList ifaces = (ArrayList) $6;
1307
1308                 if (ifaces != null){
1309                         if (bases != null)      
1310                                 bases.AddRange(ifaces);
1311                         else
1312                                 bases = ifaces;
1313                 }
1314
1315                 if (bases != null) {
1316                         if (current_class.Name == "System.Object") {
1317                                 Report.Error (537, current_class.Location,
1318                                               "The class System.Object cannot have a base " +
1319                                               "class or implement an interface.");
1320                         }
1321                         current_class.Bases = (ArrayList) bases;
1322                 }
1323
1324                 current_class.Register ();
1325           }
1326           opt_class_member_declarations
1327           END CLASS logical_end_of_line
1328           {
1329                 $$ = current_class;
1330
1331                 current_container = current_container.Parent;
1332                 current_class = current_container;
1333           }
1334         ;
1335
1336 opt_inherits
1337         : /* empty */                           { $$ = null; }
1338         | INHERITS type_list logical_end_of_line        { $$ = $2; }
1339         ;
1340
1341 opt_implements
1342         : /* empty */                           { $$ = null; }
1343         | IMPLEMENTS type_list logical_end_of_line      { $$ = $2; }
1344         ;
1345
1346 opt_modifiers
1347         : /* empty */           
1348         { 
1349                 $$ = (int) 0; 
1350                 current_modifiers = 0; 
1351         }
1352         | modifiers             
1353         { 
1354                 $$ = $1; 
1355                 current_modifiers = (int) $1; 
1356         }
1357         ;
1358         
1359 modifiers
1360         : modifier
1361         | modifiers modifier
1362           { 
1363                 int m1 = (int) $1;
1364                 int m2 = (int) $2;
1365
1366                 if ((m1 & m2) != 0) {
1367                         Location l = lexer.Location;
1368                         Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1369                 }
1370                 $$ = (int) (m1 | m2);
1371           }
1372         ;
1373
1374 modifier
1375         : PUBLIC                        { $$ = Modifiers.PUBLIC; }
1376         | PROTECTED                     { $$ = Modifiers.PROTECTED; }
1377         | PRIVATE                       { $$ = Modifiers.PRIVATE; }
1378         | SHARED                        { $$ = Modifiers.STATIC; }
1379         | FRIEND                        { $$ = Modifiers.INTERNAL; }
1380         | NOTINHERITABLE                { $$ = Modifiers.SEALED; } 
1381         | OVERRIDABLE                   { $$ = Modifiers.VIRTUAL; }
1382         | NOTOVERRIDABLE                { $$ = Modifiers.NONVIRTUAL; }
1383         | OVERRIDES                     { $$ = Modifiers.OVERRIDE; }
1384         | OVERLOADS                     { $$ = Modifiers.NEW; }
1385         | SHADOWS                       { $$ = Modifiers.SHADOWS; }
1386         | MUSTINHERIT                   { $$ = Modifiers.ABSTRACT; }
1387         | READONLY                      { $$ = Modifiers.READONLY; }
1388         | DEFAULT                       { $$ = Modifiers.DEFAULT; }
1389         | WRITEONLY                     { $$ = Modifiers.WRITEONLY; }
1390         ;
1391
1392 module_declaration
1393         : MODULE identifier logical_end_of_line
1394           { 
1395                 MemberName name = MakeName(new MemberName ((string) $2));
1396                 current_class = new VBModule (current_namespace, current_container, name, 
1397                                             current_modifiers, current_attributes, lexer.Location);
1398
1399                 current_container = current_class;
1400                 RootContext.Tree.RecordDecl(name.GetName (true), current_class);
1401
1402                 current_class.Register ();
1403           }
1404           opt_module_member_declarations
1405           END MODULE logical_end_of_line
1406           {
1407                 $$ = current_class;
1408 //              FIXME: ?????
1409 //              TypeManager.AddStandardModule (current_class);
1410
1411                 current_container = current_container.Parent;
1412                 current_class = current_container;
1413           }
1414         ;
1415
1416 opt_module_member_declarations
1417         : /* empty */
1418         | module_member_declarations
1419         ;
1420
1421 module_member_declarations
1422         : module_member_declaration
1423         | module_member_declarations module_member_declaration
1424         ;
1425
1426 module_member_declaration
1427         :  opt_attributes
1428            opt_modifiers
1429            { 
1430                 current_modifiers = ((int)$2) | Modifiers.STATIC; 
1431                 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1432                 implicit_modifiers = (!explicit_static);
1433            }
1434
1435            module_member_declarator
1436            {
1437                 implicit_modifiers = false;
1438                 $$ = $3;
1439            }
1440         ;
1441
1442 module_member_declarator
1443         :  constructor_declaration
1444         |  method_declaration
1445         |  field_declaration
1446 //      |  withevents_declaration       /* This is a field but must be treated specially, see below */
1447         |  constant_declaration
1448         |  property_declaration                 
1449         |  event_declaration
1450         |  type_spec_declaration                        
1451         ;
1452
1453         
1454 constant_declaration
1455         : CONST constant_declarators logical_end_of_line
1456         {
1457                 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1458                         current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1459                 
1460                 int modflags = (int) current_modifiers;
1461                 
1462                 // Structure members are Public by default                      
1463                 if ((current_container is Struct) && (modflags == 0))
1464                         modflags = Modifiers.PUBLIC;                    
1465
1466                 ArrayList consts = (ArrayList) $2;
1467                 if(consts.Count > 0) 
1468                 {
1469                         VariableDeclaration.FixupTypes ((ArrayList) $2);
1470                         VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1471
1472                         foreach (VariableDeclaration constant in (ArrayList) $2){
1473                                 Location l = constant.Location;
1474                                 Const c = new Const (current_class, 
1475                                                      (Expression) constant.type, 
1476                                                      (String) constant.identifier, 
1477                                                      (Expression) constant.expression_or_array_initializer, 
1478                                                      modflags, current_attributes, l);
1479
1480                                 current_container.AddConstant (c);
1481                         }
1482                 }
1483         }
1484         ;
1485            
1486 opt_class_member_declarations
1487         : /* empty */
1488         | class_member_declarations
1489         ;
1490
1491 class_member_declarations
1492         : class_member_declaration
1493         | class_member_declarations class_member_declaration
1494         ;
1495
1496 class_member_declaration
1497         :  opt_attributes
1498            opt_modifiers
1499            class_member_declarator
1500            {
1501                 $$ = $3;
1502            }
1503         ;
1504
1505 class_member_declarator
1506         :  field_declaration
1507         |  constant_declaration
1508         |  method_declaration
1509         |  constructor_declaration
1510         |  property_declaration                 
1511         |  event_declaration
1512 //      |  withevents_declaration       /* This is a field but must be treated specially, see below */
1513         |  type_spec_declaration
1514         ;
1515         
1516         
1517 method_declaration
1518         : sub_declaration
1519         | func_declaration 
1520 //      | must_override_declaration
1521         ;
1522         
1523 // must_override_declaration
1524 //      : must_override_sub_declaration
1525 //      | must_override_func_declaration        
1526 //      ;
1527         
1528 // must_override_sub_declaration
1529 //      : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
1530 //        {     
1531 // //           if (current_container is Module)
1532 // //                   Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1533                         
1534 //              if (current_container is Struct)
1535 //                      Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1536                 
1537 //              current_modifiers |= Modifiers.ABSTRACT;
1538                                         
1539 //              Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1540 //                                          (Parameters) $4, null, (ArrayList) $5, lexer.Location);
1541                                             
1542 //              if (!(current_container is Class))
1543 //                      Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");               
1544                         
1545 //              $$ = method;                        
1546 //        }
1547 //      ;
1548
1549         
1550 // must_override_func_declaration
1551 //      : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1552 //        {     
1553 //              Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.  
1554 //                      system_object_expr : (Expression) $4 ) : (Expression) $6;
1555
1556 //              if (current_container is Module)
1557 //                      Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1558                         
1559 //              if (current_container is Struct)
1560 //                      Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1561                                 
1562 //              current_modifiers |= Modifiers.ABSTRACT;
1563                                                         
1564 //              Method method = new Method ((Expression) ftype, (int) current_modifiers, 
1565 //                                              (string) $3,(Parameters) $5, null, (ArrayList) $7, 
1566 //                                              lexer.Location);
1567                                             
1568 //              if (!(current_container is Class))
1569 //                      Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1570                         
1571 //              $$ = method;                                    
1572 //        }     
1573 //      ;
1574         
1575
1576 sub_declaration
1577         : SUB identifier opt_params 
1578           {
1579                 MemberName name = new MemberName ((string) $2);
1580
1581                 if ((current_container is Struct) && (current_modifiers == 0))
1582                         current_modifiers = Modifiers.PUBLIC;           
1583
1584
1585                 GenericMethod generic = null;
1586                 Method method = new Method (current_class, generic, TypeManager.system_void_expr,
1587                                             (int) current_modifiers, false, name, 
1588                                             (Parameters) $3, (Attributes) current_attributes, 
1589                                             lexer.Location);
1590
1591                 current_local_parameters = (Parameters) $3;
1592                 $$ = method;
1593
1594                 iterator_container = (IIteratorContainer) method;
1595           }
1596           opt_evt_handler opt_implement_clause logical_end_of_line 
1597           // FIXME: opt_event_handler and opt_implements_clause are yet to be handled
1598           begin_block
1599           opt_statement_list 
1600           end_block
1601           END SUB logical_end_of_line
1602           {
1603                 Method method = (Method) $4;
1604                 Block b = (Block) $10;
1605                 const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
1606
1607                 if (b == null){
1608                         if ((method.ModFlags & extern_abstract) == 0){
1609                                 Report.Error (
1610                                         501, lexer.Location,  current_container.MakeName (method.Name) +
1611                                         "must declare a body because it is not marked abstract or extern");
1612                         }
1613                 } else {
1614                         if ((method.ModFlags & Modifiers.EXTERN) != 0){
1615                                 Report.Error (
1616                                         179, lexer.Location, current_container.MakeName (method.Name) +
1617                                         " is declared extern, but has a body");
1618                         }
1619                 }
1620
1621                 method.Block = (ToplevelBlock) $10;
1622                 current_container.AddMethod (method);
1623
1624                 current_local_parameters = null;
1625                 iterator_container = null;
1626           }
1627         ;
1628
1629 func_declaration
1630         : FUNCTION identifier opt_type_character
1631           opt_params opt_type_with_ranks 
1632           {
1633                 MemberName name =  new MemberName ((string) $2);
1634                 Expression rettype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1635
1636                 GenericMethod generic = null;
1637
1638                 Method method = new Method (current_class, generic, rettype, current_modifiers,
1639                                             false, name,  (Parameters) $4, current_attributes,
1640                                             lexer.Location);
1641
1642                 current_local_parameters = (Parameters) $4;
1643
1644                 $$ = method;
1645                 iterator_container = method;
1646           }
1647 //        FIXME: opt_implement_clauses needs to be taken care of
1648           opt_implement_clause logical_end_of_line
1649           begin_block
1650           { 
1651                 Method method = (Method) $6;
1652
1653                 ArrayList retval = new ArrayList ();
1654                 retval.Add (new VariableDeclaration ((string) $2, method.Type, lexer.Location));
1655                 declare_local_variables (method.Type, retval, lexer.Location);
1656           }       
1657           opt_statement_list
1658           end_block
1659           END FUNCTION logical_end_of_line
1660           {
1661                 Method method = (Method) $6;
1662                 Block b = (Block) $12;
1663                 const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
1664
1665                 if (b == null){
1666                         if ((method.ModFlags & extern_abstract) == 0){
1667                                 Report.Error (
1668                                         501, lexer.Location,  current_container.MakeName (method.Name) +
1669                                         "must declare a body because it is not marked abstract or extern");
1670                         }
1671                 } else {
1672                         if ((method.ModFlags & Modifiers.EXTERN) != 0){
1673                                 Report.Error (
1674                                         179, lexer.Location, current_container.MakeName (method.Name) +
1675                                         " is declared extern, but has a body");
1676                         }
1677                 }
1678
1679                 method.Block = (ToplevelBlock) b;
1680                 current_container.AddMethod (method);
1681
1682                 current_local_parameters = null;
1683                 iterator_container = null;
1684           }
1685         ;               
1686
1687 struct_declaration
1688         : STRUCTURE identifier logical_end_of_line
1689           opt_implement_clause
1690           { 
1691                 MemberName name = MakeName (new MemberName ((string) $2));
1692
1693                 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1694                         current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1695
1696                 current_class = new Struct (current_namespace, current_container, name, current_modifiers,
1697                                             current_attributes, lexer.Location);
1698
1699                 current_container = current_class;
1700                 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
1701
1702                 if ($4 != null)
1703                         current_class.Bases = (ArrayList) $4;
1704
1705                 current_class.Register ();
1706           }
1707           opt_struct_member_declarations
1708           {
1709                 $$ = current_class;
1710
1711                 current_container = current_container.Parent;
1712                 current_class = current_container;
1713           }
1714           END STRUCTURE logical_end_of_line
1715         ;
1716
1717
1718
1719 // FIXME: logical_end_of_line is actually part of the opt_implements_clause
1720 // This rule is temporary
1721
1722 opt_logical_end_of_line
1723         : /* empty */
1724         | logical_end_of_line
1725         ;
1726
1727
1728 opt_struct_member_declarations
1729         : /* empty */
1730         | struct_member_declarations
1731         ;
1732
1733 struct_member_declarations
1734         : struct_member_declaration
1735         | struct_member_declarations struct_member_declaration
1736         ;
1737
1738 struct_member_declaration
1739         : opt_modifiers
1740           struct_member_declarator
1741         ;
1742         
1743 struct_member_declarator        
1744         : field_declaration
1745         | constant_declaration
1746         | constructor_declaration
1747         | method_declaration
1748 //      | property_declaration
1749         | event_declaration
1750         | type_spec_declaration
1751
1752         
1753 //       * This is only included so we can flag error 575:
1754 //       * destructors only allowed on class types
1755 //      | destructor_declaration
1756         ;
1757         
1758 // event_declaration
1759 //      : EVENT identifier AS type opt_implement_clause logical_end_of_line
1760 //        {
1761 //              VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1762
1763 //              Event e = new Event ((Expression) $4, var.identifier, 
1764 //                                   null, current_modifiers, 
1765 //                                   current_attributes, (ArrayList) $5,
1766 //                                   lexer.Location);
1767
1768 //              CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1769 //        }
1770 //      | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1771 //        {
1772 //              string delName = null;
1773
1774 //              if ($4 == null) {
1775 //                      delName = (string) $2;
1776 //                      delName = delName + "EventHandler";
1777 //                      Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
1778 //                                                      (current_container, TypeManager.system_void_expr, 
1779 //                                                      (int) current_modifiers, MakeName(delName), (Parameters) $3, 
1780 //                                                      (Attributes) current_attributes, lexer.Location);
1781                                                           
1782 //                      del.Namespace = current_namespace;
1783 //                      CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1784 //              } else {
1785 //                      ArrayList impls = (ArrayList) $4;
1786 //                      if (impls.Count > 1) {
1787 //                              string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1788 //                                      "' can not be implemented with Event '" +
1789 //                                      (string) $2 + "', since it's delegate type does not match " +
1790 //                                      "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1791 //                              Report.Error (31407, lexer.Location, expstr);
1792 //                      }                       
1793 //                      Expression impl = (Expression) impls[0];  
1794 //                      delName = impl.ToString();
1795 //                      delName = delName.Substring (delName.LastIndexOf(".") + 1);
1796 //                      delName = delName + "EventHandler";
1797 //              }
1798                 
1799 //              Event e = new Event (DecomposeQI (delName, lexer.Location),
1800 //                                       (string) $2, 
1801 //                                   null, current_modifiers, 
1802 //                                   current_attributes, (ArrayList) $4, 
1803 //                                   lexer.Location);
1804
1805 //              CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1806 //        }
1807 //      ;
1808         
1809
1810
1811 event_declaration
1812         : EVENT identifier AS type opt_implement_clause logical_end_of_line
1813           {
1814                 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1815
1816                 MemberName name = new MemberName ((string) $2);
1817
1818                 Event e = new EventField (current_class, (Expression) $4, current_modifiers, false, name,
1819                                           var.expression_or_array_initializer, current_attributes,
1820                                           lexer.Location);
1821
1822                 current_container.AddEvent (e);
1823           }
1824
1825 //      | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1826 //        {
1827 //              string delName = null;
1828
1829 //              if ($4 == null) {
1830 //                      delName = (string) $2;
1831 //                      delName = delName + "EventHandler";
1832 //                      Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
1833 //                                                      (current_container, TypeManager.system_void_expr, 
1834 //                                                      (int) current_modifiers, MakeName(delName), (Parameters) $3, 
1835 //                                                      (Attributes) current_attributes, lexer.Location);
1836                                                           
1837 //                      del.Namespace = current_namespace;
1838 //                      CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1839 //              } else {
1840 //                      ArrayList impls = (ArrayList) $4;
1841 //                      if (impls.Count > 1) {
1842 //                              string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1843 //                                      "' can not be implemented with Event '" +
1844 //                                      (string) $2 + "', since it's delegate type does not match " +
1845 //                                      "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1846 //                              Report.Error (31407, lexer.Location, expstr);
1847 //                      }                       
1848 //                      Expression impl = (Expression) impls[0];  
1849 //                      delName = impl.ToString();
1850 //                      delName = delName.Substring (delName.LastIndexOf(".") + 1);
1851 //                      delName = delName + "EventHandler";
1852 //              }
1853                 
1854 //              Event e = new Event (DecomposeQI (delName, lexer.Location),
1855 //                                       (string) $2, 
1856 //                                   null, current_modifiers, 
1857 //                                   current_attributes, (ArrayList) $4, 
1858 //                                   lexer.Location);
1859
1860 //              CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1861 //        }
1862         ;
1863
1864 enum_declaration
1865         : ENUM identifier opt_type_spec logical_end_of_line
1866           opt_enum_member_declarations 
1867           { 
1868                 Location enum_location = lexer.Location;
1869
1870                 Expression base_type = TypeManager.system_int32_expr;
1871                 if ((Expression) $3 != null)
1872                         base_type = (Expression) $3;
1873
1874                 ArrayList enum_members = (ArrayList) $5;
1875                 if (enum_members.Count == 0)
1876                         Report.Error (30280, enum_location,
1877                                       "Enum can not have empty member list");
1878
1879
1880                 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1881                         current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1882                         
1883                 MemberName full_name = MakeName (new MemberName ((string) $2));
1884                 Enum e = new Enum (current_namespace, current_container, base_type, 
1885                                    (int) current_modifiers, full_name, 
1886                                    (Attributes) current_attributes, enum_location);
1887                 
1888                 foreach (VariableDeclaration ev in (ArrayList) $5) {
1889                         e.AddEnumMember (ev.identifier, 
1890                                          (Expression) ev.expression_or_array_initializer,
1891                                          ev.Location, ev.OptAttributes, ev.DocComment);
1892                 }
1893
1894                 string name = full_name.GetName ();
1895                 current_container.AddEnum (e);
1896                 RootContext.Tree.RecordDecl (name, e);
1897
1898           }
1899           END ENUM logical_end_of_line
1900         ;
1901
1902 opt_enum_member_declarations
1903         : /* empty */                   { $$ = new ArrayList (4); }
1904         | enum_member_declarations      { $$ = $1; }
1905         ;
1906
1907 enum_member_declarations
1908         : enum_member_declaration 
1909           {
1910                 ArrayList l = new ArrayList ();
1911
1912                 l.Add ($1);
1913                 $$ = l;
1914           }
1915         | enum_member_declarations  enum_member_declaration
1916           {
1917                 ArrayList l = (ArrayList) $1;
1918
1919                 l.Add ($2);
1920
1921                 $$ = l;
1922           }
1923         ;
1924
1925 enum_member_declaration
1926         : opt_attributes identifier logical_end_of_line
1927           {
1928                 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1929           }
1930         | opt_attributes identifier
1931           {
1932                   $$ = lexer.Location;
1933           }
1934           ASSIGN expression logical_end_of_line
1935           { 
1936                 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1937           }
1938         ;
1939
1940 // interface_property_declaration
1941 //      : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1942 //        {
1943 //              Expression ftype = ($5 == null) ? (($3 == null) ? 
1944 //                              TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1945
1946 //              current_local_parameters = (Parameters) $4;
1947 //              if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
1948 //                      get_parameters = current_local_parameters.Copy (lexer.Location);
1949 //                      set_parameters = current_local_parameters.Copy (lexer.Location);
1950                         
1951 //                      Parameter implicit_value_parameter = new Parameter (
1952 //                                      ftype, "Value", Parameter.Modifier.NONE, null);
1953                         
1954 //                      set_parameters.AppendParameter (implicit_value_parameter);
1955 //              }
1956 //              else
1957 //              {
1958 //                      get_parameters = Parameters.EmptyReadOnlyParameters;
1959 //                      set_parameters = new Parameters (null, null ,lexer.Location); 
1960                         
1961 //                      Parameter implicit_value_parameter = new Parameter (
1962 //                                      ftype, "Value", Parameter.Modifier.NONE, null);
1963                         
1964 //                      set_parameters.AppendParameter (implicit_value_parameter);
1965 //              }
1966 //              lexer.PropertyParsing = true;
1967                 
1968 //              Accessor get_block = new Accessor (null, null); 
1969 //              Accessor set_block = new Accessor (null, null); 
1970                                 
1971 //              Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
1972 //                                       get_block, set_block, current_attributes, lexer.Location,
1973 //                                       null, get_parameters, set_parameters, null);
1974     
1975 //              CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
1976                 
1977 //              get_implicit_value_parameter_type = null;
1978 //              set_implicit_value_parameter_type = null;
1979 //              get_parameters = null;
1980 //              set_parameters = null;
1981 //              current_local_parameters = null;                        
1982 //        }
1983 //      ;
1984         
1985 // interface_event_declaration
1986 //      : EVENT identifier AS type logical_end_of_line
1987 //        {
1988 //              VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1989
1990 //              Event e = new Event ((Expression) $4, var.identifier, 
1991 //                                   null, current_modifiers, 
1992 //                                   current_attributes, lexer.Location);
1993
1994 //              CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1995
1996 //        }
1997 //      | EVENT identifier opt_params logical_end_of_line
1998 //        {
1999 //              string delName = (string) $2;
2000 //              delName = delName + "EventHandler";
2001 //              int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
2002 //          Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
2003 //                                              (current_container, TypeManager.system_void_expr, 
2004 //                                           (int) delModifiers, MakeName(delName), (Parameters) $3, 
2005 //                                           (Attributes) current_attributes, lexer.Location);
2006                                                   
2007 //              del.Namespace = current_namespace;
2008 //              CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
2009           
2010 //              Event e = new Event (DecomposeQI (delName, lexer.Location),
2011 //                                       (string) $2, 
2012 //                                   null, current_modifiers, 
2013 //                                   current_attributes, lexer.Location);
2014
2015 //              CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2016 //        }
2017 //      ;
2018
2019
2020
2021 //FIXME: This apparently doesn't seem to emit the right code with property 
2022 //having opt_property_parameters defined
2023
2024 interface_property_declaration
2025         : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
2026           {
2027                 get_implicit_value_parameter_type  = 
2028                         ($5 == null) ? (($3 == null) ? 
2029                                 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
2030
2031                 current_local_parameters = (Parameters) $4;
2032                 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
2033                         get_parameters = current_local_parameters.Copy (lexer.Location);
2034                         set_parameters = current_local_parameters.Copy (lexer.Location);
2035                         
2036                         Parameter implicit_value_parameter = new Parameter (
2037                                         get_implicit_value_parameter_type, "Value", Parameter.Modifier.NONE, null);
2038                         
2039                         set_parameters.AppendParameter (implicit_value_parameter);
2040                 }
2041                 else
2042                 {
2043                         get_parameters = Parameters.EmptyReadOnlyParameters;
2044                         set_parameters = new Parameters (null, null ,lexer.Location); 
2045                         
2046                         Parameter implicit_value_parameter = new Parameter (
2047                                         get_implicit_value_parameter_type, "Value", Parameter.Modifier.NONE, null);
2048                         
2049                         set_parameters.AppendParameter (implicit_value_parameter);
2050                 }
2051                 lexer.PropertyParsing = true;
2052                 
2053                 Location loc = lexer.Location;
2054                 MemberName name = new MemberName ((string) $2);
2055
2056                 Accessor get_block = new Accessor (null, 0, null, loc); 
2057                 Accessor set_block = new Accessor (null, 0, null, loc); 
2058
2059                 Property prop = new Property (current_class, get_implicit_value_parameter_type, 
2060                                      (int) current_modifiers, true,
2061                                      name, current_attributes, 
2062                                      get_parameters, get_block, 
2063                                      set_parameters, set_block, lexer.Location);
2064                 
2065                 current_container.AddProperty (prop);
2066                 
2067                 get_implicit_value_parameter_type = null;
2068                 set_implicit_value_parameter_type = null;
2069                 get_parameters = null;
2070                 set_parameters = null;
2071                 current_local_parameters = null;                        
2072           }
2073         ;
2074
2075
2076 // interface_event_declaration
2077 //      : EVENT identifier AS type logical_end_of_line
2078 //        {
2079 //              VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
2080
2081 //              Event e = new Event ((Expression) $4, var.identifier, 
2082 //                                   null, current_modifiers, 
2083 //                                   current_attributes, lexer.Location);
2084
2085 //              CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2086
2087 //        }
2088 //      | EVENT identifier opt_params logical_end_of_line
2089 //        {
2090 //              string delName = (string) $2;
2091 //              delName = delName + "EventHandler";
2092 //              int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
2093 //          Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
2094 //                                              (current_container, TypeManager.system_void_expr, 
2095 //                                           (int) delModifiers, MakeName(delName), (Parameters) $3, 
2096 //                                           (Attributes) current_attributes, lexer.Location);
2097                                                   
2098 //              del.Namespace = current_namespace;
2099 //              CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
2100           
2101 //              Event e = new Event (DecomposeQI (delName, lexer.Location),
2102 //                                       (string) $2, 
2103 //                                   null, current_modifiers, 
2104 //                                   current_attributes, lexer.Location);
2105
2106 //              CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2107 //        }
2108 //      ;
2109
2110 interface_declaration
2111         : INTERFACE identifier logical_end_of_line
2112           {
2113                 MemberName name = new MemberName ((string) $2);
2114
2115                 current_class = new Interface (current_namespace, current_container, 
2116                                                name, (int) current_modifiers, 
2117                                                (Attributes) current_attributes, lexer.Location);
2118
2119                 current_container = current_class;
2120                 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
2121
2122           }
2123           opt_interface_base
2124           {
2125                 current_class.Bases = (ArrayList) $5;
2126                 current_class.Register ();
2127           }
2128           interface_body
2129           {
2130                 $$ = current_class;
2131
2132                 current_container = current_container.Parent;
2133                 current_class = current_container;
2134           }
2135           END INTERFACE logical_end_of_line
2136         ;
2137
2138 opt_interface_base
2139         : /* empty */                     { $$ = null; }
2140         | interface_bases                 { $$ = $1; }
2141         ;
2142
2143 interface_bases
2144         : interface_base
2145         | interface_bases interface_base
2146           {
2147                 ArrayList bases = (ArrayList) $1;
2148                 bases.AddRange ((ArrayList) $2);
2149                 $$ = bases;
2150           }
2151         ;
2152
2153 interface_base
2154         : INHERITS type_list logical_end_of_line  { $$ = $2; }
2155         ;
2156
2157 interface_body
2158         : opt_interface_member_declarations
2159         ;
2160
2161 opt_interface_member_declarations
2162         : /* empty */
2163         | interface_member_declarations
2164         ;
2165
2166 interface_member_declarations
2167         : interface_member_declaration
2168         | interface_member_declarations interface_member_declaration
2169         ;
2170
2171 interface_member_declaration
2172         : opt_attributes opt_modifiers interface_member_declarator
2173         ;
2174         
2175 interface_member_declarator
2176         : interface_method_declaration  
2177           { 
2178                 Method m = (Method) $1;
2179
2180                 current_container.AddMethod (m);
2181           }
2182         | interface_property_declaration        
2183 //      | interface_event_declaration 
2184         ;
2185
2186 interface_method_declaration
2187         : SUB identifier opt_params logical_end_of_line
2188           {
2189                 MemberName name = (MemberName) new MemberName ((string) $2);
2190
2191                 GenericMethod generic = null;
2192
2193                 $$ = new Method (current_class, generic, TypeManager.system_void_expr, 
2194                                  (int) current_modifiers, true, name, (Parameters) $3,  
2195                                  (Attributes) current_attributes, lexer.Location);
2196           }
2197
2198         | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
2199           {
2200                 MemberName name = new MemberName ((string) $2);
2201                 Expression return_type = ($5 == null) ? 
2202                         (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) 
2203                         : (Expression) $5;
2204
2205                 GenericMethod generic = null;
2206                 $$ = new Method (current_class, generic, return_type, (int) current_modifiers, 
2207                                  true, name, (Parameters) $4, (Attributes) current_attributes,
2208                                  lexer.Location);
2209           }
2210         ;
2211
2212 property_declaration
2213         : non_abstract_propery_declaration
2214 //      | abstract_propery_declaration 
2215         ;
2216         
2217 // abstract_propery_declaration
2218 //      : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
2219 //        {     
2220 //              Expression ftype = ($6 == null) ? (($4 == null) ? 
2221 //                              TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
2222
2223 //              if (current_container is Module)
2224 //                      Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
2225                         
2226 //              if (current_container is Struct)
2227 //                      Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
2228                                 
2229 //              current_modifiers |= Modifiers.ABSTRACT;
2230                 
2231 //              current_local_parameters = (Parameters) $5;
2232 //              if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
2233 //                      get_parameters = current_local_parameters.Copy (lexer.Location);
2234 //                      set_parameters = current_local_parameters.Copy (lexer.Location);
2235                         
2236 //                      Parameter implicit_value_parameter = new Parameter (
2237 //                                      ftype, "Value", Parameter.Modifier.NONE, null);
2238                         
2239 //                      set_parameters.AppendParameter (implicit_value_parameter);
2240 //              }
2241 //              else
2242 //              {
2243 //                      get_parameters = Parameters.EmptyReadOnlyParameters;
2244 //                      set_parameters = new Parameters (null, null ,lexer.Location); 
2245                         
2246 //                      Parameter implicit_value_parameter = new Parameter (
2247 //                                      ftype, "Value", Parameter.Modifier.NONE, null);
2248                         
2249 //                      set_parameters.AppendParameter (implicit_value_parameter);
2250 //              }
2251 //              lexer.PropertyParsing = true;
2252                 
2253 //              Accessor get_block = new Accessor (null, null); 
2254 //              Accessor set_block = new Accessor (null, null); 
2255                                 
2256 //              Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers, 
2257 //                                       get_block, set_block, current_attributes, lexer.Location,
2258 //                                       null, get_parameters, set_parameters, null);
2259     
2260 //              if (!(current_container is Class))
2261 //                      Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
2262                         
2263 //              CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
2264                 
2265 //              get_implicit_value_parameter_type = null;
2266 //              set_implicit_value_parameter_type = null;
2267 //              get_parameters = null;
2268 //              set_parameters = null;
2269 //              current_local_parameters = null;                                
2270 //        }     
2271 //      ;
2272         
2273 non_abstract_propery_declaration
2274           : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
2275           {
2276                 get_implicit_value_parameter_type  = 
2277                         ($5 == null) ? (($3 == null) ? 
2278                                 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
2279                 get_implicit_value_parameter_name = (string) $2;
2280                 
2281                 current_local_parameters = (Parameters) $4;
2282                 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
2283                         get_parameters = current_local_parameters.Copy (lexer.Location);
2284                         set_parameters = current_local_parameters.Copy (lexer.Location);
2285                 }
2286                 else
2287                 {
2288                         get_parameters = Parameters.EmptyReadOnlyParameters;
2289                         set_parameters = new Parameters (null, null ,lexer.Location);           
2290                 }
2291                 lexer.PropertyParsing = true;
2292
2293                 $$ = lexer.Location;
2294           }
2295           accessor_declarations 
2296           END PROPERTY logical_end_of_line
2297           {
2298                 lexer.PropertyParsing = false;
2299
2300                 Property prop;
2301                 Pair pair = (Pair) $9;
2302                 
2303                 Accessor get_block = (Accessor) pair.First; 
2304                 Accessor set_block = (Accessor) pair.Second; 
2305                 
2306                 Location loc = lexer.Location;
2307                 MemberName name = new MemberName ((string) $2);
2308
2309                 // FIXME: Implements Clause needs to be taken care of.
2310
2311                 if ((current_container is Struct) && (current_modifiers == 0))
2312                         current_modifiers = Modifiers.PUBLIC;                           
2313
2314
2315                 prop = new Property (current_class, get_implicit_value_parameter_type, 
2316                                      (int) current_modifiers, false,
2317                                      name, (Attributes) current_attributes, 
2318                                      get_parameters, get_block, 
2319                                      set_parameters, set_block, lexer.Location);
2320                 
2321                 current_container.AddProperty (prop);
2322                 get_implicit_value_parameter_type = null;
2323                 set_implicit_value_parameter_type = null;
2324                 get_parameters = null;
2325                 set_parameters = null;
2326                 current_local_parameters = null;
2327           }
2328         ;
2329
2330 opt_property_parameters
2331         : /* empty */
2332           {
2333                 $$ = Parameters.EmptyReadOnlyParameters;
2334           }
2335         | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2336           {
2337                 $$ = $2;
2338           }
2339         ;
2340         
2341 opt_implement_clause
2342         : /* empty */
2343           {
2344                 $$ = null;
2345           }
2346         | IMPLEMENTS implement_clause_list
2347           {
2348                 $$ = $2;
2349           }
2350         ;
2351         
2352 implement_clause_list
2353         : qualified_identifier
2354           {
2355                   MemberName mname = (MemberName) $1;
2356                   ArrayList impl_list = new ArrayList ();
2357                   impl_list.Add (mname.GetTypeExpression (lexer.Location));
2358                   $$ = impl_list;
2359           }     
2360         | implement_clause_list COMMA qualified_identifier
2361           {
2362                   MemberName mname = (MemberName) $3;
2363                   ArrayList impl_list = (ArrayList) $1;
2364                   impl_list.Add (mname.GetTypeExpression (lexer.Location));
2365                   $$ = impl_list;
2366           }     
2367         ;
2368
2369 accessor_declarations
2370         : get_accessor_declaration opt_set_accessor_declaration
2371           { 
2372                 $$ = new Pair ($1, $2);
2373           }
2374         | set_accessor_declaration opt_get_accessor_declaration
2375           {
2376                 $$ = new Pair ($2, $1);
2377           }
2378         ;
2379
2380 opt_get_accessor_declaration
2381         : /* empty */                   { $$ = null; }
2382         | get_accessor_declaration
2383         ;
2384
2385 opt_set_accessor_declaration
2386         : /* empty */                   { $$ = null; }
2387         | set_accessor_declaration
2388         ;
2389
2390 get_accessor_declaration
2391         : opt_attributes GET logical_end_of_line
2392           {
2393                 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
2394                         Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
2395           
2396                 current_local_parameters = get_parameters;
2397                 
2398                 lexer.PropertyParsing = false;
2399                 
2400           }
2401           begin_block
2402           {
2403                 ArrayList retval = new ArrayList ();
2404                 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
2405                 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);    
2406           }
2407           opt_statement_list
2408           end_block
2409           END GET logical_end_of_line
2410           {
2411                 $$ = new Accessor ((ToplevelBlock) $8, (int) current_modifiers, 
2412                                    (Attributes) $1, lexer.Location);
2413
2414                 current_local_parameters = null;
2415                 lexer.PropertyParsing = true;
2416           }
2417         ;
2418
2419
2420
2421 set_accessor_declaration
2422         : opt_attributes SET opt_set_parameter logical_end_of_line
2423           {
2424         if ((current_modifiers & Modifiers.READONLY) != 0)
2425                         Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
2426                         
2427                 Parameter implicit_value_parameter = new Parameter (
2428                         set_implicit_value_parameter_type, 
2429                         set_implicit_value_parameter_name, 
2430                         Parameter.Modifier.NONE, null);
2431
2432                 set_parameters.AppendParameter (implicit_value_parameter);
2433                 current_local_parameters = set_parameters;
2434
2435                 lexer.PropertyParsing = false;
2436           }
2437           begin_block
2438           opt_statement_list
2439           end_block
2440           END SET logical_end_of_line
2441           {
2442                 $$ = new Accessor ((ToplevelBlock) $8, (int) current_modifiers, 
2443                                    (Attributes) $1, lexer.Location);
2444                 current_local_parameters = null;
2445                 lexer.PropertyParsing = true;
2446           }
2447         ;
2448
2449 opt_set_parameter
2450         : /* empty */
2451         {
2452                 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2453                 set_implicit_value_parameter_name = "Value";
2454         }       
2455         |OPEN_PARENS CLOSE_PARENS
2456         {
2457                 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2458                 set_implicit_value_parameter_name = "Value";
2459         }       
2460         | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2461         {
2462                 Parameter.Modifier pm = (Parameter.Modifier)$2;
2463                 if ((pm | Parameter.Modifier.VAL) != 0)
2464                         Report.Error (31065, 
2465                                 lexer.Location, 
2466                                 "Set cannot have a paremeter modifier other than 'ByVal'");
2467                                 
2468                 set_implicit_value_parameter_type = (Expression) $4;
2469                 
2470                 if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
2471                         Report.Error (31064, 
2472                                 lexer.Location, 
2473                                 "Set value parameter type can not be different from property type");
2474                                 
2475                 if ($2 != null)
2476                         set_implicit_value_parameter_name = (string) $3;
2477                 else
2478                         set_implicit_value_parameter_name = "Value";
2479         }
2480         ;
2481
2482 field_declaration
2483         : opt_dim_stmt 
2484           variable_declarators logical_end_of_line
2485           {               
2486                 int mod = (int) current_modifiers;
2487
2488                 VariableDeclaration.FixupTypes ((ArrayList) $2);
2489                 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2490                 
2491 //              if (current_container is Module)
2492 //                      mod = mod | Modifiers.STATIC;
2493                         
2494                 // Structure members are Public by default                      
2495                 if ((current_container is Struct) && (mod == 0))
2496                         mod = Modifiers.PUBLIC;                 
2497                 
2498                 if ((mod & Modifiers.Accessibility) == 0)
2499                         mod |= Modifiers.PRIVATE;
2500                                         
2501                 foreach (VariableDeclaration var in (ArrayList) $2){
2502                         Location l = var.Location;
2503                         Field field = new Field (current_class, var.type, mod, 
2504                                                  var.identifier, var.expression_or_array_initializer, 
2505                                                  (Attributes) null, l);
2506
2507                         current_container.AddField (field);
2508                 }
2509           }
2510         ;
2511
2512         
2513 // withevents_declaration
2514 //      : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2515 //        {
2516 //              // Module members are static by default, but delegates *can't* be declared static
2517 //              // so we must fix it, if mbas was the one actually responsible for this
2518 //              // instead of triggering an error.
2519 //              if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2520 //                      current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2521           
2522 //              /* WithEvents Fields must be resolved into properties
2523 //                 with a bit of magic behind the scenes */
2524                   
2525 //              VariableDeclaration.FixupTypes ((ArrayList) $3);
2526                 
2527 //              foreach (VariableDeclaration var in (ArrayList) $3) {
2528 //                      // 1 - We create a private field
2529 //                      Location l = var.Location;
2530 //                      Property prop;
2531 //                      if ((current_modifiers & Modifiers.STATIC) > 0) 
2532 //                              Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2533                         
2534 //                      Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier, 
2535 //                                               var.expression_or_array_initializer, 
2536 //                                               (Attributes) null, l);
2537                                                  
2538 //                      CheckDef (current_container.AddField (field), field.Name, l);   
2539                         
2540 //                      // 2 - Public property
2541                                 
2542 //                      prop = BuildSimpleProperty (var.type, (string) var.identifier, 
2543 //                                              field, (int) current_modifiers, 
2544 //                                              (Attributes) current_attributes, l);
2545                         
2546 //                      CheckDef (current_container.AddProperty (prop), prop.Name, l);
2547 //              }               
2548 //        }
2549 //      ;
2550         
2551 opt_dim_stmt 
2552         : /* empty */
2553         | DIM
2554         ; 
2555                 
2556 delegate_declaration
2557         : DELEGATE SUB  
2558           identifier OPEN_PARENS 
2559           opt_formal_parameter_list
2560           CLOSE_PARENS 
2561           logical_end_of_line
2562           {
2563                 Location l = lexer.Location;
2564                 MemberName name = MakeName (new MemberName ((string) $3));
2565
2566                 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2567                         current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2568
2569                 Delegate del = new Delegate (current_namespace, current_container, TypeManager.system_void_expr,
2570                                              current_modifiers, name, (Parameters) $5, current_attributes, l);
2571
2572                 current_container.AddDelegate (del);
2573                 RootContext.Tree.RecordDecl (name.GetName (true), del);
2574           }     
2575         
2576         | DELEGATE FUNCTION       
2577           identifier OPEN_PARENS 
2578           opt_formal_parameter_list
2579           CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2580           {
2581                 Location l = lexer.Location;
2582                 MemberName name = MakeName (new MemberName ((string) $3));
2583
2584                 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2585                         current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2586
2587                 Expression rettype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2588                 Delegate del = new Delegate (current_namespace, current_container, rettype,
2589                                              current_modifiers, name, (Parameters) $5, current_attributes, l);
2590
2591                 current_container.AddDelegate (del);
2592                 RootContext.Tree.RecordDecl (name.GetName (true), del);
2593           }     
2594
2595         ;
2596
2597
2598 opt_evt_handler
2599         : /* empty */           {       $$ = null; }
2600 //        | HANDLES evt_handler         {       $$ = $2; }
2601     ;
2602
2603 // evt_handler
2604 //      : qualified_identifier
2605 //        {
2606 //              $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);     
2607 //        }
2608 //      | base_access
2609 //        {
2610 //              $$ = $1;
2611 //        }
2612 //      | ME DOT qualified_identifier
2613 //        {
2614 //              $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);     
2615 //        }
2616 //      /*| MYBASE DOT qualified_identifier
2617 //        {
2618 //              // FIXME: this is blatantly wrong and crash-prone
2619 //              $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2620 //        }*/
2621 //      ;
2622
2623
2624 constructor_declaration
2625         : SUB NEW opt_params logical_end_of_line
2626           {
2627                 current_local_parameters = (Parameters) $3;
2628                 $$ = new Constructor (current_class, current_container.Basename, 0, (Parameters) $3, 
2629                                       (ConstructorInitializer) null, lexer.Location);
2630           }
2631           begin_block
2632           opt_statement_list
2633           end_block
2634           { 
2635                 Constructor c = (Constructor) $5;
2636                 c.Block = (ToplevelBlock) $8;
2637                 c.ModFlags = (int) current_modifiers;
2638                 c.OptAttributes = current_attributes;
2639
2640                 // FIXME: Some more error checking from mcs needs to be merged here ???
2641                 
2642                 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2643
2644                 current_container.AddConstructor(c);
2645                 current_local_parameters = null;
2646           }
2647           END SUB logical_end_of_line
2648         ;
2649
2650 opt_formal_parameter_list
2651         : /* empty */                   
2652           { 
2653                 $$ = Parameters.EmptyReadOnlyParameters; 
2654           }
2655         | formal_parameter_list 
2656           { 
2657                 $$ = $1;        
2658           }
2659         ;
2660         
2661 formal_parameter_list
2662         : parameters            
2663           { 
2664                 ArrayList pars_list = (ArrayList) $1;
2665                 Parameter [] pars = null; 
2666                 Parameter array_parameter = null;
2667                 int non_array_count = pars_list.Count;
2668                 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2669                         array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2670                         non_array_count = pars_list.Count - 1;
2671                 }
2672                 foreach (Parameter par in pars_list)
2673                         if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2674                                 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2675                                 non_array_count = 0; 
2676                                 array_parameter = null;
2677                                 break;
2678                         }
2679                 if (non_array_count > 0) {
2680                         pars = new Parameter [non_array_count];
2681                         pars_list.CopyTo (0, pars, 0, non_array_count);
2682                 }
2683                 $$ = new Parameters (pars, array_parameter, lexer.Location); 
2684           } 
2685         ;
2686
2687 parameters
2688         : parameter     
2689           {
2690                 ArrayList pars = new ArrayList ();
2691
2692                 pars.Add ($1);
2693                 $$ = pars;
2694           }
2695         | parameters COMMA parameter
2696           {
2697                 ArrayList pars = (ArrayList) $1;
2698
2699                 pars.Add ($3);
2700                 $$ = $1;
2701           }
2702         ;
2703
2704 parameter
2705         : opt_attributes
2706           opt_parameter_modifier
2707           identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2708           {
2709                 Parameter.Modifier pm = (Parameter.Modifier)$2;
2710                 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2711                 Expression ptype;
2712                 
2713                 if (opt_parm && ($7 == null))
2714                         Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
2715
2716                 if (!opt_parm && ($7 != null))
2717                         Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
2718
2719                 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2720                         if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2721                                 Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
2722                 }
2723                 
2724                 if ((pm & Parameter.Modifier.REF) !=0)
2725                         pm |= Parameter.Modifier.ISBYREF;
2726                 
2727                 if ($4 != null && $6 != null && $4 != $6)
2728                         Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2729
2730                 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2731                 if ($5 != null) {
2732                         string t = ptype.ToString ();
2733                         if (t.IndexOf('[') >= 0)
2734                                 Report.Error (31087, lexer.Location, "Array types specified in too many places");
2735                         else    
2736                                 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
2737                 }
2738                 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2739                         Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
2740                 $$ = new Parameter (ptype, (string) $3, pm,
2741                                         (Attributes) $1, (Expression) $7, opt_parm);
2742           }
2743         ;
2744         
2745 opt_parameter_modifier
2746         : /* empty */           { $$ = Parameter.Modifier.VAL;  }
2747         | parameter_modifiers   { $$ = $1;                      }
2748         ;
2749
2750 parameter_modifiers
2751         : parameter_modifiers parameter_modifier        { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2752         | parameter_modifier                            { $$ = $1;      }
2753         ;
2754         
2755 parameter_modifier
2756         : BYREF                 { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2757         | BYVAL                 { $$ = Parameter.Modifier.VAL; }
2758         | OPTIONAL              { $$ = Parameter.Modifier.OPTIONAL; } 
2759         | PARAM_ARRAY           { $$ = Parameter.Modifier.PARAMS; } 
2760         ;       
2761
2762 opt_statement_list
2763         : /* empty */
2764         | statement_list end_of_stmt
2765         ;
2766
2767 statement_list
2768         : statement 
2769         | statement_list end_of_stmt statement
2770         ;
2771
2772 block
2773         : begin_block 
2774           opt_statement_list
2775           end_block { $$ = $3; }
2776         ;
2777
2778 begin_block
2779         : /* empty */
2780         {
2781                   if (current_block == null){
2782                           current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, lexer.Location);
2783                           top_current_block = current_block;
2784                   } else {
2785                   current_block = new Block (current_block, current_local_parameters,
2786                                                  lexer.Location, Location.Null);
2787                   }
2788         } 
2789         ;
2790
2791
2792 end_block
2793         : /* empty */
2794           { 
2795                 while (current_block.Implicit)
2796                         current_block = current_block.Parent;
2797                 $$ = current_block;
2798                 current_block.SetEndLocation (lexer.Location);
2799                 current_block = current_block.Parent;
2800                 if (current_block == null)
2801                         top_current_block = null;
2802           }
2803         ;
2804
2805 statement 
2806           : declaration_statement
2807             {
2808                   if ($1 != null && (Block) $1 != current_block){
2809                         current_block.AddStatement ((Statement) $1);
2810                         current_block = (Block) $1;
2811                   }
2812             }
2813           | embedded_statement
2814             {
2815                   Statement s = (Statement) $1;
2816
2817                   current_block.AddStatement ((Statement) $1);
2818             } 
2819 //        | labeled_statement 
2820           | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF expression
2821             {
2822                 Location loc = lexer.Location;
2823
2824                 ExpressionStatement expr = new CompoundAssign (Binary.Operator.Addition, 
2825                                          (Expression) $2, (Expression) $5, loc);
2826
2827                 Statement stmt = new StatementExpression (expr, loc); 
2828
2829                 current_block.AddStatement (stmt);
2830
2831             }
2832
2833           | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF expression
2834             {
2835                 Location loc = lexer.Location;
2836
2837                 ExpressionStatement expr = new CompoundAssign (Binary.Operator.Subtraction, 
2838                                          (Expression) $2, (Expression) $5, loc);
2839
2840                 Statement stmt = new StatementExpression (expr, loc); 
2841
2842                 current_block.AddStatement (stmt);
2843
2844             }
2845           | RAISEEVENT identifier opt_raise_event_args  //OPEN_PARENS opt_argument_list CLOSE_PARENS
2846             {
2847               Location loc = lexer.Location;
2848               MemberName mname = new MemberName ((string) $2);
2849               Expression expr = mname.GetTypeExpression (loc);
2850
2851               Invocation inv_expr = new Invocation (expr, (ArrayList) $3, loc);
2852               Statement stmt = new StatementExpression (inv_expr, loc); 
2853               current_block.AddStatement (stmt);        
2854             }
2855 //        /* | array_handling_statement */
2856 //        /* | empty_statement */
2857 //        | with_statement 
2858 //          {
2859 //                Statement s = (Statement) $1;
2860
2861 //            current_block.AddStatement ((Statement) $1);
2862 //          }     
2863           ;     
2864         
2865           
2866 opt_raise_event_args 
2867         : /* empty */   { $$ = null; }
2868         | OPEN_PARENS opt_argument_list CLOSE_PARENS
2869           {
2870                 $$ = $2;
2871           }
2872         ;
2873
2874 // label_name
2875 //      : identifier
2876 //      | LITERAL_INTEGER
2877 //      {
2878 //              $$ = $1.ToString();
2879 //      }
2880 //      ;
2881
2882 // labeled_statement
2883 //      : label_name COLON
2884 //        {
2885 //              LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2886
2887 //              if (!current_block.AddLabel ((string) $1, labeled)){
2888 //                      Location l = lexer.Location;
2889 //                      Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2890 //              }       
2891 //              current_block.AddStatement (labeled);
2892 //        }
2893 //      | label_name COLON
2894 //        {
2895 //              LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2896
2897 //              if (!current_block.AddLabel ((string) $1, labeled)){
2898 //                      Location l = lexer.Location;
2899 //                      Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2900 //              }       
2901 //              current_block.AddStatement (labeled);
2902 //        }
2903 //        statement
2904 //      ;
2905
2906 embedded_statement
2907         : expression_statement
2908         | selection_statement
2909 //      | iteration_statement
2910         | try_statement
2911         | synclock_statement
2912         | jump_statement
2913 //      | array_handling_statement 
2914         ;
2915
2916 // /*        
2917 // empty_statement
2918 //      : end_of_stmt
2919 //        {
2920 //                $$ = new EmptyStatement ();
2921 //        }
2922 //      ;        
2923 // */
2924
2925 // with_statement
2926 //      : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2927 //        {
2928 //              // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2929 //              Expression e = (Expression) $2;
2930 //              with_stack.Push(e);
2931 //              start_block();
2932 //        }
2933 //        opt_statement_list
2934 //        END WITH
2935 //        {
2936 //              Block b = end_block();
2937 //              with_stack.Pop();
2938 //              $$ = b;
2939 //        }
2940 //      ;
2941         
2942         
2943 // array_handling_statement
2944 //      : redim_statement
2945 //      | erase_statement
2946 //      ;
2947         
2948 // redim_statement
2949 //      : REDIM opt_preserve redim_clauses
2950 //        {
2951 //              ArrayList list = (ArrayList) $3;
2952 //              ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2953 //              $$ = r;
2954
2955 //        }
2956 //      ;
2957         
2958 // opt_preserve
2959 //      : /* empty */   { $$ = false; }
2960 //      | PRESERVE      { $$ = true;  }
2961 //      ;
2962         
2963 // redim_clauses
2964 //      : redim_clause
2965 //        {
2966 //              ArrayList clauses = new ArrayList ();
2967
2968 //              clauses.Add ($1);
2969 //              $$ = clauses;
2970 //        }
2971 //      | redim_clauses COMMA redim_clause
2972 //        {
2973 //              ArrayList clauses = (ArrayList) ($1);
2974 //              clauses.Add ($2);
2975
2976 //              $$ = clauses;
2977 //        }
2978 //      ;
2979
2980 // redim_clause
2981 //      : invocation_expression
2982 //        {
2983 //              Invocation i = (Invocation) $1;
2984 //              RedimClause rc = new RedimClause (i.expr, i.Arguments);
2985 //              $$ = rc;
2986 //        }
2987 //      ;
2988
2989 // erase_statement
2990 //      : ERASE erase_clauses
2991 //      {
2992 //              ArrayList list = (ArrayList) $2;
2993 //              foreach(Expression e in list)
2994 //              {
2995 //                      Erase r = new Erase (e, lexer.Location);
2996 //                      $$ = r;
2997 //              }
2998 //      }
2999 //      ;
3000
3001 // erase_clauses
3002 //      : erase_clause
3003 //        {
3004 //              ArrayList clauses = new ArrayList ();
3005
3006 //              clauses.Add ($1);
3007 //              $$ = clauses;
3008 //        }
3009 //      | erase_clauses COMMA erase_clause
3010 //        {
3011 //              ArrayList clauses = (ArrayList) ($1);
3012 //              clauses.Add ($2);
3013
3014 //              $$ = clauses;
3015 //        }
3016 //      ;
3017
3018 // erase_clause
3019 //      : primary_expression
3020 //      ;       
3021                         
3022 jump_statement
3023         : /*break_statement
3024         | continue_statement
3025         | */return_statement
3026         | goto_statement        
3027         | throw_statement       
3028 //      | exit_statement
3029 //      | yield_statement
3030         ;
3031                 
3032 goto_statement
3033         : GOTO label_name  
3034           {
3035                 $$ = new Goto (current_block, (string) $2, lexer.Location);
3036           }
3037         ;
3038         
3039 throw_statement
3040         : THROW opt_expression
3041           {
3042                 $$ = new Throw ((Expression) $2, lexer.Location);
3043           }
3044         ;       
3045                         
3046 // exit_statement
3047 //      : EXIT exit_type
3048 //        {
3049 //              $$ = new Exit ((ExitType)$2, lexer.Location);           
3050 //        }
3051 //      ;
3052         
3053 // exit_type
3054 //      : DO            { $$ = ExitType.DO;             }
3055 //      | FOR           { $$ = ExitType.FOR;            }
3056 //      | WHILE         { $$ = ExitType.WHILE;          }
3057 //      | SELECT        { $$ = ExitType.SELECT;         }
3058 //      | SUB           { $$ = ExitType.SUB;            }
3059 //      | FUNCTION      { $$ = ExitType.FUNCTION;       }
3060 //      | PROPERTY      { $$ = ExitType.PROPERTY;       }
3061 //      | TRY           { $$ = ExitType.TRY;            }
3062 //      ;
3063
3064 return_statement
3065         : RETURN opt_expression 
3066           {       
3067                 $$ = new Return ((Expression) $2, lexer.Location);
3068           }
3069         ;
3070                 
3071 // iteration_statement
3072 //      : while_statement
3073 //      | do_statement
3074 //      | for_statement
3075 //      | foreach_statement
3076 //      ;
3077
3078 // foreach_statement
3079 //      : FOR EACH identifier opt_type_spec IN 
3080 //        {
3081 //              oob_stack.Push (lexer.Location);
3082 //        }       
3083 //        expression end_of_stmt
3084 //        {
3085 //              Location l = lexer.Location;            
3086 //              LocalVariableReference v = null;
3087 //              VariableInfo vi;
3088
3089 //              if ($4 != null) 
3090 //              {
3091 //                      start_block();
3092 //                      VariableDeclaration decl = new VariableDeclaration ((string) $3, 
3093 //                                      (Expression) $4, null, lexer.Location, null);
3094                         
3095 //                      vi = current_block.AddVariable (
3096 //                              (Expression) $4, decl.identifier, current_local_parameters, decl.Location);
3097
3098 //                      Expression expr;
3099 //                      if (decl.expression_or_array_initializer is Expression)
3100 //                              expr = (Expression) decl.expression_or_array_initializer;
3101 //                      else if (decl.expression_or_array_initializer == null) 
3102 //                              expr = null;
3103 //                      else 
3104 //                      {
3105 //                              ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3106 //                              expr = new ArrayCreation ((Expression) $4, "", init, decl.Location);
3107 //                      }
3108                 
3109 //                      v = new LocalVariableReference (current_block, decl.identifier, l);
3110
3111 //                      if (expr != null) 
3112 //                      {
3113 //                              Assign a = new Assign (v, expr, decl.Location);
3114 //                              current_block.AddStatement (new StatementExpression (a, lexer.Location));
3115 //                      }
3116 //              }
3117 //              else
3118 //              {
3119 //                      vi = current_block.GetVariableInfo ((string) $3);
3120
3121 //                      if (vi != null) {
3122 //                              // Get a reference to this variable.
3123 //                              v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
3124 //                      }
3125 //                      else
3126 //                              Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
3127 //              }
3128                 
3129 //              oob_stack.Push (v);
3130 //              start_block();  
3131 //        }       
3132 //        opt_statement_list
3133 //        NEXT opt_identifier
3134 //        {
3135 //              LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
3136 //              Block foreach_block = end_block();
3137 //              Location l = (Location) oob_stack.Pop ();
3138
3139 //              Foreach f = null;
3140 //              if (v != null)
3141 //                      f = new Foreach (null, v, (Expression) $7, foreach_block, l);
3142                 
3143 //              if ($4 != null)
3144 //              {
3145 //                      current_block.AddStatement (f);
3146 //                      $$ = end_block ();
3147 //              }
3148 //              else
3149 //                      $$ = f;
3150 //        }       
3151 //      ;
3152
3153 // yield_statement 
3154 //      : YIELD expression
3155 //        {
3156 //              if (!UseExtendedSyntax)
3157 //              {
3158 //                      ReportError9998();
3159 //                      $$ = null;
3160 //              }
3161 // /*           else
3162 //                      if (iterator_container == null){
3163 //                              Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
3164 //                              $$ = null;
3165 //                      } else {
3166 //                              iterator_container.SetYields ();
3167 //                              $$ = new Yield ((Expression) $2, lexer.Location);
3168 //                      } */
3169 //        }
3170 //      | YIELD STOP
3171 //        {
3172 //              if (!UseExtendedSyntax)
3173 //              {
3174 //                      ReportError9998();
3175 //                      $$ = null;
3176 //              }
3177 // /*           else
3178 //                      if (iterator_container == null){
3179 //                              Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
3180 //                              $$ = null;
3181 //                      } else {
3182 //                              iterator_container.SetYields ();
3183 //                              $$ = new YieldBreak (lexer.Location);
3184 //                      } */
3185 //        }
3186 //      ;
3187
3188 synclock_statement
3189         : SYNCLOCK expression end_of_stmt
3190           block
3191           END SYNCLOCK
3192           {
3193                 $$ = new Lock ((Expression) $2, (Statement) $4, lexer.Location);
3194           }
3195         ;
3196
3197 try_statement
3198         : try_catch
3199         | try_catch_finally
3200         ;
3201                                 
3202                                         
3203 try_catch
3204         : TRY end_of_stmt block opt_catch_clauses END TRY
3205           {
3206                 Catch g = null;
3207                 
3208                 ArrayList c = (ArrayList)$4;
3209                 for (int i = 0; i < c.Count; ++i) {
3210                         Catch cc = (Catch) c [i];
3211                         if (cc.IsGeneral) {
3212                                 if (i != c.Count - 1)
3213                                         Report.Error (1017, cc.loc, "Empty catch block must be the last in a series of catch blocks");
3214                                 g = cc;
3215                                 c.RemoveAt (i);
3216                                 i--;
3217                         }
3218                 }
3219
3220                 // Now s contains the list of specific catch clauses
3221                 // and g contains the general one.
3222                 
3223                 $$ = new Try ((Block) $3, c, g, null, ((Block) $3).loc);
3224           }
3225         ;       
3226           
3227 try_catch_finally
3228         : TRY end_of_stmt 
3229           block 
3230           opt_catch_clauses 
3231           FINALLY end_of_stmt
3232           block
3233           END TRY
3234           {
3235                 Catch g = null;
3236                 ArrayList s = new ArrayList (4);
3237                 ArrayList catch_list = (ArrayList) $4;
3238
3239                 if (catch_list != null){
3240                         foreach (Catch cc in catch_list) {
3241                                 if (cc.IsGeneral)
3242                                         g = cc;
3243                                 else
3244                                         s.Add (cc);
3245                         }
3246                 }
3247
3248                 $$ = new Try ((Block) $3, s, g, (Block) $7, ((Block) $3).loc);
3249           }
3250           ;             
3251
3252 opt_catch_clauses
3253         : /* empty */  {  $$ = null;  }
3254         | catch_clauses
3255         ;
3256
3257 catch_clauses
3258         : catch_clause 
3259           {
3260                 ArrayList l = new ArrayList (4);
3261
3262                 l.Add ($1);
3263                 $$ = l;
3264           }
3265         | catch_clauses catch_clause
3266           {
3267                 ArrayList l = (ArrayList) $1;
3268
3269                 l.Add ($2);
3270                 $$ = l;
3271           }
3272         ;
3273
3274 opt_identifier
3275         : /* empty */   {  $$ = null;  }
3276         | identifier
3277         ;
3278
3279 // opt_when
3280 //      : /* empty */   {  $$ = null;  }
3281 //      | WHEN boolean_expression { $$ = $2; }
3282 //      ;
3283         
3284
3285 catch_clause 
3286 //      : CATCH opt_catch_args opt_when end_of_stmt
3287         : CATCH opt_catch_args end_of_stmt
3288         {
3289                 // FIXME: opt_when needs to be hnadled
3290                 Expression type = null;
3291                 string id = null;
3292                 
3293                 if ($2 != null) {
3294                         DictionaryEntry cc = (DictionaryEntry) $2;
3295                         type = (Expression) cc.Key;
3296                         id   = (string) cc.Value;
3297
3298                         if (id != null){
3299                                 ArrayList one = new ArrayList (4);
3300                                 Location loc = lexer.Location;
3301
3302                                 one.Add (new VariableDeclaration (id, type, loc));
3303
3304                                 $1 = current_block;
3305                                 current_block = new Block (current_block);
3306                                 Block b = declare_local_variables (type, one, loc);
3307                                 current_block = b;
3308                         }
3309                 }
3310         }
3311         block
3312         {
3313                 Expression type = null;
3314                 string id = null;
3315
3316                 if ($2 != null){
3317                         DictionaryEntry cc = (DictionaryEntry) $2;
3318                         type = (Expression) cc.Key;
3319                         id   = (string) cc.Value;
3320
3321                         if ($1 != null){
3322                                 //
3323                                 // FIXME: I can change this for an assignment.
3324                                 //
3325                                 while (current_block != (Block) $1)
3326                                         current_block = current_block.Parent;
3327                         }
3328                 }
3329
3330
3331                 $$ = new Catch (type, id , (Block) $5, ((Block) $5).loc);
3332         }
3333     ;
3334
3335 opt_catch_args
3336         : /* empty */ {  $$ = null; }
3337         | catch_args
3338         ;         
3339
3340 catch_args 
3341         : identifier AS type
3342         {
3343                  $$ = new DictionaryEntry ($3, $1); 
3344         }
3345         ;
3346
3347
3348 // do_statement
3349 //      : DO opt_do_construct end_of_stmt
3350 //        {
3351 //              start_block();
3352 //              oob_stack.Push (lexer.Location);
3353 //        }     
3354 //        opt_statement_list
3355 //        LOOP opt_do_construct
3356 //        {
3357 //              Expression t_before = (Expression) $2;
3358 //              Expression t_after = (Expression) $7;
3359 //              Expression t;
3360
3361 //              if  ((t_before != null) && (t_after != null))
3362 //                      Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
3363
3364 //              if ((t_before == null) && (t_after == null))
3365 //                      t = new BoolLiteral (true);
3366 //              else
3367 //                      t = (t_before != null) ? t_before : t_after;
3368                         
3369 //              DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
3370                 
3371 //              if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
3372 //                  ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
3373 //                       t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
3374                          
3375 //              $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
3376 //        }
3377 //        ;
3378
3379 // opt_do_construct
3380 //      : /* empty */ { $$ = null; }
3381 //      | while_or_until boolean_expression
3382 //        {
3383 //              do_type = (DoOptions)$1;
3384 //              $$ = (Expression) $2;
3385 //        }
3386 //      ;
3387
3388 // while_or_until
3389 //      : WHILE { $$ = DoOptions.WHILE; }
3390 //      | UNTIL { $$ = DoOptions.UNTIL; }
3391 //      ;
3392
3393 while_statement
3394         : WHILE
3395         {
3396                 oob_stack.Push (lexer.Location);
3397         }
3398         boolean_expression end_of_stmt
3399         begin_block
3400         opt_statement_list
3401         end_block
3402         END WHILE
3403         {
3404                 Location l = (Location) oob_stack.Pop ();
3405                 $$ = new While ((Expression) $3, (Statement) $7, l);
3406         }
3407         ;
3408
3409 // for_statement
3410 //      : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
3411 //        {
3412 //              if ($3 != null)
3413 //              {
3414 //                      start_block();
3415 //                      ArrayList VarDeclaration = new ArrayList ();
3416 //                      VarDeclaration.Add (new VariableDeclaration ((string) $2, 
3417 //                              (Expression) $3, null, lexer.Location, null));
3418
3419 //                      DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
3420 //                      Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3421 //                      current_block = b;
3422 //              }
3423 //              oob_stack.Push (lexer.Location);                
3424 //              start_block();
3425 //        }
3426 //        opt_statement_list
3427 //        NEXT opt_identifier 
3428 //        {
3429 //                      Block inner_statement = end_block();
3430 //                      Location l = (Location) oob_stack.Pop ();
3431 //                      Expression for_var = (Expression) DecomposeQI ((string)$2, l);
3432                         
3433 //             Expression assign_expr = new Assign (for_var, (Expression) $5, l);
3434 //             Expression test_expr =  new Binary (Binary.Operator.LessThanOrEqual,
3435 //                                                             for_var, (Expression) $7, l);
3436 //             Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
3437 //                                              for_var, (Expression) $8, l), l);
3438
3439 //             Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
3440 //             Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
3441
3442 //             For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
3443 //                      if ($3 != null)
3444 //                      {
3445 //                              current_block.AddStatement (f);
3446 //                              $$ = end_block();
3447 //                      }
3448 //                      else
3449 //                              $$ = f;
3450 //        }
3451 //      ;
3452
3453 // opt_step
3454 //      : /* empty */           { $$ = new IntLiteral ((Int32) 1); }
3455 //      | STEP expression       { $$ = $2; }
3456 //      ;
3457
3458 selection_statement
3459         : if_statement
3460 //      | select_statement
3461         ;
3462
3463 // if_statement
3464 //      : IF boolean_expression opt_then end_of_stmt 
3465 //        if_statement_rest
3466 // //   | IF boolean_expression THEN block opt_else_pre_embedded_statement
3467 // //   | IF boolean_expression else_pre_embedded_statement
3468 //      ;
3469
3470
3471 // FXIME: The rule for LineIfThenStatement needs to be still enabled
3472 // FIXME: The lexer.Location that is calculated may have to replaced with the most correct one
3473
3474 if_statement
3475         : IF boolean_expression opt_then end_of_stmt 
3476           block
3477           END IF
3478           { 
3479                 oob_stack.Push (lexer.Location);          
3480                 Location l = (Location) oob_stack.Pop ();
3481
3482                 $$ = new If ((Expression) $2, (Statement) $5, l);
3483
3484                 if (RootContext.WarningLevel >= 3){
3485                         if ($5 == EmptyStatement.Value)
3486                                 Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
3487                 }
3488
3489           }
3490           
3491         | IF boolean_expression opt_then end_of_stmt 
3492           block
3493           ELSE end_of_stmt 
3494           block
3495           END IF
3496           {
3497                 oob_stack.Push (lexer.Location);          
3498                 Location l = (Location) oob_stack.Pop ();
3499
3500                 $$ = new If ((Expression) $2, (Statement) $5, (Statement) $8, l);
3501           }     
3502         
3503         | IF boolean_expression opt_then end_of_stmt 
3504           block
3505           else_if_statement_rest 
3506           {
3507                 oob_stack.Push (lexer.Location);          
3508                 Location l = (Location) oob_stack.Pop ();
3509
3510                 $$ = new If ((Expression) $2, (Statement) $5, (Statement) $6, l);
3511           }     
3512         ;
3513
3514 else_if_statement_rest
3515         : ELSEIF boolean_expression opt_then end_of_stmt 
3516           block
3517           END IF
3518           { 
3519                 oob_stack.Push (lexer.Location);          
3520                 Location l = (Location) oob_stack.Pop ();
3521
3522                 $$ = new If ((Expression) $2, (Statement) $5, l);
3523
3524                 if (RootContext.WarningLevel >= 3){
3525                         if ($5 == EmptyStatement.Value)
3526                                 Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
3527                 }
3528
3529           }
3530
3531         | ELSEIF boolean_expression opt_then end_of_stmt 
3532           block
3533           ELSE end_of_stmt 
3534           block
3535           END IF        
3536           {
3537                 oob_stack.Push (lexer.Location);          
3538                 Location l = (Location) oob_stack.Pop ();
3539
3540                 $$ = new If ((Expression) $2, (Statement) $5, (Statement) $8, l);
3541           }     
3542
3543         | ELSEIF boolean_expression opt_then end_of_stmt 
3544           block
3545           else_if_statement_rest 
3546           {
3547                 oob_stack.Push (lexer.Location);          
3548                 Location l = (Location) oob_stack.Pop ();
3549
3550                 $$ = new If ((Expression) $2, (Statement) $5, (Statement) $6, l);
3551           }     
3552         ;
3553
3554
3555 // opt_else_pre_embedded_statement
3556 //      : /* empty */
3557 //      | else_pre_embedded_statement
3558 //      ;
3559         
3560 // else_pre_embedded_statement  
3561 //      : ELSE
3562 //        {
3563 //              Block bl = end_block(); 
3564 //         tmp_blocks.Push(bl); 
3565         
3566 //              start_block();
3567 //        }
3568 //      | ELSE embedded_statement 
3569 //        {
3570 //              Block bl = end_block(); 
3571 //         tmp_blocks.Push(bl); 
3572         
3573 //              start_block();
3574 //              Statement s = (Statement) $2;
3575 //              current_block.AddStatement ((Statement) $2);
3576 //        } 
3577 //      ;       
3578
3579         
3580 opt_then
3581         : /* empty */
3582         | THEN
3583         ;
3584         
3585
3586 // select_statement
3587 //      : SELECT opt_case expression end_of_stmt
3588 //        { 
3589 //              oob_stack.Push (lexer.Location);
3590 //              switch_stack.Push (current_block);
3591 //        }     
3592 //        opt_case_sections
3593 //        END SELECT 
3594 //        {
3595 //              $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3596 //              current_block = (Block) switch_stack.Pop ();
3597 //        }       
3598 //      ;
3599
3600 // opt_case_sections
3601 //      : /* empty */   { $$ = null; }
3602 //      | case_sections { $$ = $1; }
3603 //      ;
3604         
3605 // case_sections
3606 //      : case_sections case_section
3607 //        {
3608 //              ArrayList sections = (ArrayList) $1;
3609
3610 //              sections.Add ($2);
3611 //              $$ = sections;
3612 //        }
3613 //      | case_section
3614 //        {
3615 //              ArrayList sections = new ArrayList (4);
3616
3617 //              sections.Add ($1);
3618 //              $$ = sections;
3619 //        }
3620 //      ;
3621
3622 // ends 
3623 //      : end_of_stmt
3624 //      | ends end_of_stmt
3625 //      ;
3626         
3627
3628 // case_section
3629 //      : CASE case_clauses ends
3630 //        { 
3631 //              start_block();
3632 //        }
3633 //        opt_statement_list
3634 //        {
3635 //              //Block topmost = current_block;
3636 //              Block topmost = end_block();
3637                 
3638 //              while (topmost.Implicit)
3639 //                      topmost = topmost.Parent;
3640                         
3641 //              // FIXME: This is a horrible hack which MUST go                 
3642 //              topmost.statements.Add (new Break (lexer.Location));
3643 //              $$ = new SwitchSection ((ArrayList) $2, topmost);
3644 //        }
3645 //      | CASE ELSE ends
3646 //          /* FIXME: we should somehow flag an error 
3647 //             (BC30321 'Case' cannot follow a 'Case Else' 
3648 //             in the same 'Select' statement.) 
3649 //             if Case Else is not the last of the Case clauses
3650 //          */
3651 //        { 
3652 //              start_block();
3653 //        }     
3654 //        opt_statement_list
3655 //        { 
3656 //              //Block topmost = current_block;
3657 //              Block topmost = end_block();
3658
3659 //              while (topmost.Implicit)
3660 //                      topmost = topmost.Parent;
3661                         
3662 //              // FIXME: This is a horrible hack which MUST go                 
3663 //              topmost.statements.Add (new Break (lexer.Location));
3664                 
3665 //              ArrayList a = new ArrayList();
3666 //              a.Add (new SwitchLabel (null, lexer.Location));                 
3667 //              $$ = new SwitchSection ((ArrayList) a, topmost);                
3668 //        }
3669 //      ;         
3670         
3671
3672 case_clauses
3673         : case_clause
3674           {
3675                 ArrayList labels = new ArrayList ();
3676
3677                 labels.Add ($1);
3678                 $$ = labels;
3679           }     
3680         | case_clauses COMMA case_clause
3681           {
3682                 ArrayList labels = (ArrayList) ($1);
3683                 labels.Add ($2);
3684
3685                 $$ = labels;
3686           }     
3687         ;
3688         
3689 case_clause
3690         : opt_is comparison_operator expression
3691         | expression
3692           {
3693                 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3694           }
3695         ;
3696         
3697 opt_is 
3698         : /* empty */
3699         | IS
3700         ;
3701
3702 comparison_operator
3703         : OP_LT
3704         | OP_GT
3705         | OP_LE
3706         | OP_NE
3707         /*| OP_EQ */
3708         ;
3709
3710 opt_case
3711         : /* empty */
3712         | CASE
3713         ;
3714
3715 expression_statement
3716         : statement_expression 
3717           {
3718                  $$ = $1; 
3719           }
3720         ;
3721
3722
3723 statement_expression
3724         : invocation_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
3725         | object_creation_expression    { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
3726         | assignment_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
3727         ;
3728
3729 object_creation_expression
3730         : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3731           {
3732                 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3733           }
3734         | NEW type
3735           {
3736                 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3737           }
3738         ;
3739         
3740
3741 // array_creation_expression
3742 //      : object_creation_expression opt_rank_specifiers array_initializer
3743 //        {
3744 //              New n = (New) $1;
3745 //              ArrayList dims = new ArrayList();
3746                 
3747 //              if (n.Arguments != null) {
3748 //                      foreach (Argument a in n.Arguments) {
3749 //                              dims.Add (a.Expr);
3750 //                      }
3751 //              }
3752                         
3753 //              Expression atype = n.RequestedType;
3754
3755 //              if ($2 != null)
3756 //                      atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
3757
3758 //              ArrayList init = (ArrayList) $3;
3759 //              if (init.Count == 0)
3760 //                      init = null;
3761         
3762 //              if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3763 //                      VariableDeclaration.VBFixIndexList (ref dims);
3764 //                      $$ = new ArrayCreation (atype, dims, "", init, lexer.Location); 
3765 //              }
3766 //              else
3767 //              {
3768 //                      string rank = VariableDeclaration.BuildRank (dims);
3769 //                      $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location); 
3770 //              }
3771 //              //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3772 //        }
3773 //      ;       
3774
3775 new_expression
3776         : object_creation_expression
3777 //      | array_creation_expression
3778         ;
3779
3780 declaration_statement
3781         : local_variable_declaration 
3782           {
3783                 if ($1 != null){
3784                         DictionaryEntry de = (DictionaryEntry) $1;
3785
3786                         $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3787                 }
3788           }
3789         | local_constant_declaration 
3790           {
3791                 if ($1 != null){
3792                         DictionaryEntry de = (DictionaryEntry) $1;
3793
3794                         $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3795                 }
3796           }
3797         ;        
3798
3799 local_variable_declaration
3800         : DIM variable_declarators
3801           {
3802                 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);             
3803           }
3804         ;
3805
3806         
3807 local_constant_declaration
3808         : CONST constant_declarators
3809           {
3810                 if ($2 != null)
3811                         $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3812                 else
3813                         $$ = null;
3814           }
3815         ;        
3816
3817 constant_declarators
3818         : constant_declarator 
3819           {
3820                 ArrayList decl = new ArrayList ();
3821                 if ($1 != null) 
3822                         decl.Add ($1);
3823                         
3824                 $$ = decl;
3825           }
3826         | constant_declarators COMMA constant_declarator
3827           {
3828                 ArrayList decls = (ArrayList) $1;
3829                 if ($3 != null)
3830                         decls.Add ($3);
3831
3832                 $$ = $1;
3833           }
3834         ;
3835
3836 constant_declarator
3837         : variable_name opt_type_decl opt_variable_initializer
3838           {
3839                 VarName vname = (VarName) $1;
3840                 string varname = (string) vname.Name;
3841                 current_rank_specifiers = (ArrayList) vname.Rank;
3842                 object varinit = $3;
3843                 ArrayList a_dims = null;
3844
3845                 if (varinit == null)
3846                         Report.Error (
3847                                 30438, lexer.Location, "Constant should have a value"
3848                                 );
3849
3850                 if (vname.Type != null && $2 != null)
3851                         Report.Error (
3852                                 30302, lexer.Location, 
3853                                 "Type character cannot be used with explicit type declaration" );
3854
3855                 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3856
3857                 if (current_rank_specifiers != null) 
3858                 {
3859                         Report.Error (30424, lexer.Location, "Constant doesn't support array");
3860                         $$ = null;
3861                 }
3862                 else
3863                         $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3864           }
3865         ;               
3866
3867 variable_declarators
3868         : variable_declarator 
3869           {
3870                 ArrayList decl = new ArrayList ();
3871                 decl.AddRange ((ArrayList) $1);
3872                 $$ = decl;
3873           }
3874         | variable_declarators COMMA variable_declarator
3875           {
3876                 ArrayList decls = (ArrayList) $1;
3877                 decls.AddRange ((ArrayList) $3);
3878                 $$ = $1;
3879           }
3880         ;
3881
3882 variable_declarator
3883         : variable_names opt_type_decl opt_variable_initializer
3884           {
3885             ArrayList names = (ArrayList) $1;
3886                 object varinit = $3;
3887                 ArrayList VarDeclarations = new ArrayList();
3888                 Expression vartype;
3889                 ArrayList a_dims = null;
3890
3891                 if ((names.Count > 1) && (varinit != null)) 
3892                         Report.Error (
3893                                 30671, lexer.Location, 
3894                                 "Multiple variables with single type can not have " +
3895                                 "a explicit initialization" );
3896
3897                                 
3898                 foreach (VarName vname in names)
3899                 {
3900                         string varname = (string) vname.Name;
3901                         current_rank_specifiers = (ArrayList) vname.Rank;
3902                         a_dims = null;
3903                         varinit = $3;
3904
3905                         if(vname.Type != null && $2 != null)
3906                                 Report.Error (
3907                                         30302, lexer.Location, 
3908                                         "Type character cannot be used with explicit type declaration" );
3909
3910                         // Some checking is required for particularly weird declarations
3911                         // like Dim a As Integer(,)
3912                         if ($2 is Pair) {
3913                                 vartype = (Expression) ((Pair) $2).First;
3914                                 
3915                                 /*if ($3 != null && $3 is ArrayList)
3916                                         Report.Error (205, "End of statement expected.");*/
3917                                         
3918                                 ArrayList args = (ArrayList) ((Pair) $2).Second;
3919                                 if (current_rank_specifiers != null)
3920                                         Report.Error (31087, lexer.Location,
3921                                                  "Array types specified in too many places");   
3922                                 
3923                                 if (VariableDeclaration.IndexesSpecifiedInRank (args))            
3924                                         Report.Error (30638, "Array bounds cannot appear in type specifiers."); 
3925                                 
3926                                 current_rank_specifiers = new ArrayList ();
3927                                 current_rank_specifiers.Add (args);                             
3928                         }
3929                         else
3930                                 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3931
3932                         // if the variable is an array with explicit bound
3933                         // and having explicit initialization throw exception
3934                         if (current_rank_specifiers != null && varinit != null) 
3935                         {
3936                                 bool broken = false;
3937                                 foreach (ArrayList exprs in current_rank_specifiers)
3938                                 {
3939                                         foreach (Expression expr in exprs)
3940                                         {
3941                                                 if (!((Expression)expr is EmptyExpression ))
3942                                                 {
3943                                                         Report.Error (
3944                                                                 30672, lexer.Location, 
3945                                                                 "Array declared with explicit bound " +
3946                                                                 " can not have explicit initialization");
3947                                                         broken = true;
3948                                                         break;
3949                                                 }
3950                                         }
3951                                         if (broken)
3952                                                 break;
3953                                 }
3954                         }
3955                         
3956                         /*
3957                         Check for a declaration like Dim a(2) or Dim a(2,3)
3958                         If this is the case, we must generate an ArrayCreationExpression
3959                         and, in case, add the initializer after the array has been created.
3960                         */
3961 //                      if (VariableDeclaration.IsArrayDecl (this)) {   
3962 //                              if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {   
3963 //                                      a_dims = (ArrayList) current_rank_specifiers;
3964 //                                      VariableDeclaration.VBFixIndexLists (ref a_dims);
3965 //                                      varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3966 //                              }
3967 //                              vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
3968 //                      }
3969
3970                         if (vartype is New) {
3971                                 if (varinit != null) {
3972                                         Report.Error (30205, lexer.Location, "End of statement expected");
3973                                         $$ = null;
3974                                 }
3975                                 else
3976                                 {
3977                                         varinit = vartype;
3978                                         vartype = ((New)vartype).RequestedType;
3979                                 }
3980                         }
3981                         VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3982             }// end of for
3983             $$ = VarDeclarations;
3984           } 
3985         ;
3986
3987 variable_names
3988         : variable_name
3989           {
3990                 ArrayList list = new ArrayList ();
3991                 list.Add ($1);
3992                 $$ = list;
3993           }
3994         | variable_names COMMA variable_name
3995           {
3996                 ArrayList list = (ArrayList) $1;
3997                 list.Add ($3);
3998                 $$ = list;
3999           }
4000         ;
4001         
4002 variable_name
4003         : identifier opt_type_character opt_array_name_modifier 
4004           {
4005                 $$ = new VarName ($1, $2, $3);
4006           }
4007         ;
4008
4009 opt_type_spec
4010         : /* empty */   
4011           { 
4012                 $$ = null;              
4013           }
4014         | AS type       
4015           { 
4016                 $$ = (Expression) $2;
4017           }
4018         ;
4019                 
4020 opt_type_with_ranks
4021         : opt_type_spec 
4022 //      | AS type rank_specifiers 
4023 //        {
4024 // //           $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
4025 //        }
4026         ;
4027         
4028 opt_type_decl
4029         : opt_type_with_ranks
4030           {
4031                 $$ = $1;
4032           }
4033         | AS NEW type
4034           {
4035                 New n = new New ((Expression)$3, null, lexer.Location);
4036                 $$ = (Expression) n;
4037           }
4038         | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS 
4039           {
4040                 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
4041                 $$ = (Expression) n;
4042           }
4043         /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS 
4044           {
4045             ArrayList args = new ArrayList();
4046                 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
4047                 args.Add (arg);
4048                 
4049                 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
4050                 $$ = (Expression) n;
4051           }*/
4052         ;
4053                 
4054 opt_array_name_modifier
4055         : /* empty */                           { $$ = null; }
4056 //      | array_type_modifier                   { $$ = $1;   }
4057         ;
4058         
4059 // array_type_modifier
4060 //      : rank_specifiers               { $$ = $1; }
4061 //      ;
4062         
4063 opt_variable_initializer
4064         : /* empty */                   { $$ = null; }
4065         | ASSIGN variable_initializer   { $$ = $2; }
4066         ;
4067                 
4068 variable_initializer
4069         : expression
4070           {
4071                 $$ = $1;
4072           }
4073         | array_initializer
4074           {
4075                 $$ = $1;
4076           }
4077         
4078         ;       
4079         
4080 array_initializer
4081         : OPEN_BRACE CLOSE_BRACE
4082           {
4083                 ArrayList list = new ArrayList ();
4084                 $$ = list;
4085           }
4086         | OPEN_BRACE variable_initializer_list CLOSE_BRACE
4087           {
4088                 $$ = (ArrayList) $2;
4089           }
4090         ;
4091
4092 variable_initializer_list
4093         : variable_initializer
4094           {
4095                 ArrayList list = new ArrayList ();
4096                 list.Add ($1);
4097                 $$ = list;
4098           }
4099         | variable_initializer_list COMMA variable_initializer
4100           {
4101                 ArrayList list = (ArrayList) $1;
4102                 list.Add ($3);
4103                 $$ = list;
4104           }
4105         ;
4106
4107 opt_rank_specifiers
4108         : /* empty */
4109           {
4110                   // $$ = "";
4111                   $$ = null;
4112           }
4113         | rank_specifiers
4114           {
4115                         $$ = $1;
4116           }
4117         ;      
4118         
4119 rank_specifiers
4120         : rank_specifier
4121           {
4122                   ArrayList rs = new ArrayList();
4123                   rs.Add ($1);
4124                   $$ = rs;
4125           }
4126         | rank_specifiers rank_specifier
4127           {
4128                   ArrayList rs = (ArrayList) $1;
4129                   rs.Add ($2);
4130                   $$ = rs;
4131           }             
4132         ;               
4133         
4134 rank_specifier
4135         : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
4136           {
4137                 $$ = $2;
4138           }
4139         ;
4140                 
4141 opt_dim_specifiers
4142         : /* empty */
4143           {
4144                 ArrayList ds = new ArrayList();
4145                 ds.Add (new EmptyExpression());
4146                 $$ = ds;
4147           }     
4148         | expression
4149           {
4150                 ArrayList ds = new ArrayList();
4151                 ds.Add ((Expression) $1);
4152                 $$ = ds;
4153           }     
4154         | opt_dim_specifiers COMMA expression
4155           {
4156                 ArrayList ds = (ArrayList) $1;
4157                 ds.Add ((Expression) $3);
4158                 $$ = ds;                
4159           }     
4160         | opt_dim_specifiers COMMA 
4161           {
4162                 ArrayList ds = (ArrayList) $1;
4163                 ds.Add (new EmptyExpression());
4164                 $$ = ds;                
4165           }     
4166         ;
4167         
4168 // primary_expression
4169 //      : literal
4170 //        {
4171 //              //TODO
4172 //        }
4173 //      | parenthesized_expression
4174 //      | this_access
4175 //      | base_access
4176 //      | qualified_identifier
4177 //        {
4178 //              string name = (string) $1;
4179 //              $$ = DecomposeQI (name, lexer.Location);
4180 //        }
4181 //      | get_type_expression
4182 //      | member_access
4183 //      | invocation_expression
4184 //      //| element_access
4185 //      | new_expression
4186 //      | cast_expression
4187 //      ;
4188
4189 primary_expression
4190         : literal
4191           {
4192                 //TODO
4193           }
4194         | parenthesized_expression
4195         | this_access
4196         | base_access
4197         | qualified_identifier
4198           {
4199                 $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
4200           }
4201         | get_type_expression
4202         | member_access
4203         | invocation_expression
4204         //| element_access
4205         | new_expression
4206         | cast_expression
4207         ;
4208
4209
4210
4211 literal
4212         : boolean_literal
4213         | integer_literal
4214         | real_literal
4215         | LITERAL_DATE          { $$ = new DateLiteral ((DateTime)lexer.Value); }
4216         | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value); }
4217         | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value); }
4218         | NOTHING               { $$ = NullLiteral.Null; }
4219         ;
4220
4221 real_literal
4222         : LITERAL_SINGLE        { $$ = new FloatLiteral ((float) lexer.Value); }
4223         | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value); }
4224         | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value); }
4225         ;
4226
4227 integer_literal
4228         : LITERAL_INTEGER       {
4229                 object v = lexer.Value;
4230
4231                 if (v is int)
4232                         $$ = new IntLiteral ((Int32)v); 
4233 //              else if (v is short)
4234 //                      $$ = new ShortLiteral ((Int16)v);
4235                 else if (v is long)
4236                         $$ = new LongLiteral ((Int64)v);
4237                 else
4238                         Console.WriteLine ("OOPS.  Unexpected result from scanner");
4239                         
4240           }
4241         ;
4242
4243 boolean_literal
4244         : TRUE                  { $$ = new BoolLiteral (true); }
4245         | FALSE                 { $$ = new BoolLiteral (false); }
4246         ;
4247
4248 parenthesized_expression
4249         : OPEN_PARENS expression CLOSE_PARENS
4250           { $$ = $2; }
4251         ;
4252
4253 member_access
4254         : primary_expression DOT identifier
4255           {
4256                 if ($1 != null) {
4257                         string id_name = (string)$3;
4258                         if (id_name.ToUpper() == "NEW")
4259                                 id_name = ".ctor";
4260                         $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
4261                 }
4262                 else
4263                 {
4264 //                      if (with_stack.Count > 0) {
4265 //                              Expression e = (Expression) with_stack.Peek();
4266 //                              $$ = new MemberAccess (e, (string) $3, lexer.Location);
4267 //                      }
4268 //                      else
4269 //                      {
4270 //                              // OOps
4271 //                      }
4272                 }
4273           }
4274 /*      | primary_expression DOT NEW
4275           {
4276                 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
4277           }       */
4278         | predefined_type DOT identifier
4279           {
4280                 if ($1 != null)
4281                         $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
4282                 else
4283                 {
4284 //                      if (with_stack.Count > 0) {
4285 //                              Expression e = (Expression) with_stack.Peek();
4286 //                              $$ = new MemberAccess (e, (string) $3, lexer.Location);
4287 //                      }
4288 //                      else
4289 //                      {
4290 //                              // OOps
4291 //                      }
4292                 }
4293           }
4294         ;
4295         
4296 predefined_type
4297         : builtin_types
4298         ;
4299
4300 invocation_expression
4301         : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
4302           {
4303                 if ($1 == null) {
4304                         Location l = lexer.Location;
4305                         Report.Error (1, l, "Parse error");
4306                 }
4307                 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
4308           }
4309         | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
4310           {
4311                 if ($2 == null) {
4312                         Location l = lexer.Location;
4313                         Report.Error (1, l, "THIS IS CRAZY");
4314                 }
4315                 $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
4316 //              Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
4317           }
4318         ;
4319         
4320 base_access
4321         : MYBASE DOT IDENTIFIER
4322           {
4323                 string id_name = (string) $3;
4324                 if (id_name.ToUpper() == "NEW")
4325                         id_name = "New";
4326                 $$ = new BaseAccess (id_name, lexer.Location);
4327           }
4328 /*      | MYBASE DOT NEW
4329           {
4330                 $$ = new BaseAccess ("New", lexer.Location);
4331           }*/
4332         ;       
4333
4334 opt_argument_list
4335         : argument_list
4336           { 
4337                 /*
4338                    The 'argument' rule returns an 'empty' argument
4339                    of type NoArg (used for default arguments in invocations)
4340                    if no arguments are actually passed.
4341
4342                    If there is only one argument and it is o type NoArg,
4343                    we return a null (empty) list
4344                 */
4345                 ArrayList args = (ArrayList) $1;
4346                 if (args.Count == 1 &&
4347                     ((Argument)args[0]).ArgType == Argument.AType.NoArg)
4348                         $$ = null;
4349                 else
4350                         $$ = $1;
4351           }
4352         ;
4353
4354 argument_list
4355         : argument
4356           {
4357                 ArrayList list = new ArrayList ();
4358                 list.Add ($1);
4359                 $$ = list;
4360           }
4361         | argument_list COMMA argument
4362           {
4363                 ArrayList list = (ArrayList) $1;
4364                 list.Add ($3);
4365                 $$ = list;
4366           }
4367         ;
4368
4369 argument
4370         : expression
4371           {
4372                 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
4373           }
4374         | BYREF variable_reference
4375           {
4376                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
4377           }
4378         | /* empty */
4379           {
4380                 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
4381           }
4382         | ADDRESSOF expression
4383           {
4384                 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
4385           }
4386         ;
4387
4388 variable_reference
4389         : expression {/* note ("section 5.4"); */  $$ = $1;  }
4390         ;
4391
4392                 
4393 expression
4394         : conditional_xor_expression { $$ = $1; }
4395         /*| assignment_expression*/
4396         ;
4397
4398 opt_expression
4399         : /* empty */
4400         | expression
4401         ;
4402                 
4403 this_access
4404         : ME
4405           {
4406                 $$ = new This (current_block, lexer.Location);
4407           }
4408         | MYCLASS
4409           {
4410                 // FIXME: This is actually somewhat different from Me
4411                 // because it is for accessing static (classifier) methods/properties/fields
4412                 $$ = new This (current_block, lexer.Location);
4413           }
4414         ;
4415
4416 cast_expression
4417         : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
4418           {
4419                 // TODO
4420           } 
4421         | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
4422           {
4423                   $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
4424           }     
4425         | cast_operator OPEN_PARENS expression CLOSE_PARENS
4426           {
4427                   $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
4428           }     
4429         ;
4430         
4431 cast_operator
4432         : CBOOL         { $$ = TypeManager.system_boolean_expr;         }
4433         | CBYTE         { $$ = TypeManager.system_byte_expr;            }
4434         | CCHAR         { $$ = TypeManager.system_char_expr;            }
4435         | CDATE         { $$ = TypeManager.system_date_expr;            }
4436         | CDBL          { $$ = TypeManager.system_double_expr;          }
4437         | CDEC          { $$ = TypeManager.system_decimal_expr;         }
4438         | CINT          { $$ = TypeManager.system_int32_expr;           }
4439         | CLNG          { $$ = TypeManager.system_int64_expr;           }
4440         | COBJ          { $$ = TypeManager.system_object_expr;          }
4441         | CSHORT        { $$ = TypeManager.system_int16_expr;           }
4442         | CSNG          { $$ = TypeManager.system_single_expr;          }
4443         | CSTR          { $$ = TypeManager.system_string_expr;  }
4444         ;
4445
4446 get_type_expression
4447         : GETTYPE OPEN_PARENS type CLOSE_PARENS
4448           {
4449                 $$ = new TypeOf ((Expression) $3, lexer.Location);
4450           }
4451         ;
4452         
4453 exponentiation_expression
4454         : primary_expression
4455         | exponentiation_expression OP_EXP primary_expression
4456           {
4457                 //TODO
4458           }                             
4459         ;
4460         
4461 prefixed_unary_expression
4462         : exponentiation_expression
4463         | PLUS prefixed_unary_expression
4464           {
4465                 //FIXME: Is this rule correctly defined ?
4466                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
4467           }
4468         | MINUS prefixed_unary_expression
4469           {
4470                 //FIXME: Is this rule correctly defined ?
4471                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
4472           }
4473         ;
4474
4475 multiplicative_expression
4476         : prefixed_unary_expression
4477         | multiplicative_expression STAR prefixed_unary_expression
4478           {
4479                 $$ = new Binary (Binary.Operator.Multiply,
4480                                  (Expression) $1, (Expression) $3, lexer.Location);
4481           }
4482         | multiplicative_expression DIV prefixed_unary_expression
4483           {
4484                 $$ = new Binary (Binary.Operator.Division,
4485                                  (Expression) $1, (Expression) $3, lexer.Location);
4486           }
4487         ;
4488
4489 integer_division_expression
4490         : multiplicative_expression
4491         | integer_division_expression OP_IDIV multiplicative_expression
4492           {
4493               $$ = new Binary (Binary.Operator.IntegerDivision,
4494                            (Expression) $1, (Expression) $3, lexer.Location);
4495           }
4496         ;
4497
4498 mod_expression
4499         : integer_division_expression
4500         | mod_expression MOD integer_division_expression
4501           {
4502               $$ = new Binary (Binary.Operator.Modulus,
4503                                (Expression) $1, (Expression) $3, lexer.Location);
4504           }
4505         ;
4506         
4507 additive_expression
4508         : mod_expression
4509         | additive_expression PLUS mod_expression
4510           {
4511               $$ = new Binary (Binary.Operator.Addition,
4512                                (Expression) $1, (Expression) $3, lexer.Location);
4513           }
4514         | additive_expression MINUS mod_expression
4515           {
4516               $$ = new Binary (Binary.Operator.Subtraction,
4517                                (Expression) $1, (Expression) $3, lexer.Location);
4518           }
4519         ;
4520
4521 concat_expression
4522         : additive_expression
4523         | concat_expression OP_CONCAT additive_expression
4524           {
4525               $$ = new Binary (Binary.Operator.Concatenation,
4526                                (Expression) $1, (Expression) $3, lexer.Location);
4527           }     
4528         ;
4529
4530 shift_expression
4531         : concat_expression
4532         | shift_expression OP_SHIFT_LEFT concat_expression
4533           {
4534               $$ = new Binary (Binary.Operator.LeftShift, 
4535                                (Expression) $1, (Expression) $3, lexer.Location);
4536           }
4537         | shift_expression OP_SHIFT_RIGHT concat_expression
4538           {
4539               $$ = new Binary (Binary.Operator.RightShift, 
4540                                (Expression) $1, (Expression) $3, lexer.Location);
4541           }
4542         ;
4543
4544 relational_expression
4545         : shift_expression
4546         | relational_expression ASSIGN shift_expression
4547           {
4548                 $$ = new Binary (Binary.Operator.Equality,
4549                                  (Expression) $1, (Expression) $3, lexer.Location);
4550           }
4551         | relational_expression OP_NE shift_expression
4552           {
4553                 $$ = new Binary (Binary.Operator.Inequality, 
4554                                  (Expression) $1, (Expression) $3, lexer.Location);
4555           }       
4556         | relational_expression OP_LT shift_expression
4557           {
4558                 $$ = new Binary (Binary.Operator.LessThan,
4559                                  (Expression) $1, (Expression) $3, lexer.Location);
4560           }
4561         | relational_expression OP_GT shift_expression
4562           {
4563                 $$ = new Binary (Binary.Operator.GreaterThan,
4564                                  (Expression) $1, (Expression) $3, lexer.Location);
4565           }
4566         | relational_expression OP_LE shift_expression
4567           {
4568                 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4569                                  (Expression) $1, (Expression) $3, lexer.Location);
4570           }
4571         | relational_expression OP_GE shift_expression
4572           {
4573                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4574                                  (Expression) $1, (Expression) $3, lexer.Location);
4575           }
4576         | relational_expression IS shift_expression
4577           {
4578                 $$ = new Binary (Binary.Operator.Is,
4579                                  (Expression) $1, (Expression) $3, lexer.Location);
4580           }
4581         | relational_expression LIKE shift_expression
4582           {
4583                 $$ = new Binary (Binary.Operator.Like,
4584                                  (Expression) $1, (Expression) $3, lexer.Location);
4585           }
4586         | TYPEOF shift_expression IS type
4587           {
4588                 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4589           }
4590         ;
4591
4592 negation_expression
4593         : relational_expression
4594         | NOT negation_expression 
4595           {
4596                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location);
4597           }
4598         ;
4599         
4600 conditional_and_expression
4601         : negation_expression
4602         | conditional_and_expression AND negation_expression
4603           {
4604                 $$ = new Binary (Binary.Operator.BitwiseAnd,
4605                                  (Expression) $1, (Expression) $3, lexer.Location);
4606           }
4607         | conditional_and_expression ANDALSO negation_expression
4608           {     
4609                 $$ = new Binary (Binary.Operator.LogicalAndAlso,
4610                                  (Expression) $1, (Expression) $3, lexer.Location);
4611           }
4612         ;
4613
4614 conditional_or_expression
4615         : conditional_and_expression
4616         | conditional_or_expression OR conditional_and_expression
4617           {
4618                 $$ = new Binary (Binary.Operator.BitwiseOr,
4619                                  (Expression) $1, (Expression) $3, lexer.Location);
4620           }
4621         | conditional_or_expression ORELSE conditional_and_expression
4622           {     
4623                 $$ = new Binary (Binary.Operator.LogicalOrElse,
4624                                  (Expression) $1, (Expression) $3, lexer.Location);
4625           }
4626         ;
4627
4628 conditional_xor_expression
4629         : conditional_or_expression
4630         | conditional_xor_expression XOR conditional_or_expression
4631         {
4632               $$ = new Binary (Binary.Operator.ExclusiveOr,
4633                                (Expression) $1, (Expression) $3, lexer.Location);
4634         }
4635         ;
4636
4637 assignment_expression
4638         : prefixed_unary_expression ASSIGN expression
4639           { 
4640                 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4641           }
4642         | prefixed_unary_expression STAR ASSIGN expression
4643           {
4644                 Location l = lexer.Location;
4645
4646                 $$ = new CompoundAssign (
4647                         Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
4648           }
4649         | prefixed_unary_expression DIV ASSIGN expression
4650           {
4651                 Location l = lexer.Location;
4652
4653                 $$ = new CompoundAssign (
4654                         Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
4655           }
4656         | prefixed_unary_expression PLUS ASSIGN expression
4657           {
4658                 Location l = lexer.Location;
4659
4660                 $$ = new CompoundAssign (
4661                         Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4662           }
4663         | prefixed_unary_expression MINUS ASSIGN expression
4664           {
4665                 Location l = lexer.Location;
4666
4667                 $$ = new CompoundAssign (
4668                         Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
4669           }
4670         | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
4671           {
4672                 Location l = lexer.Location;
4673
4674                 $$ = new CompoundAssign (
4675                         Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
4676           }
4677         | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
4678           {
4679                 Location l = lexer.Location;
4680
4681                 $$ = new CompoundAssign (
4682                         Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
4683           }
4684         | prefixed_unary_expression OP_CONCAT ASSIGN expression
4685           {
4686                 Location l = lexer.Location;
4687
4688                 // FIXME should be strings only
4689                 $$ = new CompoundAssign (
4690                         Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4691           }
4692         | prefixed_unary_expression OP_EXP ASSIGN expression
4693           {
4694                 Location l = lexer.Location;
4695
4696                 /* TODO: $$ = new CompoundAssign (
4697                         Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
4698           }
4699         | prefixed_unary_expression ASSIGN ADDRESSOF expression
4700           { 
4701 //              ArrayList args = new ArrayList();
4702 //              Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4703 //              args.Add (arg);
4704                 
4705 //              New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4706 //              n.isDelegate = true;
4707                 $$ = new Assign ((Expression) $1, (Expression) $4, lexer.Location);
4708           }
4709         ;
4710
4711 constant_expression
4712         : expression
4713         ;
4714
4715 boolean_expression
4716         : expression
4717         ;
4718
4719 type
4720         : namespace_or_type_name 
4721           {     
4722                 $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
4723           }
4724         | builtin_types 
4725         //| array_type 
4726         ;
4727
4728 type_list
4729         : type
4730           {
4731                 ArrayList types = new ArrayList ();
4732
4733                 types.Add ($1);
4734                 $$ = types;
4735           }
4736         | type_list COMMA type
4737           {
4738                 ArrayList types = (ArrayList) $1;
4739
4740                 types.Add ($3);
4741                 $$ = types;
4742           }
4743         ;
4744
4745 namespace_or_type_name
4746         : qualified_identifier
4747         ;
4748
4749 builtin_types
4750         : OBJECT        { $$ = TypeManager.system_object_expr; }
4751         | primitive_type
4752         ;
4753
4754 primitive_type
4755         : numeric_type
4756         | BOOLEAN       { $$ = TypeManager.system_boolean_expr; }
4757         | DATE          { $$ = TypeManager.system_date_expr; }
4758         | CHAR          { $$ = TypeManager.system_char_expr; }
4759         | STRING        { $$ = TypeManager.system_string_expr; }
4760         ;
4761         
4762
4763 numeric_type
4764         : integral_type
4765         | floating_point_type
4766         | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
4767         ;
4768
4769 integral_type
4770         :
4771         | BYTE          { $$ = TypeManager.system_byte_expr; }
4772         | SHORT         { $$ = TypeManager.system_int16_expr; }
4773         | INTEGER       { $$ = TypeManager.system_int32_expr; }
4774         | LONG          { $$ = TypeManager.system_int64_expr; }
4775         ;
4776         
4777 floating_point_type
4778         : SINGLE        { $$ = TypeManager.system_single_expr; }
4779         | DOUBLE        { $$ = TypeManager.system_double_expr; }
4780         ;
4781
4782 pp_directive
4783         : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4784           { 
4785 //              if(tokenizerController.IsAcceptingTokens)
4786 //              {
4787 //                      if(in_external_source) 
4788 //                              Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4789 //                      else {
4790 //                              in_external_source = true;
4791                         
4792 //                              lexer.EffectiveSource = (string) $4;
4793 //                              lexer.EffectiveLine = (int) $6;
4794 //                      }
4795 //              }
4796           }
4797         | HASH IDENTIFIER LITERAL_STRING EOL
4798           {
4799                 if(tokenizerController.IsAcceptingTokens) 
4800                 {
4801                         string id = ($2 as string);
4802                 
4803                         if(!($2 as string).ToLower().Equals("region"))
4804                                 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4805                         else
4806                         {
4807                                 ++in_marked_region;
4808                         }
4809                 }
4810           }
4811         | HASH END IDENTIFIER EOL
4812           {
4813                 if(tokenizerController.IsAcceptingTokens)
4814                 {
4815 //                      if( ($3 as string).ToLower().Equals("externalsource")) {
4816 //                              if(!in_external_source)
4817 //                                      Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4818 //                              else {
4819 //                                      in_external_source = false;
4820 //                                      lexer.EffectiveSource = lexer.Source;
4821 //                                      lexer.EffectiveLine = lexer.Line;
4822 //                              }
4823 //                      }
4824                         /* else */if(($3 as string).ToLower().Equals("region")) {
4825                                 if(in_marked_region > 0)
4826                                         --in_marked_region;
4827                                 else
4828                                         Report.Error (30205, lexer.Location, "'#End Region' must be preceded  by a matching '#Region'");
4829                         }
4830                         else {
4831                                 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4832                         }       
4833                 }
4834           }
4835         | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4836           {
4837                 if(tokenizerController.IsAcceptingTokens)
4838                 {
4839                         //TODO;
4840                 }
4841           }
4842         | HASH IF 
4843           {
4844                 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4845
4846                 try {
4847                         ifElseStateMachine.HandleToken(tok);
4848                 }
4849                 catch(ApplicationException) {
4850                         throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4851                 }
4852           }
4853            boolean_literal opt_then  EOL 
4854           {
4855                 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4856           }
4857         | HASH ELSEIF 
4858           {
4859                       IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4860                       try {
4861                               ifElseStateMachine.HandleToken(tok);
4862                       }
4863                       catch(ApplicationException) {
4864                               throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4865                       }
4866           }
4867            boolean_literal opt_then  EOL 
4868           { 
4869                   HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4870           }
4871         | HASH ELSE  
4872           {
4873                     IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4874                     try {
4875                             ifElseStateMachine.HandleToken(tok);
4876                     }
4877                     catch(ApplicationException) {
4878                             throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4879                     }
4880           }
4881           EOL 
4882           { 
4883                 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4884           }
4885         | HASH END IF  
4886           {
4887                   IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4888                   try {
4889                           ifElseStateMachine.HandleToken(tok);
4890                   }
4891                   catch(ApplicationException) {
4892                           throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4893                   }
4894           }
4895           EOL 
4896           { 
4897                 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4898           }
4899         | HASH error EOL          
4900         {
4901                 if(tokenizerController.IsAcceptingTokens)
4902                         Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4903                 else
4904                         Report.Warning (9999, lexer.Location,   "Unrecognized Pre-Processor statement");
4905         }
4906           
4907         ;               
4908
4909 %%
4910
4911
4912 Tokenizer lexer;
4913
4914 public Tokenizer Lexer {
4915         get {
4916                 return lexer;
4917         }
4918 }                  
4919
4920 public static Expression DecomposeQI (string name, Location loc)
4921 {
4922         Expression o;
4923
4924         if (name.IndexOf ('.') == -1){
4925                 return new SimpleName (name, loc);
4926         } else {
4927                 int pos = name.LastIndexOf (".");
4928                 string left = name.Substring (0, pos);
4929                 string right = name.Substring (pos + 1);
4930
4931                 o = DecomposeQI (left, loc);
4932
4933                 return new MemberAccess (o, right, loc);
4934         }
4935 }
4936
4937 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4938 {
4939         Block implicit_block;
4940         ArrayList inits = null;
4941
4942         //
4943         // We use the `Used' property to check whether statements
4944         // have been added to the current block.  If so, we need
4945         // to create another block to contain the new declaration
4946         // otherwise, as an optimization, we use the same block to
4947         // add the declaration.
4948         //
4949         // FIXME: A further optimization is to check if the statements
4950         // that were added were added as part of the initialization
4951         // below.  In which case, no other statements have been executed
4952         // and we might be able to reduce the number of blocks for
4953         // situations like this:
4954         //
4955         // int j = 1;  int k = j + 1;
4956         //
4957         
4958         VariableDeclaration.FixupTypes (variable_declarators);
4959         // FIXME: Should VariableDeclaration.FixupArrayTypes be called here
4960
4961         if (current_block.Used)
4962                 implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
4963         else
4964                 implicit_block = current_block;
4965
4966
4967         foreach (VariableDeclaration decl in variable_declarators){
4968                 Expression type = decl.type;
4969                 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4970                         if (decl.expression_or_array_initializer != null){
4971                                 if (inits == null)
4972                                         inits = new ArrayList ();
4973                                 inits.Add (decl);
4974                         }
4975                 }
4976         }
4977
4978         if (inits == null)
4979                 return implicit_block;
4980
4981         foreach (VariableDeclaration decl in inits){
4982                 Assign assign;
4983                 Expression expr;
4984                 Expression type = decl.type;
4985                 
4986                 if ((decl.expression_or_array_initializer is Expression) || 
4987                     (decl.expression_or_array_initializer is New)) {
4988                         expr = (Expression) decl.expression_or_array_initializer;
4989                 } else {
4990                         ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4991                         
4992                         expr = new ArrayCreation (type, "", init, decl.Location);
4993                 }
4994
4995                 LocalVariableReference var;
4996                 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4997
4998                 assign = new Assign (var, expr, decl.Location);
4999
5000                 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
5001         }
5002         
5003         return implicit_block;
5004 }
5005
5006 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
5007 {
5008         Block implicit_block;
5009         VariableDeclaration.FixupTypes (variable_declarators);
5010
5011         if (current_block.Used)
5012                 implicit_block = new Block (current_block, Block.Flags.Implicit);
5013         else
5014                 implicit_block = current_block;
5015
5016         foreach (VariableDeclaration decl in variable_declarators){
5017                 Expression type = decl.type;
5018                 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
5019                                           current_local_parameters, decl.Location);
5020         }
5021         
5022         return implicit_block;
5023 }
5024
5025
5026
5027 struct VarName {
5028                 public object Name;
5029                 public object Type;
5030                 public object Rank;
5031                                                                                 
5032                 public VarName (object n, object t, object r)
5033                 {
5034                         Name = n;
5035                         Type = t;
5036                         Rank = r;
5037                 }
5038         }
5039
5040
5041 // <summary>
5042 //   A class used to pass around variable declarations and constants
5043 // </summary>
5044 public class VariableDeclaration {
5045         public string identifier;
5046         public object expression_or_array_initializer;
5047         public Location Location;
5048         public Attributes OptAttributes;
5049         public string DocComment;
5050         public Expression type;
5051         public ArrayList dims;
5052                 
5053         public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
5054         {
5055                 this.identifier = id;
5056                 this.expression_or_array_initializer = eoai;
5057                 this.Location = l;
5058                 this.OptAttributes = opt_attrs;
5059                 this.type = t;
5060                 this.dims = null;
5061         }       
5062
5063         public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
5064         {
5065         }
5066         
5067         public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
5068         {
5069         }       
5070         
5071         public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this 
5072                                         (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
5073         {
5074         }       
5075         
5076         public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
5077         {       
5078                 // FIXME : This is broken: only the first rank is parsed
5079                 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
5080         }
5081         
5082         public static void FixupTypes (ArrayList vars)
5083         {
5084                 int varcount =  vars.Count;
5085                 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
5086                         
5087                 if (last_var.type == null)
5088                         last_var.type = TypeManager.system_object_expr;
5089                         
5090                 Expression cur_type = last_var.type;
5091                 int n = varcount - 1;
5092                 
5093                 while (n >= 0) {
5094                         VariableDeclaration var = (VariableDeclaration) vars[n--];
5095                         if (var.type == null)
5096                                 var.type = cur_type;
5097                         else
5098                                 cur_type = var.type;
5099                 }
5100         }
5101         
5102         public static bool IndexesSpecifiedInRank (ArrayList IndexList)
5103         {
5104                 bool res = false;
5105                 
5106                 if (IndexList != null) {
5107                         foreach (Expression e in IndexList)
5108                                 if (!(e is EmptyExpression)) {
5109                                         res = true;
5110                                         break;
5111                                 }       
5112                 }
5113                 return (res);
5114         }       
5115         
5116         
5117         public static bool IndexesSpecified (ArrayList ranks)
5118         {
5119                 bool res = false;
5120                 
5121                 if (ranks != null) {
5122                         foreach (ArrayList IndexList in ranks) {
5123                                 if (IndexesSpecifiedInRank (IndexList)) {
5124                                         res = true;
5125                                         break;
5126                                 }       
5127                         }       
5128                 }
5129                 return (res);
5130         }
5131         
5132         public static string StripDims (string varname, ref string d)
5133         {
5134                 string res = varname;
5135                 string dres = "";
5136                 
5137                 if (varname.IndexOf("[") >= 0) {
5138                         dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
5139                         res = varname.Substring(0, varname.IndexOf("["));
5140                 }
5141                 d = dres;
5142                 return (res);
5143         }       
5144         
5145         public static string StripDims (string varname)
5146         {
5147                 string dres = "";
5148                 
5149                 return (StripDims(varname, ref dres));
5150         }       
5151         
5152         public static string StripIndexesFromDims (string dims)
5153         {
5154                 StringBuilder sb = new StringBuilder();
5155
5156                 foreach (char c in dims) 
5157                         if (c == ',' || c == ']' || c == '[')
5158                                 sb.Append (c);
5159                                 
5160                 return sb.ToString();                           
5161         }
5162         
5163         public static string BuildRank (ArrayList rank)
5164         {
5165                 bool allEmpty;
5166                 return BuildRank(rank, out allEmpty);
5167         }
5168             
5169         public static string BuildRank (ArrayList rank, out bool allEmpty)
5170         {
5171                 string res = "";
5172
5173                 res += "[";
5174                 allEmpty = true;
5175                 bool first = true;
5176                 foreach (object e in rank) {
5177                         if (!(e is EmptyExpression))
5178                                 allEmpty = false;
5179                         if (!first)
5180                                 res += ",";
5181                         first = false;
5182                 }
5183                         
5184                 res += "]";
5185                 return res;
5186         }
5187                 
5188         public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
5189         {
5190                 string res = "";
5191
5192                 bool allEmpty = true;
5193                 foreach (ArrayList rank in rank_specifiers) {
5194                         bool tmp;
5195                         res = BuildRank (rank, out tmp) + res;
5196                         if (!tmp)
5197                                 allEmpty = false;
5198                 }
5199                 if (!allEmpty && mustBeEmpty)
5200                         Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");    
5201
5202                 return res;
5203         }       
5204         
5205         public static void VBFixIndexList (ref ArrayList IndexList)
5206         {
5207                 if (IndexList != null) {
5208                         for (int x = 0; x < IndexList.Count; x++) {
5209                                 Expression e = (Expression) IndexList[x];
5210                                 if (!(e is EmptyExpression)) {
5211                                         IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
5212                                 }
5213                         }
5214                 }
5215         }               
5216         
5217 //      public static bool IsArrayDecl (Parser t)
5218 //      {
5219 //              // return (varname.IndexOf("[") >= 0);
5220 //              return (t.current_rank_specifiers != null);
5221 //      }                       
5222         
5223         public static void VBFixIndexLists (ref ArrayList ranks)
5224         {       
5225                 if (ranks != null) {
5226                         for (int x = 0; x < ranks.Count; x++) {
5227                                 ArrayList IndexList = (ArrayList) ranks[x];
5228                                 VBFixIndexList (ref IndexList);
5229                         }       
5230                 }       
5231         }
5232                 
5233         public static void FixupArrayTypes (ArrayList vars)
5234         {
5235                 int varcount =  vars.Count;
5236                 string dims;
5237                 
5238                 foreach (VariableDeclaration var in vars) {
5239                         if (var.identifier.EndsWith(",")) {
5240                                 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","), 
5241                                                                 var.identifier.LastIndexOf(",")) + "]";
5242                                 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
5243                                 var.type = new ComposedCast (var.type, (string) dims, var.Location);
5244                         }
5245                 }
5246         }                               
5247 }
5248
5249
5250 // public Property BuildSimpleProperty (Expression p_type, string name, 
5251 //                                      Field p_fld, int mod_flags,
5252 //                                      Attributes attrs, Location loc) 
5253 // {
5254 //      Property p;
5255 //      Block get_block, set_block;
5256 //      Accessor acc_set, acc_get;
5257 //      StatementExpression a_set;
5258 //      Statement a_get;
5259 //      Parameter [] args;
5260         
5261 //      // Build SET Block
5262 //      Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);    
5263 //      args  = new Parameter [1];
5264 //      args [0] = implicit_value_parameter;
5265                 
5266 //      Parameters set_params = new Parameters (args, null, loc);
5267 //      a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc), 
5268 //                          (Expression) new SimpleName("value", loc), loc), loc);
5269                             
5270 //      set_block = new Block (current_block, set_params, loc, Location.Null);
5271 //      set_block.AddStatement ((Statement) a_set);                                         
5272 //      acc_set = new Accessor (set_block, attrs);
5273         
5274 //      // Build GET Block
5275 //      a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
5276 //      get_block = new Block (current_block, null, loc, Location.Null);
5277 //      get_block.AddStatement ((Statement) a_get);                                         
5278 //      acc_get = new Accessor (get_block, attrs);
5279                 
5280 //      p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
5281         
5282 //      return (p);
5283 // }
5284         
5285 void start_block () 
5286 {
5287           if (current_block == null){
5288                   current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, 
5289                                              current_local_parameters, lexer.Location);
5290                   top_current_block = current_block;
5291           } else {
5292                   current_block = new Block (current_block, current_local_parameters,
5293                                                  lexer.Location, Location.Null);
5294           }
5295
5296
5297
5298 Block end_block ()
5299
5300         Block res;
5301
5302         while (current_block.Implicit)
5303                 current_block = current_block.Parent;
5304         res = current_block;
5305         current_block.SetEndLocation (lexer.Location);
5306         current_block = current_block.Parent;
5307         if (current_block == null)
5308                 top_current_block = null;
5309
5310         return res;
5311 }
5312
5313 // private void AddHandler (Expression evt_definition, Expression handler_exp)
5314 // {
5315 //      AddHandler (current_block, evt_definition, handler_exp);
5316 // }
5317
5318 void CheckAttributeTarget (string a)
5319 {
5320         switch (a) {
5321
5322         case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
5323                 return;
5324                 
5325         default :
5326                 Location l = lexer.Location;
5327                 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
5328                 break;
5329         }
5330 }
5331
5332 // private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
5333 // {
5334 //      Expression evt_target;
5335 //      Location loc = lexer.Location;
5336         
5337 //      Statement addhnd = (Statement) new AddHandler (evt_id, 
5338 //                                                                                                      handles_exp, 
5339 //                                                                                                      loc);                                                                                                   
5340                                                                                                         
5341 //      b.AddStatement (addhnd);
5342 // }
5343
5344 // private void RaiseEvent (string evt_name, ArrayList args)
5345 // {
5346 //      Location loc = lexer.Location;
5347         
5348 //      Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
5349 //      Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc)); 
5350 //      current_block.AddStatement (s); 
5351 // }
5352
5353 // private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
5354 // {
5355 //      Expression evt_target;
5356 //      Location loc = lexer.Location;
5357         
5358 //      Statement rmhnd = (Statement) new RemoveHandler (evt_definition, 
5359 //                                                                                                      handler_exp, 
5360 //                                                                                                      loc);
5361 //      b.AddStatement (rmhnd);
5362 // }
5363
5364 // <summary>
5365 //  This method is used to get at the complete string representation of
5366 //  a fully-qualified type name, hiding inside a MemberAccess ;-)
5367 //  This is necessary because local_variable_type admits primary_expression
5368 //  as the type of the variable. So we do some extra checking
5369 // </summary>
5370 string GetQualifiedIdentifier (Expression expr)
5371 {
5372         if (expr is SimpleName)
5373                 return ((SimpleName)expr).Name;
5374         else if (expr is MemberAccess)
5375                 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
5376         else 
5377                 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
5378         
5379 }
5380
5381 // private void RemoveHandler (Expression evt_definition, Expression handler_exp)
5382 // {
5383 //      RemoveHandler (current_block, evt_definition, handler_exp);
5384 // }
5385
5386 // FIXME: This needs to be fixed for This and Base access because the way the name of the
5387 // mbas' constructor is changed from "New" to current_container.Basename
5388
5389 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
5390 {
5391         ConstructorInitializer ci = null;
5392         
5393         if (s.Count > 0) {
5394                 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
5395                         Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
5396                         
5397                         if (i.expr is BaseAccess) {
5398                                 BaseAccess ba = (BaseAccess) i.expr;
5399                                 if (ba.member == "New" || ba.member == ".ctor") {
5400                                         ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
5401                                         s.RemoveAt(0);
5402                                 }
5403                         }
5404                         if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
5405                                 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location); 
5406                                 s.RemoveAt(0);
5407                         }
5408                 }
5409         }
5410         return ci;
5411 }
5412
5413 void Error_ExpectingTypeName (Location l, Expression expr)
5414 {
5415         if (expr is Invocation){
5416                 Report.Error (1002, l, "; expected");
5417         } else {
5418                 Report.Error (-1, l, "Invalid Type definition");
5419         }
5420 }
5421
5422 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
5423         return true;
5424 }
5425
5426 private void ReportError9998()
5427 {
5428         Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
5429 }
5430
5431 public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
5432 {
5433         current_namespace = new NamespaceEntry (null, file, null, Location.Null);
5434         this.name = file.Name;
5435         this.file = file;
5436         current_container = RootContext.Tree.Types;
5437         current_container.NamespaceEntry = current_namespace;
5438         oob_stack = new Stack ();
5439         switch_stack = new Stack ();
5440
5441         lexer = new Tokenizer (reader, file, defines);
5442
5443         ifElseStateMachine = new IfElseStateMachine();
5444         tokenizerController = new TokenizerController(lexer);
5445 }
5446
5447 public void parse ()
5448 {
5449         try {
5450                 if (yacc_verbose_flag > 1)
5451                         yyparse (lexer, new yydebug.yyDebugSimple ());
5452                 else
5453                         yyparse (lexer);
5454                 Tokenizer tokenizer = lexer as Tokenizer;
5455                 tokenizer.cleanup ();           
5456         } catch (Exception e){
5457                 // 
5458                 // Removed for production use, use parser verbose to get the output.
5459                 //
5460                 // Console.WriteLine (e);
5461                 Report.Error (-25, lexer.Location, "Parsing error");
5462                 if (yacc_verbose_flag > 0)
5463                         Console.WriteLine (e);
5464         }
5465 }
5466
5467
5468 // protected override int parse ()
5469 // {
5470 //      RootContext.InitializeImports(ImportsList);
5471 //      current_namespace = new Namespace (null, RootContext.RootNamespace);
5472 //      current_container = RootContext.Tree.Types;
5473 //      current_container.Namespace = current_namespace;
5474 //      oob_stack = new Stack ();
5475 //      switch_stack = new Stack ();
5476 //      expr_stack = new Stack ();      
5477 //      tmp_blocks = new Stack(); 
5478 //      with_stack = new Stack();
5479 //      statement_stack = new Stack();  
5480
5481 //      allow_global_attribs = true;
5482 //      expecting_global_attribs = false;
5483 //      expecting_local_attribs = false;
5484 //      local_attrib_section_added = false;
5485
5486 //      UseExtendedSyntax = name.EndsWith(".mbs");
5487 //      OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
5488 //      OptionStrict = InitialOptionStrict || UseExtendedSyntax;
5489 //      OptionCompareBinary = InitialOptionCompareBinary;
5490
5491 //      lexer = new Tokenizer (input, name, defines);
5492         
5493 //      ifElseStateMachine = new IfElseStateMachine();
5494 //      tokenizerController = new TokenizerController(lexer);
5495         
5496 //      StringBuilder value = new StringBuilder ();
5497 //      try {
5498 //              if (yacc_verbose_flag > 0)
5499 //                      yyparse (lexer, new yydebug.yyDebugSimple ());
5500 //              else {
5501 //                      yyparse (lexer);
5502 //                      cleanup();
5503 //              }
5504 //      } 
5505 //      catch(MBASException e) {
5506 //              Report.Error(e.code, e.loc, e.Message);
5507 //      }
5508 //      catch (Exception e) {
5509 //              if (Report.Stacktrace)
5510 //                      Console.WriteLine(e);
5511 //              Report.Error (29999, lexer.Location, "Parsing error");
5512 //      }
5513
5514 //      RootContext.VerifyImports();
5515
5516 //      return Report.Errors;
5517 // }
5518
5519 // void cleanup()
5520 // {
5521 //      try {
5522 //              ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
5523 //      }
5524 //      catch(ApplicationException) {
5525 //              throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5526 //      }
5527
5528 //      if(in_external_source) 
5529 //              Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
5530
5531 //      if(in_marked_region > 0)
5532 //              Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
5533 // }
5534
5535 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
5536 {
5537         try {
5538                 tokenizerController.PositionTokenizerCursor(tok, expr);
5539         }
5540         catch(ApplicationException) {
5541                 tok = IfElseStateMachine.Token.EOF;
5542                 try {
5543                         ifElseStateMachine.HandleToken(tok);
5544                 }
5545                 catch(ApplicationException) {
5546                         throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5547                 }
5548         }
5549 }
5550 /* end end end */
5551
5552 // <summary>
5553 //   Given the @class_name name, it creates a fully qualified name
5554 //   based on the containing declaration space
5555 // </summary>
5556 MemberName
5557 MakeName (MemberName class_name)
5558 {
5559         string ns = current_namespace.FullName;
5560
5561         if (current_container.Name == ""){
5562                 if (ns != "")
5563                         return new MemberName (new MemberName (ns), class_name);
5564                 else
5565                         return class_name;
5566         } else {
5567                 return new MemberName (current_container.MemberName, class_name);
5568         }
5569 }
5570
5571 }