root/branches/compiler/cSharp/ooasCompiler/src/Program.cs
3 | krennw | /**
|
|
*
|
|||
* OOAS Compiler (Deprecated)
|
|||
*
|
|||
* Copyright 2015, Institute for Software Technology, Graz University of
|
|||
* Technology. Portions are copyright 2015 by the AIT Austrian Institute
|
|||
* of Technology. All rights reserved.
|
|||
*
|
|||
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
|
|||
*
|
|||
* Please notice that this version of the OOAS compiler is considered de-
|
|||
* precated. Only the Java version is maintained.
|
|||
*
|
|||
* Contributors:
|
|||
* Willibald Krenn (TU Graz/AIT)
|
|||
* Stefan Tiran (TU Graz/AIT)
|
|||
*/
|
|||
using System;
|
|||
using System.Collections.Generic;
|
|||
using System.Text;
|
|||
using System.Configuration;
|
|||
using Antlr.Runtime;
|
|||
using TUG.Mogentes.Codegen;
|
|||
namespace TUG.Mogentes
|
|||
{
|
|||
[Serializable()]
|
|||
public struct ArgosVersion
|
|||
{
|
|||
public int ParserMajor;
|
|||
public int ParserMinor;
|
|||
public int ParserRevision;
|
|||
public int GrammarMajor;
|
|||
public int GrammarMinor;
|
|||
public override string ToString()
|
|||
{
|
|||
StringBuilder result = new StringBuilder();
|
|||
result.Append(" Version: ");
|
|||
result.Append(ParserMajor); result.Append("."); result.Append(String.Format("{0:00}",ParserMinor));
|
|||
result.Append(" ("); result.Append(ParserRevision); result.AppendLine(")");
|
|||
result.Append(" Grammar-Version: ");
|
|||
result.Append(GrammarMajor); result.Append("."); result.Append(String.Format("{0:00}",GrammarMinor));
|
|||
return result.ToString();
|
|||
}
|
|||
}
|
|||
public abstract class ConfigurationElementCollection<T> : ConfigurationElementCollection
|
|||
where T : ConfigurationElement
|
|||
{
|
|||
protected override ConfigurationElement CreateNewElement()
|
|||
{
|
|||
return (ConfigurationElement)Activator.CreateInstance(typeof(T));
|
|||
}
|
|||
public void Add(T elem)
|
|||
{
|
|||
BaseAdd(elem);
|
|||
}
|
|||
public T this[int index]
|
|||
{
|
|||
get { return (T)base.BaseGet(index); }
|
|||
set
|
|||
{
|
|||
if (base.BaseGet(index) != null)
|
|||
{
|
|||
base.BaseRemoveAt(index);
|
|||
}
|
|||
this.BaseAdd(index, value);
|
|||
}
|
|||
}
|
|||
public new T this[string key]
|
|||
{
|
|||
get { return (T)base.BaseGet(key); }
|
|||
}
|
|||
}
|
|||
public class BackEndConfig : ConfigurationElement
|
|||
{
|
|||
[ConfigurationProperty("switch", IsRequired = true)]
|
|||
public string Switch
|
|||
{
|
|||
get { return (string)base["switch"]; }
|
|||
set { base["switch"] = value; }
|
|||
}
|
|||
[ConfigurationProperty("file", IsRequired = true)]
|
|||
public string File
|
|||
{
|
|||
get { return (string)base["file"]; }
|
|||
set { base["file"] = value; }
|
|||
}
|
|||
[ConfigurationProperty("class", IsRequired = true)]
|
|||
public string Class
|
|||
{
|
|||
get { return (string)base["class"]; }
|
|||
set { base["class"] = value; }
|
|||
}
|
|||
[ConfigurationProperty("descr", IsRequired = true)]
|
|||
public string Descr
|
|||
{
|
|||
get { return (string)base["descr"]; }
|
|||
set { base["descr"] = value; }
|
|||
}
|
|||
public BackEndConfig(string aSwitch, string aFile, string aClass, string aDescr)
|
|||
: base()
|
|||
{
|
|||
Switch = aSwitch;
|
|||
File = aFile;
|
|||
Class = aClass;
|
|||
Descr = aDescr;
|
|||
}
|
|||
public BackEndConfig(BackEndConfig toCopy)
|
|||
{
|
|||
Switch = toCopy.Switch;
|
|||
File = toCopy.File;
|
|||
Class = toCopy.Class;
|
|||
Descr = toCopy.Descr;
|
|||
}
|
|||
public BackEndConfig() { }
|
|||
}
|
|||
public class InstantiatedBackEndConfig : BackEndConfig
|
|||
{
|
|||
public Type Visitor;
|
|||
public System.Reflection.ConstructorInfo Constr;
|
|||
public CreateVisitor GetConstructor()
|
|||
{
|
|||
return p => (IAstVisitor)Constr.Invoke(new Object[] { p });
|
|||
}
|
|||
public InstantiatedBackEndConfig(BackEndConfig toInstantiate)
|
|||
: base(toInstantiate)
|
|||
{
|
|||
if (toInstantiate.File != String.Empty)
|
|||
{
|
|||
string filename = System.IO.Path.GetFullPath(toInstantiate.File);
|
|||
if (!System.IO.File.Exists(filename))
|
|||
{
|
|||
filename = new Uri(System.Reflection.Assembly.GetExecutingAssembly().Location).LocalPath;
|
|||
filename = System.IO.Path.GetDirectoryName(filename) + System.IO.Path.DirectorySeparatorChar + toInstantiate.File;
|
|||
if (!System.IO.File.Exists(filename))
|
|||
{
|
|||
throw new ArgumentException(String.Format("Not found: {0}", toInstantiate.File));
|
|||
}
|
|||
}
|
|||
this.File = filename;
|
|||
System.Reflection.Assembly backend = System.Reflection.Assembly.LoadFile(File);
|
|||
Visitor = backend.GetType(toInstantiate.Class);
|
|||
if (Visitor == null)
|
|||
throw new ArgumentException(String.Format("Cannot find type {0}", toInstantiate.Class));
|
|||
}
|
|||
else
|
|||
{
|
|||
Visitor = System.Reflection.Assembly.GetExecutingAssembly().GetType(toInstantiate.Class);
|
|||
if (Visitor == null)
|
|||
throw new ArgumentException(String.Format("Cannot find type {0}", toInstantiate.Class));
|
|||
}
|
|||
Constr = Visitor.GetConstructor(new Type[] { typeof(ParserState) });
|
|||
if (Constr == null)
|
|||
throw new ArgumentException(String.Format("Cannot get constructor of type {0}", toInstantiate.Class));
|
|||
}
|
|||
}
|
|||
[ConfigurationCollection(typeof(BackEndConfig))]
|
|||
public class BackendSettingsCollection : ConfigurationElementCollection<BackEndConfig>
|
|||
{
|
|||
protected override object GetElementKey(ConfigurationElement element)
|
|||
{
|
|||
return ((BackEndConfig)element).Switch;
|
|||
}
|
|||
}
|
|||
public class ArgosConfigData : ConfigurationSection
|
|||
{
|
|||
public ArgosConfigData()
|
|||
{
|
|||
}
|
|||
[ConfigurationProperty("backends")]
|
|||
public BackendSettingsCollection BackendSettings
|
|||
{
|
|||
get { return (BackendSettingsCollection)this["backends"]; }
|
|||
set { this["backends"] = value; }
|
|||
}
|
|||
}
|
|||
public class Program
|
|||
{
|
|||
public class Options
|
|||
{
|
|||
public static string searchDepth = "35";
|
|||
internal bool quiet = false;
|
|||
internal string fileToParse = String.Empty;
|
|||
internal string outputToFile = String.Empty;
|
|||
internal string namedTypePrefix = String.Empty;
|
|||
public static string nameSpace = "as";
|
|||
internal List<CreateVisitor> pipeLine = new List<CreateVisitor>();
|
|||
}
|
|||
public static List<InstantiatedBackEndConfig> BackEnds = new List<InstantiatedBackEndConfig>();
|
|||
public static readonly string BackEndSectionName = "BackEnds";
|
|||
static void CreateSection()
|
|||
{
|
|||
try
|
|||
{
|
|||
ArgosConfigData customSection;
|
|||
// Get the current configuration file.
|
|||
System.Configuration.Configuration config =
|
|||
ConfigurationManager.OpenExeConfiguration(
|
|||
ConfigurationUserLevel.None);
|
|||
// Create the section entry
|
|||
// in the <configSections> and the
|
|||
// related target section in <configuration>.
|
|||
if (config.Sections[BackEndSectionName] == null)
|
|||
{
|
|||
customSection = new ArgosConfigData();
|
|||
customSection.BackendSettings.Add(new BackEndConfig("a", String.Empty, "TUG.Mogentes.OoaPrintVisitor", "create psuedo-action system code"));
|
|||
customSection.BackendSettings.Add(new BackEndConfig("p", String.Empty, "TUG.Mogentes.Codegen.OoaPrologVisitor", "create prolog code"));
|
|||
customSection.BackendSettings.Add(new BackEndConfig("psym", String.Empty, "TUG.Mogentes.Codegen.PrologSymbolic.OoaPrologSymbolicVisitor", "create symbolic prolog code"));
|
|||
config.Sections.Add(BackEndSectionName, customSection);
|
|||
customSection.SectionInformation.ForceSave = true;
|
|||
config.Save(ConfigurationSaveMode.Full);
|
|||
}
|
|||
}
|
|||
catch (ConfigurationErrorsException err)
|
|||
{
|
|||
Console.WriteLine(err.ToString());
|
|||
}
|
|||
}
|
|||
public static ArgosVersion GetProgramVersion()
|
|||
{
|
|||
Version ver = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
|||
ArgosVersion result;
|
|||
result.ParserMajor = ver.Major;
|
|||
result.ParserMinor = ver.Minor;
|
|||
result.ParserRevision = ver.Revision;
|
|||
result.GrammarMajor = (ver.Build / 100);
|
|||
result.GrammarMinor = (ver.Build % 100);
|
|||
return result;
|
|||
}
|
|||
static void displayTitle()
|
|||
{
|
|||
ArgosVersion ver = Program.GetProgramVersion();
|
|||
Console.WriteLine();
|
|||
Console.WriteLine(" >> Mogentes OO-Action System Parser <<");
|
|||
Console.WriteLine();
|
|||
Console.WriteLine(ver.ToString());
|
|||
Console.WriteLine();
|
|||
}
|
|||
/* display some help screen */
|
|||
static void displayHelp()
|
|||
{
|
|||
string programName = String.Empty;
|
|||
programName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToString();
|
|||
displayTitle();
|
|||
Console.WriteLine("Usage: " + programName + " [options] <oo-actionsystem-file>");
|
|||
Console.WriteLine("Options:");
|
|||
Console.WriteLine(" -o<name> ... write output to file <name> (overwrites!)");
|
|||
Console.WriteLine(" -n<name> ... use namespace <name> (default: as)");
|
|||
Console.WriteLine(" -d<depth> ... set max. search depth (default: 35)");
|
|||
Console.WriteLine(" -q ... \"quiet\" mode: doesn't print Warnings to console");
|
|||
Console.WriteLine();
|
|||
foreach (var x in BackEnds)
|
|||
{
|
|||
Console.WriteLine(String.Format(" -{0} ... {1}", x.Switch, x.Descr));
|
|||
}
|
|||
}
|
|||
/* fire up the parser */
|
|||
static int runAntlrParser(Options options)
|
|||
{
|
|||
ParserState pState = new ParserState(options);
|
|||
int result = ooaParser.FirstPass(pState);
|
|||
displayTitle();
|
|||
if (result > 0)
|
|||
{
|
|||
Console.WriteLine("The parser returned {0} errors:", result);
|
|||
foreach (var error in pState.listOfParserErrors)
|
|||
Console.WriteLine("ERROR ({0}): {1},{2}; {3}", error.file, error.line, error.column, error.message);
|
|||
}
|
|||
else
|
|||
{
|
|||
Console.WriteLine(" Passed: OoaParser");
|
|||
if (options.pipeLine.Count > 0)
|
|||
{
|
|||
IAstVisitor visitor = null;
|
|||
foreach (var item in options.pipeLine)
|
|||
{
|
|||
visitor = item(pState);
|
|||
pState.ooaSystem.Accept(visitor);
|
|||
if (pState.listOfParserErrors.Count > 0)
|
|||
{
|
|||
Console.WriteLine("The parser ({0}) returned {1} errors:",
|
|||
visitor.GetType().Name, pState.listOfParserErrors.Count);
|
|||
foreach (var error in pState.listOfParserErrors)
|
|||
Console.WriteLine("ERROR ({0}): {1},{2}; {3}",
|
|||
error.file, error.line, error.column, error.message);
|
|||
return pState.listOfParserErrors.Count;
|
|||
}
|
|||
else
|
|||
{
|
|||
Console.Write(" Passed: ");
|
|||
Console.WriteLine(visitor.GetType().Name);
|
|||
}
|
|||
}
|
|||
Console.WriteLine();
|
|||
Console.WriteLine("File {0} successfully parsed.", pState.filename);
|
|||
Console.WriteLine("");
|
|||
if (pState.listOfParserMessages.Count > 0 && !(options.quiet))
|
|||
{
|
|||
Console.WriteLine(String.Format("Parser returned {0} messages:", pState.listOfParserMessages.Count));
|
|||
foreach (var message in pState.listOfParserMessages)
|
|||
Console.WriteLine("Message ({0}): {1},{2}; {3}",
|
|||
message.file, message.line, message.column, message.message);
|
|||
Console.WriteLine();
|
|||
Console.WriteLine();
|
|||
}
|
|||
if (pState.listOfParserWarnings.Count > 0 && !(options.quiet))
|
|||
{
|
|||
Console.WriteLine(String.Format("Parser returned {0} warnings:", pState.listOfParserWarnings.Count));
|
|||
foreach (var warning in pState.listOfParserWarnings)
|
|||
Console.WriteLine("Warning ({0}): {1},{2}; {3}",
|
|||
warning.file, warning.line, warning.column, warning.message);
|
|||
Console.WriteLine("");
|
|||
Console.WriteLine("");
|
|||
}
|
|||
if (options.outputToFile != String.Empty)
|
|||
{
|
|||
Console.WriteLine("Writing output to {0}.", options.outputToFile);
|
|||
System.IO.File.WriteAllText(options.outputToFile, visitor.ToString(), System.Text.Encoding.ASCII);
|
|||
}
|
|||
else
|
|||
Console.WriteLine(visitor.ToString());
|
|||
}
|
|||
else
|
|||
{
|
|||
Console.WriteLine();
|
|||
Console.WriteLine("File {0} successfully parsed.", pState.filename);
|
|||
Console.WriteLine("");
|
|||
}
|
|||
}
|
|||
return result;
|
|||
}
|
|||
/* entry point */
|
|||
static int Main(string[] args)
|
|||
{
|
|||
CreateSection();
|
|||
Program.Options options = new Program.Options();
|
|||
/*load backends..*/
|
|||
ArgosConfigData backends = ConfigurationManager.GetSection(BackEndSectionName) as ArgosConfigData;
|
|||
foreach (var x in backends.BackendSettings)
|
|||
{
|
|||
BackEndConfig cnfg = (BackEndConfig)x;
|
|||
//try
|
|||
//{
|
|||
InstantiatedBackEndConfig icnfg = new InstantiatedBackEndConfig(cnfg);
|
|||
BackEnds.Add(icnfg);
|
|||
//}
|
|||
//catch (ArgumentException)
|
|||
//{ }
|
|||
}
|
|||
if ((args.Length == 0) || (!System.IO.File.Exists(args[args.Length - 1])))
|
|||
{
|
|||
displayHelp();
|
|||
#if DEBUG
|
|||
Console.ReadLine();
|
|||
#endif
|
|||
return 0;
|
|||
}
|
|||
/*do some argument 'parsing'*/
|
|||
for (int i = 0; i < args.Length; i++)
|
|||
{
|
|||
if (args[i].StartsWith("-"))
|
|||
ParserOption(args[i], options);
|
|||
else
|
|||
{
|
|||
options.fileToParse = args[i];
|
|||
break;
|
|||
}
|
|||
}
|
|||
/* c# really lacks meta-classes :-((
|
|||
* but lambdas are a nice feature too :-)
|
|||
*/
|
|||
int index = 0;
|
|||
options.pipeLine.Insert(index++, p => new OoaSymbolSortVisitor(p));
|
|||
options.pipeLine.Insert(index++, p => new OoaReplaceOpaqueVisitor(p));
|
|||
options.pipeLine.Insert(index++, p => new OoaTypesVisitor(p));
|
|||
options.pipeLine.Insert(index++, p => new OoaResolveExpressionsVisitor(p));
|
|||
options.pipeLine.Insert(index++, p => new OoaMethodPureClassifierVisitor(p));
|
|||
options.pipeLine.Insert(index++, p => new OoaTypeCheckVisitor(p));
|
|||
if (options.namedTypePrefix != String.Empty)
|
|||
{
|
|||
options.pipeLine.Insert(index++, p => new OoaTypeRenameVisitor(p));
|
|||
}
|
|||
options.pipeLine.Insert(index++, aParser => new OoaRemoveTrivialPrioritizedCompositionVisitor(aParser));
|
|||
options.pipeLine.Insert(index++, p => new OoaActionClassifierVisitor(p));
|
|||
options.pipeLine.Insert(index++, p => new OoaObjectInstantiationVisitor(p));
|
|||
Console.WriteLine("Parsing {0}.", options.fileToParse);
|
|||
int result = runAntlrParser(options);
|
|||
#if DEBUG
|
|||
Console.ReadLine();
|
|||
#endif
|
|||
return result;
|
|||
}
|
|||
private static void ParserOption(string p, Options options)
|
|||
{
|
|||
string p_lower = p.ToLower();
|
|||
if (p_lower.StartsWith("-o"))
|
|||
options.outputToFile = p.Remove(0, 2);
|
|||
if (p_lower.StartsWith("-t"))
|
|||
options.namedTypePrefix = p.Remove(0, 2);
|
|||
if (p_lower.StartsWith("-n"))
|
|||
{
|
|||
TUG.Mogentes.Program.Options.nameSpace = p.Remove(0, 2);
|
|||
}
|
|||
if (p_lower.StartsWith("-q"))
|
|||
{
|
|||
p.Remove(0, 2);
|
|||
options.quiet = true;
|
|||
}
|
|||
if (p_lower.StartsWith("-d"))
|
|||
{
|
|||
TUG.Mogentes.Program.Options.searchDepth = p.Remove(0, 2);
|
|||
}
|
|||
else
|
|||
foreach (var x in BackEnds)
|
|||
{
|
|||
if (p_lower.Equals(String.Format("-{0}", x.Switch)))
|
|||
{
|
|||
options.pipeLine.Add(x.GetConstructor());
|
|||
return;
|
|||
}
|
|||
}
|
|||
}
|
|||
}
|
|||
}
|