2004-12-21 Anirban Bhattacharjee <banirban@novell.com>
[mono.git] / mcs / mbas / mb-parser.jay
index 4555a83e0a0067b897532ef47f631b9a12be01fd..2d7d5fd0c715bddc8e27a1dc59a3f68706cf575d 100644 (file)
@@ -3,8 +3,8 @@
 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
 //
 // Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
-//                 Anirban Bhattacharjee (banirban@novell.com)
-//          Jambunathan (kjambunathan@novell.com)
+//         Anirban Bhattacharjee (banirban@novell.com)
+//          Jambunathan (kjambunathan@novell.com)
 //
 // Licensed under the terms of the GNU GPL
 //
@@ -42,6 +42,7 @@ namespace Mono.MonoBASIC
        {
        
 
+
                /// <summary>
                ///   Current block is used to add statements as we find
                ///   them.  
@@ -627,14 +628,21 @@ compilation_unit
        : logical_end_of_line
          opt_option_directives
          opt_imports_directives 
-         opt_global_attributes
-         opt_declarations 
+         declarations 
          EOF
          {
                $$=$4;
          }
+       |logical_end_of_line
+         opt_option_directives
+         opt_imports_directives 
+         opt_attributes
+         EOF
+         {
+               /* ????? */ ;
+         }
        ;
-         
+         
 opt_option_directives
        : /* empty */
        | option_directives
@@ -821,84 +829,6 @@ opt_params
        | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS    { $$ = $2; }
        ;
 
-opt_global_attributes
-       : /* empty */
-       | global_attribute_sections     
-       ;
-       
-global_attribute_sections
-       : global_attribute_section      
-         { 
-               $$ = null;
-               if ($1 != null) {
-                       CodeGen.AddGlobalAttributes ((ArrayList) $1);
-               }
-         }
-       | global_attribute_sections global_attribute_section    
-         {
-               $$ = null;
-               if ($2 != null) {
-                       CodeGen.AddGlobalAttributes ((ArrayList) $2);
-               }       
-         }
-       ;
-
-global_attribute_section
-       : OP_LT global_attribute_list OP_GT end_of_stmt
-         {
-               $$ = $2;
-         }
-       ; 
-
-global_attribute_list
-       : global_attribute 
-         {
-               ArrayList attrs = null;
-               if ($1 != null) {
-                       attrs = new ArrayList ();
-                       attrs.Add ($1);
-               }
-               $$ = attrs;
-         }     
-       | global_attribute_list COMMA global_attribute
-         {
-               ArrayList attrs = null;
-               if ($3 != null) {
-                       attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
-                       attrs.Add ($3);
-               }
-               $$ = attrs;
-         }     
-       ;
-
-global_attribute 
-       : global_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;
-               }
-               $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location)$5 );
-      }        
-       ;
-
-global_attribute_target_specifier
-       : ASSEMBLY      { $$ = "assembly"; }
-       | MODULE        { $$ = "module"; }
-       | namespace_or_type_name
-       ;
-
 opt_attributes
        : /* empty */
        | attribute_sections    
@@ -912,9 +842,26 @@ attribute_sections
        :  attribute_section    
          { 
                $$ = $1;
-               if ($1 != null) {
+               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;
+
                        $$ = new Attributes ((ArrayList) $1);
                }       
+
+               if (expecting_global_attribs) {
+                       $$ = null;
+                       CodeGen.AddGlobalAttributes ((ArrayList) $1);
+               }
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
          }
        | attribute_sections  
           {
@@ -926,19 +873,51 @@ attribute_sections
                if ($3 != null) {
                        ArrayList attrs = (ArrayList) $3;
 
-                       if ($1 == null)
-                               $$ = new Attributes (attrs);
-                       else 
-                               ((Attributes) $1).Add (attrs);
+                       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;
+                               }
+
+                               if ($1 == null)
+                                       $$ = new Attributes (attrs);
+                               else 
+                                       ((Attributes) $1).Add (attrs);
+
+                               local_attrib_section_added = true;
+                               allow_global_attribs = false;
+                       }
+
+                       if (expecting_global_attribs) {
+                               $$ = null;
+                               CodeGen.AddGlobalAttributes ((ArrayList) $3);
+                       }
                }       
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
          }
        ;
 
 attribute_section
-       : OP_LT attribute_list OP_GT
+       : OP_LT attribute_list OP_GT opt_end_of_stmt
          {
                $$ = 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;
                }
          }
@@ -979,9 +958,54 @@ attribute
           }
           opt_attribute_arguments
           {
-               $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+               $$ = 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_target_specifier
+       :  ASSEMBLY     { $$ = "assembly"; }
+       | MODULE        { $$ = "module"; }
+       | namespace_or_type_name
+       ;
+       
                        
 opt_attribute_arguments
        : /* empty */   { $$ = null; }
@@ -1560,7 +1584,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);
 
@@ -1597,7 +1621,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);
 
@@ -1843,7 +1867,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);
@@ -1864,7 +1888,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);
@@ -1936,6 +1960,16 @@ 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)
+                               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;
@@ -5072,6 +5106,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;
@@ -5084,7 +5123,7 @@ protected override int parse ()
        
        StringBuilder value = new StringBuilder ();
        try {
-               if (yacc_verbose_flag)
+               if (yacc_verbose_flag > 0)
                        yyparse (lexer, new yydebug.yyDebugSimple ());
                else {
                        yyparse (lexer);