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