private ICollection<State> ParseSyntaxToGraph(string syntax) { var parser = new Parser(new Scanner(new MemoryStream(Encoding.UTF8.GetBytes(syntax)))); parser.Parse(); Assert.Equal(0, parser.errors.count); var graphBuilder = new StateGraphBuilder(); return graphBuilder.BuildGraph(parser.Syntax); }
public void OnDocumentSaved(Document document) { if (document.FullName.EndsWith(FileAndContentTypeDefinitions.FileExtension, StringComparison.OrdinalIgnoreCase)) { var generatedFileName = document.FullName + ".cs"; Action<string> saveDocument = text => File.WriteAllText(generatedFileName, text); var openDocument = _dte.Documents .Cast<Document>() .FirstOrDefault(d => d.FullName.Equals(generatedFileName, StringComparison.OrdinalIgnoreCase)); if (openDocument != null) { saveDocument = text => { var selection = (TextSelection)(object)openDocument.Selection; selection.StartOfDocument(); selection.EndOfDocument(true); selection.Text = ""; var textDocument = (TextDocument)(object)openDocument.Object("TextDocument"); textDocument.StartPoint.CreateEditPoint().Insert(text); openDocument.Save(); }; } var project = document.ProjectItem.ContainingProject; var ns = ((object)project.Properties.Item("DefaultNamespace").Value).ToString(); var projectDir = Path.GetDirectoryName(project.FullName); var fileDir = Path.GetDirectoryName(generatedFileName); if (fileDir.StartsWith(projectDir, StringComparison.OrdinalIgnoreCase)) { var relativePath = fileDir.Substring(projectDir.Length); ns += relativePath.Replace('\\', '.'); } try { var parser = new Parser(new Scanner(document.FullName)); parser.errors.errorStream = new StringWriter(); parser.Parse(); if (parser.errors.count != 0) { saveDocument(parser.errors.errorStream.ToString()); } else { var graphBuilder = new StateGraphBuilder(); var states = graphBuilder.BuildGraph(parser.Syntax); using (var output = new StringWriter()) { var generator = new CodeGenerator(); generator.GenerateCode(states.First(), output, string.Join(".", ns, parser.Syntax.Name), parser.Syntax.Usings, parser.Syntax.GenericArguments); saveDocument(output.ToString()); } } } catch (Exception err) { saveDocument(err.ToString()); } var fileAlreadyAdded = false; var projectItems = document.ProjectItem.ProjectItems; for (int i = 0; i < projectItems.Count; i++) { var item = (ProjectItem)projectItems.Item(i + 1); if (item.Document.FullName.Equals(generatedFileName, StringComparison.OrdinalIgnoreCase)) { fileAlreadyAdded = true; break; } } if (!fileAlreadyAdded) { projectItems.AddFromFile(generatedFileName); } } }
static int Main(string[] args) { string inputFile = null; string outputFile = null; string namespaceName = null; bool help = false; bool graph = false; bool compile = false; var options = new OptionSet { { "i|input=", v => inputFile = v }, { "o|output=", v => outputFile = v }, { "ns|namespace=", v => namespaceName = v }, { "g|graph", var => graph = true }, { "c|compile", var => compile = true }, { "h|?|help", v => help = true }, }; options.Parse(args); if (help) { var notice = @" This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. USAGE: "; System.Console.WriteLine(notice.Replace("\t", "")); options.WriteOptionDescriptions(System.Console.Out); return 2; } var parser = new Parser(inputFile != null ? new Scanner(inputFile) : new Scanner(System.Console.OpenStandardInput())); var previousConsoleColor = System.Console.ForegroundColor; System.Console.ForegroundColor = System.ConsoleColor.Red; parser.Parse(); System.Console.ForegroundColor = previousConsoleColor; if (parser.errors.count != 0) { return 1; } var graphBuilder = new StateGraphBuilder(); var states = graphBuilder.BuildGraph(parser.Syntax); var output = outputFile != null ? File.CreateText(outputFile) : System.Console.Out; if (graph) { GenerateStateGraph(states, output); } else if (compile) { var generator = new CodeGenerator(); var buffer = new StringWriter(); generator.GenerateCode(states.First(), buffer, namespaceName ?? parser.Syntax.Name, parser.Syntax.Usings, parser.Syntax.GenericArguments); var compiler = new CSharpCodeProvider(); var result = compiler.CompileAssemblyFromSource(new System.CodeDom.Compiler.CompilerParameters(new string[0], "temp.dll", true), new[] { buffer.ToString() }); foreach (var resultLine in result.Output) { output.WriteLine(resultLine); } output.WriteLine(); var reader = new StringReader(buffer.ToString()); int lineNumber = 0; string line; while ((line = reader.ReadLine()) != null) { output.WriteLine("{0}\t{1}", ++lineNumber, line); } } else { var generator = new CodeGenerator(); generator.GenerateCode(states.First(), output, namespaceName ?? parser.Syntax.Name, parser.Syntax.Usings, parser.Syntax.GenericArguments); } output.Flush(); output.Close(); return 0; }