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