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
// 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
\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
\r
static private void MapParsers()\r
{\r
-\r
mapOfParsers = new Hashtable();\r
\r
Assembly thisAssembly = Assembly.GetExecutingAssembly();\r
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
{\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
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
}\r
\r
}\r
-}\r
-\r
-\r
-\r
+}