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