/** * * 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 : 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 { 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 pipeLine = new List(); } public static List BackEnds = new List(); 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 and the // related target section in . 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] "); Console.WriteLine("Options:"); Console.WriteLine(" -o ... write output to file (overwrites!)"); Console.WriteLine(" -n ... use namespace (default: as)"); Console.WriteLine(" -d ... 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; } } } } }