/// <summary>Read a Grammar definition from text. </summary> /// <param name="Grammar">Grammar text.</param> /// <returns>Grammar is Ok.</returns> /// <exclude/> private void SetGrammar(string Grammar) { CodeDocument grammarDoc = null; TextBuffer buffer = new FlatBuffer(Grammar); grammarDoc = MetaParser.Instance.ParseString(buffer); if (buffer.Status.Error != null || !ParserBuilder.BuildRules(this, grammarDoc, buffer.Status)) { // only place to throw exception is CodeDocument.Load and Parser.SetGrammar (and MetaGrammar) var error = new ParserException(buffer.Status.Error.Message); error.AllErrors.AddRange(buffer.Status.AllErrors); throw error; } }
/// <summary> /// Parse code with a given parser. /// </summary> /// <param name="parser"></param> /// <param name="input"></param> /// <returns></returns> public static CodeDocument Load(Parser parser, string input) { TextBuffer buffer = new FlatBuffer(input); CodeDocument doc = parser.ParseString(buffer); if (doc != null) { return(doc); } // only place to throw exception is CodeDocument.Load and Parser.SetGrammar (and MetaGrammar) var error = new ParserException(buffer.Status.Error.Message); error.AllErrors.AddRange(buffer.Status.AllErrors); throw error; }
// https://msdn.microsoft.com/en-us/library/bb675186(v=vs.110).aspx /* * string xslMarkup = @"<?xml version='1.0'?> * <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'> * <xsl:template match='/Parent'> * <Root> * <C1> * <xsl:value-of select='Child1'/> * </C1> * <C2> * <xsl:value-of select='Child2'/> * </C2> * </Root> * </xsl:template> * </xsl:stylesheet>"; * * XDocument xmlTree = new XDocument( * new XElement("Parent", * new XElement("Child1", "Child1 data"), * new XElement("Child2", "Child2 data") * ) * ); * * XDocument newTree = new XDocument(); * using (XmlWriter writer = newTree.CreateWriter()) { * // Load the style sheet. * XslCompiledTransform xslt = new XslCompiledTransform(); * xslt.Load(XmlReader.Create(new StringReader(xslMarkup))); * * // Execute the transform and output the results to a writer. * xslt.Transform(xmlTree.CreateReader(), writer); * } */ /// <summary>Compare two TextDocuments. Only elements in the 'expect' document are compared.</summary> /// <returns>Empty string if equal. Message with path if different.</returns> /// <exclude/> internal static string CompareCode(CodeDocument actual, CodeDocument expect) { string msg; if (expect == null && actual == null) { return(string.Empty); } if (expect == null) { return("Expected doc is null"); } if (actual == null) { return("Actual doc is null"); } if (actual.ChildNodes == null && expect.ChildNodes == null) { return(string.Empty); } if (expect == null || expect.ChildNodes == null) { return("Expected doc has no elements"); } if (actual == null || actual.ChildNodes == null) { return("Actual doc has no elements"); } foreach (TextElement xpct in expect.ChildNodes) { TextElement actualElement = actual.ChildNodes.FirstOrDefault(n => n.Name == xpct.Name && GetRuleName(n) == GetRuleName(xpct)); if (actualElement == null) { return(string.Format("Actual element '{0}', '{1}' is missing", xpct.Name, GetRuleName(xpct))); } msg = CompareElement(actualElement, xpct, string.Format("{0}[{1}]", xpct.Name, GetRuleName(xpct))); if (!string.IsNullOrEmpty(msg)) { return(msg); } } return(string.Empty); }
/// <summary>Read from a text buffer and create a text document.</summary> /// <param name="buffer">The text buffer.</param> /// <returns>A text document, or null if error.</returns> /// <exclude/> internal CodeDocument ParseString(TextBuffer buffer) { if (buffer.Status.Error != null) { return(null); } List <Rule> procesRules = Rules.Select(r => r.CloneForParse(buffer) as Rule).ToList(); if (!ParserBuilder.InitializeGrammar(this, procesRules, buffer.Status)) { return(null); } var elements = new List <TextElement>(); bool ok; var resultDoc = new CodeDocument(elements, procesRules[0].Name); try { // skip preceding white spaces and comments buffer.FindNextWord(resultDoc.ChildNodes, false); //buffer.InsertComments(elements); ok = procesRules[0].Load(elements, 0); buffer.FindNextWord(elements, false); //buffer.InsertComments(elements); } catch (Exception e) { buffer.Status.AddException(e, () => MessageRes.itc12, e.Message); return(null); } if (buffer.Status.Error != null) { return(null); } if (!ok) { buffer.Status.AddParseError(() => MessageRes.itc12, procesRules[0].Name); } else if (!buffer.IsEnd()) { if (elements != null && elements.Count() > 0) { CodeElement last = elements.OfType <CodeElement>().Last(); string debug = last.ToMarkupProtected(string.Empty); buffer.GetLoopLast(null); procesRules[0].ResolveErrorsLast(last, 0); } buffer.Status.AddSyntaxErrorEof(() => MessageRes.itc13); } else if (elements.OfType <CodeElement>().Count() == 1) { resultDoc.AddRange(elements.OfType <CodeElement>().First().ChildNodes); resultDoc.AddRange(elements.OfType <CommentElement>()); return(resultDoc); } else { buffer.Status.AddParseError(() => MessageRes.itc20, procesRules[0].Name); } return(null); }