2004/03/22 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
[mono.git] / mcs / mbas / genericparser.cs
index f31f0be075cc00d7c59f657fa281ba9c03dcb3a3..817cd33c319fa246f660ad24d134e5ea9a619989 100644 (file)
@@ -14,7 +14,7 @@ namespace Mono.Languages
        using System.Reflection;\r
        using System.Collections;\r
        using System.IO;\r
-       using Mono.CSharp;\r
+       using Mono.MonoBASIC;\r
 \r
        /// <summary>\r
        /// Base class to support multiple Jay generated parsers\r
@@ -30,6 +30,9 @@ namespace Mono.Languages
                // Maps extensions to specific parsers\r
                static private Hashtable mapOfParsers;\r
 \r
+               // Maps extensions to specific parsers\r
+               static private GenericParser defaultParser = null;\r
+\r
                // Indicates if parsing should be verbose\r
                static public bool yacc_verbose_flag = false;\r
 \r
@@ -50,14 +53,14 @@ namespace Mono.Languages
 \r
                // Current typecontainer definition\r
                protected TypeContainer current_container;\r
-\r
+               \r
                // ---------------------------------------------------\r
                // What the descendants MUST reimplement\r
 \r
                /// <summary>\r
                /// Parses the current "input"\r
                /// </summary>\r
-               public abstract int parse();\r
+               protected abstract int parse();\r
 \r
                /// <summary>\r
                /// Lists the extensions this parser can handle\r
@@ -110,7 +113,6 @@ namespace Mono.Languages
 \r
                static private void MapParsers()\r
                {\r
-\r
                        mapOfParsers = new Hashtable();\r
 \r
                        Assembly thisAssembly = Assembly.GetExecutingAssembly();\r
@@ -128,29 +130,41 @@ namespace Mono.Languages
                                                        else\r
                                                                mapOfParsers.Add(theFileExtension, parser);\r
                                                }\r
+                                               object[] attribs = type.GetCustomAttributes(typeof(DefaultParserAttribute), false);\r
+                                               if (attribs != null && attribs.Length > 0)\r
+                                               {\r
+                                                       if (defaultParser == null)\r
+                                                               defaultParser = parser;\r
+                                                       else\r
+                                                               Console.WriteLine("[TRACE] " + type.FullName + " can't be another default parser");                                                             \r
+                                               }\r
                                        }\r
                        }\r
                }\r
 \r
                /// <summary>\r
                /// Find the descendant parser that knows how to parse the specified file\r
-               /// based on the files extension\r
+               /// based on the file extension, or the default parser otherwise, if available\r
                /// </summary>\r
                /// <param name="fileName">Name of the file to be parsed</param>\r
                public static GenericParser GetSpecificParserFor(string fileName)\r
                {\r
                        int i;\r
-                       string fileExtension;\r
+                       GenericParser chosenParser = null;\r
                        \r
                        if (mapOfParsers == null)\r
                                MapParsers();\r
                        \r
-                       if ((i = fileName.LastIndexOf(".")) < 0)\r
-                               return null;\r
-                       else\r
-                               fileExtension = fileName.Substring(i).ToLower();\r
-\r
-                       return (GenericParser)mapOfParsers[fileExtension];\r
+                       if ((i = fileName.LastIndexOf(".")) > 0)\r
+                       {\r
+                               string fileExtension = fileName.Substring(i).ToLower();\r
+                               chosenParser = (GenericParser)mapOfParsers[fileExtension];\r
+                       }\r
+                       \r
+                       if (chosenParser != null)                       \r
+                               return chosenParser;\r
+                               \r
+                       return defaultParser;\r
                }\r
 \r
                \r
@@ -212,12 +226,16 @@ namespace Mono.Languages
                        {\r
                                errors = parser.ParseFile(fileName);\r
                        } \r
-                       catch (FileNotFoundException ex)\r
+                       catch (FileNotFoundException)\r
                        {\r
-                               error(2001, "Source file \'" + fileName + "\' could not be found!!!");\r
-                               Console.WriteLine (ex);\r
+                               Report.Error(2001, "Source file \'" + fileName + "\' could not be found!!!");\r
                                return 1;\r
                        }\r
+                       catch (DirectoryNotFoundException)\r
+                       {\r
+                               Report.Error(2001, "Source file \'" + fileName + "\' could not be found!!!");\r
+                               return 1;\r
+                       }                       \r
                        catch (Exception ex)\r
                        {\r
                                Console.WriteLine (ex);\r
@@ -228,99 +246,77 @@ namespace Mono.Languages
                        return errors;\r
                }\r
 \r
-               // <summary>
-               //   Given the @class_name name, it creates a fully qualified name
-               //   based on the containing declaration space
-               // </summary>
-               protected string MakeName(string class_name)
-               {
-                       string ns = current_namespace.Name;
-                       string container_name = current_container.Name;
-
+               // <summary>\r
+               //   Given the @class_name name, it creates a fully qualified name\r
+               //   based on the containing declaration space\r
+               // </summary>\r
+               protected string MakeName(string class_name)\r
+               {\r
+                       string ns = current_namespace.Name;\r
+                       string container_name = current_container.Name;\r
+\r
                        if (container_name == "")\r
-                       {
-                               if (ns != "")
-                                       return ns + "." + class_name;
-                               else
-                                       return class_name;
+                       {\r
+                               if (ns != "")\r
+                                       return ns + "." + class_name;\r
+                               else\r
+                                       return class_name;\r
                        } \r
-                       else
-                               return container_name + "." + class_name;
-               }
-
-               // <summary>
-               //   Used to report back to the user the result of a declaration
-               //   in the current declaration space
-               // </summary>
-               protected void CheckDef (AdditionResult result, string name, Location l)
-               {
-                       if (result == AdditionResult.Success)
-                               return;
-
-                       switch (result)\r
-                       {
-                               case AdditionResult.NameExists:
-                                       Report.Error (102, l, "The container '" + current_container.Name + 
-                                               "' already contains a definition for '"+
-                                               name + "'");
-                                       break;
-
-
-                                       //
-                                       // This is handled only for static Constructors, because
-                                       // in reality we handle these by the semantic analysis later
-                                       //
-                               case AdditionResult.MethodExists:
-                                       Report.Error (
-                                               111, l, "Class `"+current_container.Name+
-                                               "' already defines a member called '" + 
-                                               name + "' with the same parameter types (more than one default constructor)");
-                                       break;
-
-                               case AdditionResult.EnclosingClash:
-                                       Report.Error (542, l, "Member names cannot be the same as their enclosing type");
-                                       break;
-               
-                               case AdditionResult.NotAConstructor:
-                                       Report.Error (1520, l, "Class, struct, or interface method must have a return type");
-                                       break;
-                       }
-               }
-
-               // <summary>
-               //   Used to report back to the user the result of a declaration
-               //   in the current declaration space
-               // </summary>
-               protected void CheckDef (bool result, string name, Location l)
-               {
-                       if (result)
-                               return;
-                       CheckDef (AdditionResult.NameExists, name, l);
-               }
-
+                       else\r
+                               return container_name + "." + class_name;\r
+               }\r
 \r
-               /// <summary>\r
-               /// Emits error messages and increments a global count of them\r
-               /// </summary>\r
-               /// <param name="code"></param>\r
-               /// <param name="desc"></param>\r
-               static public void error (int code, string desc)\r
+               // <summary>\r
+               //   Used to report back to the user the result of a declaration\r
+               //   in the current declaration space\r
+               // </summary>\r
+               protected void CheckDef (AdditionResult result, string name, Location l)\r
                {\r
-                       Console.WriteLine ("error MC"+code+": "+ desc);\r
-                       global_errors++;\r
+                       if (result == AdditionResult.Success)\r
+                               return;\r
+\r
+                       switch (result)\r
+                       {\r
+                               case AdditionResult.NameExists:\r
+                                       Report.Error (102, l, "The container '" + current_container.Name + \r
+                                               "' already contains a definition for '"+\r
+                                               name + "'");\r
+                                       break;\r
+\r
+\r
+                                       //\r
+                                       // This is handled only for static Constructors, because\r
+                                       // in reality we handle these by the semantic analysis later\r
+                                       //\r
+                               case AdditionResult.MethodExists:\r
+                                       Report.Error (\r
+                                               111, l, "Class `"+current_container.Name+\r
+                                               "' already defines a member called '" + \r
+                                               name + "' with the same parameter types (more than one default constructor)");\r
+                                       break;\r
+\r
+                               case AdditionResult.EnclosingClash:\r
+                                       Report.Error (542, l, "Member names cannot be the same as their enclosing type");\r
+                                       break;\r
+               \r
+                               case AdditionResult.NotAConstructor:\r
+                                       Report.Error (1520, l, "Class, struct, or interface method must have a return type");\r
+                                       break;\r
+                       }\r
                }\r
 \r
-               // Emits error messages with location info.\r
-               // FIXME : Ideally, all error reporting should happen\r
-               // with Report.Error but how do you get at that non-static\r
-               // method everywhere you need it ?\r
-               static public void error (int code, Mono.CSharp.Location l, string text)\r
+               // <summary>\r
+               //   Used to report back to the user the result of a declaration\r
+               //   in the current declaration space\r
+               // </summary>\r
+               protected void CheckDef (bool result, string name, Location l)\r
                {\r
-                       Console.WriteLine (l.Name + "(" + l.Row + ",?" + /*l.Col +*/\r
-                                          "): error MC" + code + ": " + text);\r
-                       global_errors++;\r
+                       if (result)\r
+                               return;\r
+                       CheckDef (AdditionResult.NameExists, name, l);\r
                }\r
-               \r
+\r
+\r
                // ---------------------------------------------------\r
                // Constructors\r
 \r
@@ -330,7 +326,4 @@ namespace Mono.Languages
                }\r
 \r
        }\r
-}\r
-\r
-\r
-\r
+}