2005-01-19 Sureshkumar T <tsureshkumar@novell.com>
[mono.git] / mcs / mbas / mb-parser.jay
index dce3103eebe9be817a0321db8d104ae337871574..8802a2ffaac970798616263e2c049a7fe4e14e9e 100644 (file)
@@ -2,12 +2,14 @@
 //
 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
 //
-// Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
-//                Anirban Bhattacharjee (banirban@novell.com)
+// Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+//         Anirban Bhattacharjee (banirban@novell.com)
+//          Jambunathan K (kjambunathan@novell.com)
 //
 // Licensed under the terms of the GNU GPL
 //
-// Copyright (C) 2001 A Rafael D Teixeira
+// Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
+// Copyright (C) 2003, 2004 Novell
 //
 //
 
@@ -40,6 +42,7 @@ namespace Mono.MonoBASIC
        {
        
 
+
                /// <summary>
                ///   Current block is used to add statements as we find
                ///   them.  
@@ -364,6 +367,13 @@ namespace Mono.MonoBASIC
                                }
                        }
                }
+
+               bool allow_global_attribs = true;
+
+               bool expecting_global_attribs = false;
+               bool expecting_local_attribs = false;
+
+               bool local_attrib_section_added = false;
 %}
 
 %token EOF
@@ -618,13 +628,19 @@ compilation_unit
        : logical_end_of_line
          opt_option_directives
          opt_imports_directives 
-         opt_global_attributes
-         opt_declarations 
+         declarations 
          EOF
          {
-               $$=$5;
+               $$=$4;
+         }
+       |logical_end_of_line
+         opt_option_directives
+         opt_imports_directives 
+         opt_attributes
+         EOF
+         {
+               /* ????? */ ;
          }
-       
        ;
          
 opt_option_directives
@@ -704,7 +720,7 @@ option_compare_directive
 opt_declarations
        : /* empty */
        | declarations
-       ;
+       ;               
 
 declarations
        : declaration
@@ -712,24 +728,41 @@ declarations
        ;
        
 declaration
-       : namespace_declaration
-       | type_declaration
+       : declaration_qualifiers
+         {
+               // FIXME: Need to check declaration qualifiers for multi-file compilation
+               // FIXME: Qualifiers cannot be applied to namespaces
+               allow_global_attribs = false;
+         }
+         namespace_declaration
+       |declaration_qualifiers
+         {
+                 // FIXME: Need to check declaration qualifiers for multi-file compilation
+                 allow_global_attribs = false;
+         }
+         type_spec_declaration
          {
                string name = "";
                int mod_flags;
 
-               if ($1 is Class || $1 is Struct || $1 is Module ){
-                       TypeContainer c = (TypeContainer) $1;
+               if ($3 is Class || $3 is Struct || $3 is Module ){
+                       TypeContainer c = (TypeContainer) $3;
                        mod_flags = c.ModFlags;
                        name = c.Name;
                } else
                        break;
 
-               if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+               if ((mod_flags & (Modifiers.PRIVATE)) != 0){
                        Report.Error (
-                               1527, lexer.Location, 
+                               31089, lexer.Location, 
                                "Namespace elements cannot be explicitly " +
-                               "declared private or protected in '" + name + "'");
+                               "declared private in '" + name + "'");
+                       }
+               else if ((mod_flags & (Modifiers.PROTECTED)) != 0){
+                       Report.Error (
+                               31047, lexer.Location, 
+                               "Namespace elements cannot be explicitly " +
+                               "declared protected in '" + name + "'");
                }
          }
        ;
@@ -802,93 +835,183 @@ opt_params
        | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS    { $$ = $2; }
        ;
 
-attribute_modifier
-       : ASSEMBLY 
-       | MODULE
-       | identifier 
-          { 
-               Report.Error (658, lexer.Location, "`" + (string)$1 + "' is an invalid attribute target");
-          }
-       ;
+opt_attributes
+       : /* empty */
+       | attribute_sections    
+         { 
+               $$ = $1; 
+               local_attrib_section_added = false;
+         }
+       ;
 
-global_attribute_list
-       : global_attribute
-       | global_attribute_list COMMA global_attribute
-       ;
+attribute_sections
+       :  attribute_section    
+         { 
+               $$ = $1;
+               if ($1 == null) {
+                       expecting_local_attribs = false;
+                       expecting_global_attribs = false;
+                       break;
+               }
+               
+               if (expecting_local_attribs) {
+                       local_attrib_section_added = true;
+                       allow_global_attribs = false;
 
-global_attribute
-       : attribute_modifier COLON attribute
-       ;
+                       $$ = new Attributes ((ArrayList) $1);
+               }       
 
-global_attributes_definition
-       : attr_begin global_attribute_list attr_end
-       ;
+               if (expecting_global_attribs) {
+                       $$ = null;
+                       CodeGen.AddGlobalAttributes ((ArrayList) $1);
+               }
 
-global_attributes
-       : global_attributes_definition
-       | global_attributes global_attributes_definition 
-       | global_attributes end_of_stmt global_attributes_definition
-       ;
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
+         }
+       | attribute_sections  
+          {
+               $$ = lexer.Location;
+          }
+          attribute_section    
+         {
+               $$ = $1;
+               if ($3 != null) {
+                       ArrayList attrs = (ArrayList) $3;
+
+                       if (expecting_local_attribs) {
+                               if (local_attrib_section_added) {
+                                       expecting_local_attribs = false;
+                                       expecting_global_attribs = false;
+                                       Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
+                                       break;
+                               }
 
-opt_global_attributes
-       : /* empty */
-       | global_attributes end_of_stmt
-       ;
+                               if ($1 == null)
+                                       $$ = new Attributes (attrs);
+                               else 
+                                       ((Attributes) $1).Add (attrs);
 
-opt_attributes
-       : /* empty */
-       | attributes    { $$ = $1; }
-       ;
+                               local_attrib_section_added = true;
+                               allow_global_attribs = false;
+                       }
 
-attr_begin
-       : OP_LT
-       ;
+                       if (expecting_global_attribs) {
+                               $$ = null;
+                               CodeGen.AddGlobalAttributes ((ArrayList) $3);
+                       }
+               }       
 
-attr_end
-       : OP_GT
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
+         }
        ;
 
-attributes
-       : attr_begin attribute_list attr_end
+attribute_section
+       : OP_LT attribute_list OP_GT opt_end_of_stmt
          {
-               AttributeSection sect = new AttributeSection (null, (ArrayList) $2);
-               $$ = new Attributes (sect, lexer.Location);
+               $$ = null;
+               if ($2 != null) {
+                       if (expecting_global_attribs && !(bool) $4) {
+                               Report.Error (30205, lexer.Location, "End of statement expected");
+                               break;
+                       }
+                       
+                       if (expecting_local_attribs)  {
+                               if ((bool) $4) {
+                                       Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
+                                       break;
+                               }
+                       }
+
+                       $$ = $2;
+               }
          }
-       | attr_begin global_attribute_list attr_end logical_end_of_line
        ; 
 
+opt_end_of_stmt
+       : /* empty */ { $$ = false; }
+       | end_of_stmt   { $$ = true; }
+       ;
+
 attribute_list
        : attribute 
          {
-               ArrayList attrs = new ArrayList ();
-               attrs.Add ($1);
-
+               ArrayList attrs = null;
+               if ($1 != null) {
+                       attrs = new ArrayList ();
+                       attrs.Add ($1);
+               }
                $$ = attrs;
-              
          }     
        | attribute_list COMMA attribute
          {
-               ArrayList attrs = (ArrayList) $1;
-               attrs.Add ($3);
+               ArrayList attrs = null;
+               
+               if ($3 != null) {
+                       attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
+                       attrs.Add ($3);
+               }
 
                $$ = attrs;
          }     
        ;
 
 attribute 
-       : attribute_name
-         {
+       :  namespace_or_type_name
+          {
                $$ = lexer.Location;
-         }
-         opt_attribute_arguments
-         {
-               $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
-         }       
+          }
+          opt_attribute_arguments
+          {
+               $$ = null;
+               
+               if (expecting_global_attribs)
+                       Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
+               else {
+                       expecting_local_attribs = true;
+                       $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+               }
+          }
+         | attribute_target_specifier 
+           {
+               $$ = lexer.Location;
+           }
+           COLON 
+           namespace_or_type_name
+          {
+                 $$ = lexer.Location;
+          }
+          opt_attribute_arguments
+          {
+               $$ = null;
+
+               string attribute_target = (string) $1;
+               if (attribute_target != "assembly" && attribute_target != "module") {
+                       Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
+                       break;
+               }
+               if (!allow_global_attribs) {
+                       Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
+                       break;
+               }
+
+               if (expecting_local_attribs) {
+                       Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
+                       break;
+               }                       
+
+               expecting_global_attribs = true;
+               $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5);
+           }   
        ;
 
-attribute_name
-       : namespace_or_type_name 
+attribute_target_specifier
+       :  ASSEMBLY     { $$ = "assembly"; }
+       | MODULE        { $$ = "module"; }
+       | namespace_or_type_name
        ;
+       
                        
 opt_attribute_arguments
        : /* empty */   { $$ = null; }
@@ -984,14 +1107,13 @@ namespace_declaration
          }
        ;
 
-type_declaration
+declaration_qualifiers
        : opt_attributes 
          opt_modifiers 
          { 
                current_attributes = (Attributes) $1; 
                current_modifiers = (int) $2; 
          }       
-         type_spec_declaration
        ;
 
 type_spec_declaration
@@ -1004,7 +1126,7 @@ type_spec_declaration
        ;
 
 class_declaration
-       : CLASS identifier logical_end_of_line opt_inherits opt_implements
+       : CLASS identifier end_of_stmt opt_inherits opt_implements
          {
                // Module members are static by default, but Class *can't* be declared static
                // so we must fix it, if mbas was the one actually responsible for this
@@ -1048,12 +1170,12 @@ class_declaration
 
 opt_inherits
        : /* empty */                           { $$ = null; }
-       | INHERITS type_list logical_end_of_line        { $$ = $2; }
+       | INHERITS type_list end_of_stmt        { $$ = $2; }
        ;
 
 opt_implements
        : /* empty */                           { $$ = null; }
-       | IMPLEMENTS type_list logical_end_of_line      { $$ = $2; }
+       | IMPLEMENTS type_list end_of_stmt              { $$ = $2; }
        ;
 
 opt_modifiers
@@ -1165,7 +1287,7 @@ module_member_declarator
        ;
        
 constant_declaration
-       : CONST constant_declarators logical_end_of_line
+       : CONST constant_declarators end_of_stmt
        {
                // Module members are static by default, but constants *can't* be declared static
                // so we must fix it, if mbas was the one actually responsible for this
@@ -1349,7 +1471,6 @@ sub_declaration
                                                evt_target + " is not declared with WithEvents");
                        }
                  } else if (handles_exp is BaseAccess) {
-                               string evt_id = ((BaseAccess) $4).member;
                                Statement addhnd = (Statement) new AddHandler ((Expression) $4, 
                                                                                        DecomposeQI((string) $2, loc), 
                                                                                        loc);   
@@ -1394,7 +1515,7 @@ func_declaration
        ;               
 
 struct_declaration
-       : STRUCTURE identifier logical_end_of_line
+       : STRUCTURE identifier end_of_stmt
          opt_implement_clause
          {
                Struct new_struct;
@@ -1468,7 +1589,7 @@ event_declaration
                VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
 
                Event e = new Event ((Expression) $4, var.identifier, 
-                                    null, current_modifiers, null, null, 
+                                    null, current_modifiers, 
                                     current_attributes, (ArrayList) $5,
                                     lexer.Location);
 
@@ -1505,7 +1626,7 @@ event_declaration
                
                Event e = new Event (DecomposeQI (delName, lexer.Location),
                                         (string) $2, 
-                                    null, current_modifiers, null, null, 
+                                    null, current_modifiers, 
                                     current_attributes, (ArrayList) $4, 
                                     lexer.Location);
 
@@ -1751,7 +1872,7 @@ interface_event_declaration
                VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
 
                Event e = new Event ((Expression) $4, var.identifier, 
-                                    null, current_modifiers, null, null, 
+                                    null, current_modifiers, 
                                     current_attributes, lexer.Location);
 
                CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
@@ -1772,7 +1893,7 @@ interface_event_declaration
          
                Event e = new Event (DecomposeQI (delName, lexer.Location),
                                         (string) $2, 
-                                    null, current_modifiers, null, null, 
+                                    null, current_modifiers, 
                                     current_attributes, lexer.Location);
 
                CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
@@ -1844,6 +1965,17 @@ abstract_propery_declaration
  non_abstract_propery_declaration
          : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
          {
+               if ((current_modifiers & Modifiers.DEFAULT) > 0) {
+                       if (current_container.DefaultPropName != null 
+                                 && current_container.DefaultPropName != (string) $2)
+                               Report.Error (30359, 
+                                               lexer.Location,
+                                               "Type '" + current_container.Name +
+                                               "' cannot have more than one 'Default Property' ");
+                                               
+                       current_container.DefaultPropName = (string) $2;
+               }               
+         
                get_implicit_value_parameter_type  = 
                        ($5 == null) ? (($3 == null) ? 
                                TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
@@ -2034,11 +2166,11 @@ opt_set_parameter
                                
                set_implicit_value_parameter_type = (Expression) $4;
                
-               if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
+               if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
                        Report.Error (31064, 
                                lexer.Location, 
                                "Set value parameter type can not be different from property type");
-               
+                               
                if ($2 != null)
                        set_implicit_value_parameter_name = (string) $3;
                else
@@ -2048,7 +2180,7 @@ opt_set_parameter
                        
 field_declaration
        : opt_dim_stmt 
-         variable_declarators logical_end_of_line
+         variable_declarators end_of_stmt
          {               
                int mod = (int) current_modifiers;
 
@@ -2351,8 +2483,6 @@ statement
            }
          | embedded_statement
            {
-                 Statement s = (Statement) $1;
-
                  current_block.AddStatement ((Statement) $1);
            } 
          | labeled_statement 
@@ -2372,8 +2502,6 @@ statement
          /* | empty_statement */
          | with_statement 
            {
-                 Statement s = (Statement) $1;
-
              current_block.AddStatement ((Statement) $1);
            }     
          ;     
@@ -2952,19 +3080,19 @@ for_statement
          opt_statement_list
          NEXT opt_identifier 
          {
-                       Block inner_statement = end_block();\r
-                       Location l = (Location) oob_stack.Pop ();\r
-                       Expression for_var = (Expression) DecomposeQI ((string)$2, l);\r
-                       \r
-            Expression assign_expr = new Assign (for_var, (Expression) $5, l);\r
-            Expression test_expr =  new Binary (Binary.Operator.LessThanOrEqual,\r
-                                                            for_var, (Expression) $7, l);\r
-            Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,\r
-                                             for_var, (Expression) $8, l), l);\r
-\r
-            Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);\r
-            Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);\r
-\r
+                       Block inner_statement = end_block();
+                       Location l = (Location) oob_stack.Pop ();
+                       Expression for_var = (Expression) DecomposeQI ((string)$2, l);
+                       
+            Expression assign_expr = new Assign (for_var, (Expression) $5, l);
+            Expression test_expr =  new Binary (Binary.Operator.LessThanOrEqual,
+                                                            for_var, (Expression) $7, l);
+            Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
+                                             for_var, (Expression) $8, l), l);
+
+            Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
+            Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
+
             For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
                        if ($3 != null)
                        {
@@ -3019,8 +3147,6 @@ if_statement
 pre_embedded_statement
        : embedded_statement 
          {
-               Statement s = (Statement) $1;
-
                current_block.AddStatement ((Statement) $1);
          } 
        ;       
@@ -3044,7 +3170,6 @@ else_pre_embedded_statement
         tmp_blocks.Push(bl); 
         
                start_block();
-               Statement s = (Statement) $2;
                current_block.AddStatement ((Statement) $2);
          } 
        ;       
@@ -3415,7 +3540,6 @@ constant_declarator
                string varname = (string) vname.Name;
                current_rank_specifiers = (ArrayList) vname.Rank;
                object varinit = $3;
-               ArrayList a_dims = null;
 
                if (varinit == null)
                        Report.Error (
@@ -4244,9 +4368,9 @@ assignment_expression
          }
        | prefixed_unary_expression OP_EXP ASSIGN expression
          {
-               Location l = lexer.Location;
+               /*Location l = lexer.Location;
 
-               /* TODO: $$ = new CompoundAssign (
+                TODO: $$ = new CompoundAssign (
                        Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
          }
        | prefixed_unary_expression ASSIGN ADDRESSOF expression
@@ -4351,8 +4475,6 @@ pp_directive
          {
                if(tokenizerController.IsAcceptingTokens) 
                {
-                       string id = ($2 as string);
-               
                        if(!($2 as string).ToLower().Equals("region"))
                                Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
                        else
@@ -4781,7 +4903,6 @@ public class VariableDeclaration {
                
        public static void FixupArrayTypes (ArrayList vars)
        {
-               int varcount =  vars.Count;
                string dims;
                
                foreach (VariableDeclaration var in vars) {
@@ -4873,13 +4994,11 @@ void CheckAttributeTarget (string a)
 
 private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
 {
-       Expression evt_target;
        Location loc = lexer.Location;
        
        Statement addhnd = (Statement) new AddHandler (evt_id, 
                                                                                                        handles_exp, 
                                                                                                        loc);                                                                                                   
-                                                                                                       
        b.AddStatement (addhnd);
 }
 
@@ -4894,7 +5013,6 @@ private void RaiseEvent (string evt_name, ArrayList args)
 
 private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
 {
-       Expression evt_target;
        Location loc = lexer.Location;
        
        Statement rmhnd = (Statement) new RemoveHandler (evt_definition, 
@@ -4980,6 +5098,11 @@ protected override int parse ()
        with_stack = new Stack();
        statement_stack = new Stack();  
 
+       allow_global_attribs = true;
+       expecting_global_attribs = false;
+       expecting_local_attribs = false;
+       local_attrib_section_added = false;
+
        UseExtendedSyntax = name.EndsWith(".mbs");
        OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
        OptionStrict = InitialOptionStrict || UseExtendedSyntax;
@@ -4990,9 +5113,8 @@ protected override int parse ()
        ifElseStateMachine = new IfElseStateMachine();
        tokenizerController = new TokenizerController(lexer);
        
-       StringBuilder value = new StringBuilder ();
        try {
-               if (yacc_verbose_flag)
+               if (yacc_verbose_flag > 0)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
                else {
                        yyparse (lexer);