public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress) { pcbOutput = 0; try { ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.Progress(0, 4); var hasErrors = false; using (var stm = new MemoryStream()) { EbnfDocument ebnf = null; try { ebnf = EbnfDocument.ReadFrom(wszInputFilePath); } catch (ExpectingException ee) { hasErrors = true; ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.GeneratorError(0, 0, "Error parsing the EBNF: " + ee.Message, (uint)ee.Line - 1, (uint)ee.Column - 1); } ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.Progress(1, 4); foreach (var msg in ebnf.Validate(false)) { switch (msg.ErrorLevel) { case EbnfErrorLevel.Error: ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.GeneratorError(0, 0, "EBNF " + msg.Message, (uint)msg.Line - 1, (uint)msg.Column - 1); hasErrors = true; break; case EbnfErrorLevel.Warning: ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.GeneratorError(1, 0, "EBNF " + msg.Message, (uint)msg.Line - 1, (uint)msg.Column - 1); break; } } ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.Progress(3, 4); var cfg = ebnf.ToCfg(); foreach (var msg in cfg.PrepareLL1(false)) { switch (msg.ErrorLevel) { case CfgErrorLevel.Error: ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.GeneratorError(0, 0, "CFG " + msg.Message, 0, 0); hasErrors = true; break; case CfgErrorLevel.Warning: ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.GeneratorError(1, 0, "CFG " + msg.Message, 0, 0); break; } } if (!hasErrors) { var sw = new StreamWriter(stm); LLCodeGenerator.WriteParserAndGeneratorClassesTo(ebnf, cfg, wszDefaultNamespace, null, Path.GetFileNameWithoutExtension(wszInputFilePath), "cs", sw); sw.Flush(); int length = (int)stm.Length; rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(length); Marshal.Copy(stm.GetBuffer(), 0, rgbOutputFileContents[0], length); pcbOutput = (uint)length; } ThreadHelper.ThrowIfNotOnUIThread(); pGenerateProgress.Progress(4, 4); } } catch (Exception ex) { string s = string.Concat("/* ", ex.Message, " */"); byte[] b = Encoding.UTF8.GetBytes(s); int length = b.Length; rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(length); Marshal.Copy(b, 0, rgbOutputFileContents[0], length); pcbOutput = (uint)length; } return(VSConstants.S_OK); }
static int Main(string[] args) { string grammarFile = null; string outFile = null; string @namespace = null; string language = null; // "c#"; var optIndex = -1; for (var i = 0; i < args.Length; ++i) { if ("--help" == args[i] || "/?" == args[i] || "/help" == args[i]) { _PrintUsage(); return(0); } if (args[i].StartsWith("/")) { optIndex = i; if (i == args.Length - 1) { _PrintUsage(); return(1); } switch (args[i]) { case "/language": ++i; language = args[i]; break; case "/namespace": ++i; @namespace = args[i]; break; default: _PrintUsage(); return(1); } } else { if (-1 != optIndex) { _PrintUsage(); return(1); } if (0 == i) { grammarFile = args[i]; } else if (1 == i) { outFile = args[i]; } else { _PrintUsage(); return(1); } } } string inp; if (string.IsNullOrEmpty(grammarFile)) { inp = Console.In.ReadToEnd(); } else { using (var sr = File.OpenText(grammarFile)) inp = sr.ReadToEnd(); } var ebnf = EbnfDocument.Parse(inp); var hasErrors = false; foreach (var msg in ebnf.Validate(false)) { Console.Error.WriteLine(string.Concat("EBNF ", msg.ToString())); if (EbnfErrorLevel.Error == msg.ErrorLevel) { hasErrors = true; } } var cfg = ebnf.ToCfg(); foreach (var msg in cfg.PrepareLL1(false)) { Console.Error.WriteLine(string.Concat("CFG ", msg.ToString())); if (CfgErrorLevel.Error == msg.ErrorLevel) { hasErrors = true; } } Console.Error.WriteLine(); Console.Error.WriteLine(cfg); if (!hasErrors) { if (!string.IsNullOrEmpty(outFile)) { if (null == language) { language = Path.GetExtension(outFile).Substring(1); if ("" == language) { language = null; } } using (var fw = new StreamWriter(File.Open(outFile, FileMode.OpenOrCreate))) { fw.BaseStream.SetLength(0); LLCodeGenerator.WriteParserAndGeneratorClassesTo(ebnf, cfg, @namespace, inp, Path.GetFileNameWithoutExtension(outFile), language, fw); } } else { LLCodeGenerator.WriteParserAndGeneratorClassesTo(ebnf, cfg, @namespace, inp, cfg.StartSymbol, language, Console.Out); } return(0); } return(1); }