#pragma warning disable CC0091 // Use static method public EbnfDefinition Parse(string ebnf) { var grammar = new EbnfGrammar(); var parseEngine = new ParseEngine( grammar, new ParseEngineOptions( optimizeRightRecursion: true, loggingEnabled: false)); var parseRunner = new ParseRunner(parseEngine, ebnf); while (!parseRunner.EndOfStream()) { if (!parseRunner.Read()) { throw new Exception( $"Unable to parse Ebnf. Error at line {parseRunner.Line}, column {parseRunner.Column}."); } } if (!parseEngine.IsAccepted()) { throw new Exception( $"Ebnf parse not accepted. Error at line {parseRunner.Line}, column {parseRunner.Column}."); } var parseForest = parseEngine.GetParseForestRootNode(); var parseTree = new InternalTreeNode( parseForest as IInternalForestNode, new SelectFirstChildDisambiguationAlgorithm()); var ebnfVisitor = new EbnfVisitor(); parseTree.Accept(ebnfVisitor); return(ebnfVisitor.Definition); }
public void EbnfParserShouldParseComplexGrammarWithRepeat() { var stringBuilder = new StringBuilder() //.AppendLine("file = ws directives ws ;") .AppendLine("file = \"1\" { \"2\" } \"1\";"); //.AppendLine("directives = directive { ows directive };") //.AppendLine("directive = \"0\" | \"1\"; "); var actual = Parse(stringBuilder.ToString()); var grammar = new EbnfGrammar(); var parseEngine = new ParseEngine(grammar, new ParseEngineOptions(false)); var parseRunner = new ParseRunner(parseEngine, stringBuilder.ToString()); while (!parseRunner.EndOfStream()) { if (!parseRunner.Read()) { throw new Exception( $"Unable to parse Ebnf. Error at position {parseRunner.Position}."); } } if (!parseEngine.IsAccepted()) { throw new Exception( $"Unable to parse Ebnf. Error at position {parseRunner.Position}"); } var parseForest = parseEngine.GetParseForestRootNode(); var visitor = new LoggingForestNodeVisitor(Console.Out); parseForest.Accept(visitor); }
public Regex Parse(string regularExpression) { var grammar = new RegexGrammar(); var parseEngine = new ParseEngine(grammar, new ParseEngineOptions(optimizeRightRecursion: true)); var parseRunner = new ParseRunner(parseEngine, regularExpression); while (!parseRunner.EndOfStream()) { if (!parseRunner.Read()) { throw new Exception( $"Unable to parse regular expression. Error at position {parseRunner.Position}."); } } if (!parseEngine.IsAccepted()) { throw new Exception( $"Error parsing regular expression. Error at position {parseRunner.Position}"); } var parseForest = parseEngine.GetParseForestRootNode(); var parseTree = new InternalTreeNode( parseForest as IInternalForestNode, new SelectFirstChildDisambiguationAlgorithm()); var regexVisitor = new RegexVisitor(); parseTree.Accept(regexVisitor); return(regexVisitor.Regex); }
public void ParseEngineWhenScanCompletedShouldCreateInternalAndTerminalNodes() { ProductionExpression S = "S"; S.Rule = (Expr)'a'; var grammar = new GrammarExpression(S, new[] { S }) .ToGrammar(); var tokens = Tokenize("a"); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, tokens); var parseNode = parseEngine.GetParseForestRootNode(); Assert.IsNotNull(parseNode); var S_0_1 = parseNode as ISymbolForestNode; Assert.IsNotNull(S_0_1); Assert.AreEqual(1, S_0_1.Children.Count); var S_0_1_1 = S_0_1.Children[0] as IAndForestNode; Assert.IsNotNull(S_0_1_1); Assert.AreEqual(1, S_0_1_1.Children.Count); var a_0_1 = S_0_1_1.Children[0] as ITokenForestNode; Assert.IsNotNull(a_0_1); Assert.AreEqual("a", a_0_1.Token.Value); }
public void ParseEngineShouldHandleTransitionsFromRightRecursionToNormalGrammar() { var grammar = CreateRegularExpressionStubGrammar(); var input = Tokenize("aaaa"); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, input); // R_0_7 -> E_0_7 // E_0_7 -> T_0_7 // T_0_7 -> F_0_1 T_1_7 // F_0_1 -> 'a' // T_1_7 -> F_1_2 T_2_7 // F_1_2 -> 'a' // T_2_7 -> F_2_3 T_3_7 // F_2_3 -> 'a' // T_3_7 -> F_3_4 T_4_7 // F_3_4 -> 'a' // T_4_7 -> F_4_5 T_5_7 // F_4_5 -> 'a' // T_5_7 -> F_5_6 T_6_7 // F_5_6 -> 'a' // T_6_7 -> F_6_7 // F_6_7 -> 'a' var parseForestRoot = parseEngine.GetParseForestRootNode(); var root = parseForestRoot; var R_0_4 = CastAndCountChildren <ISymbolForestNode>(root, 1); AssertNodeProperties(R_0_4, "R", 0, 4); var E_0_4 = GetAndCastChildAtIndex <ISymbolForestNode>(R_0_4, 0); AssertNodeProperties(E_0_4, "E", 0, 4); var T_0_4 = GetAndCastChildAtIndex <ISymbolForestNode>(E_0_4, 0); AssertNodeProperties(T_0_4, "T", 0, 4); var F_0_1 = GetAndCastChildAtIndex <ISymbolForestNode>(T_0_4, 0); AssertNodeProperties(F_0_1, "F", 0, 1); var T_1_4 = GetAndCastChildAtIndex <ISymbolForestNode>(T_0_4, 1); AssertNodeProperties(T_1_4, "T", 1, 4); var F_1_2 = GetAndCastChildAtIndex <ISymbolForestNode>(T_1_4, 0); AssertNodeProperties(F_1_2, "F", 1, 2); var T_2_4 = GetAndCastChildAtIndex <ISymbolForestNode>(T_1_4, 1); AssertNodeProperties(T_2_4, "T", 2, 4); var F_2_4 = GetAndCastChildAtIndex <ISymbolForestNode>(T_2_4, 0); AssertNodeProperties(F_2_4, "F", 2, 3); var T_3_4 = GetAndCastChildAtIndex <ISymbolForestNode>(T_2_4, 1); AssertNodeProperties(T_3_4, "T", 3, 4); var F_3_4 = GetAndCastChildAtIndex <ISymbolForestNode>(T_3_4, 0); AssertNodeProperties(F_3_4, "F", 3, 4); }
public static void Main(string[] args) { string grammarText = LoadFromResource(nameof(DefaultNamespaceName), "Grammar", "syntax5.ebnf"); //string input = File.ReadAllText("/etc/apache2/httpd.conf", Encoding.UTF8); string input = "1 1"; var definition = new EbnfParser().Parse(grammarText); var grammar = new EbnfGrammarGenerator().Generate(definition); var parseEngine = new ParseEngine(grammar); var parseRunner = new ParseRunner(parseEngine, input); var recognized = false; var errorPosition = 0; while (!parseRunner.EndOfStream()) { recognized = parseRunner.Read(); if (!recognized) { errorPosition = parseRunner.Position; break; } } var accepted = false; if (recognized) { accepted = parseRunner.ParseEngine.IsAccepted(); if (!accepted) { errorPosition = parseRunner.Position; } } Console.WriteLine($"Recognized: {recognized}, Accepted: {accepted}"); if (!recognized || !accepted) { Console.Error.WriteLine($"Error at position {errorPosition}"); } // get the parse forest root from the parse engine var parseForestRoot = parseEngine.GetParseForestRootNode(); // create a internal tree node and supply the disambiguation algorithm for tree traversal. var parseTree = new InternalTreeNode( parseForestRoot, new SelectFirstChildDisambiguationAlgorithm()); Console.WriteLine(parseTree.ToString()); }
public void ParseEngineGivenAmbiguousNullableRightRecursionShouldCreateMultipleParsePaths() { // example 1 section 3, Elizabeth Scott var tokens = Tokenize("aa"); ProductionExpression S = "S", T = "T", B = "B"; S.Rule = (S + T) | "a"; B.Rule = null; T.Rule = ("a" + B) | "a"; var grammar = new GrammarExpression(S, new[] { S, T, B }).ToGrammar(); var parseEngine = new ParseEngine(grammar, new ParseEngineOptions(false)); ParseInput(parseEngine, tokens); var parseForestRoot = parseEngine.GetParseForestRootNode(); var actual = parseForestRoot; var a_1_2 = new TokenForestNode(MakeToken("a", 1)); var expected = new SymbolForestNode( S.ProductionModel.LeftHandSide.NonTerminal, 0, 2, new AndForestNode( new SymbolForestNode( S.ProductionModel.LeftHandSide.NonTerminal, 0, 1, new AndForestNode(new TokenForestNode(MakeToken("a", 0)))), new SymbolForestNode( T.ProductionModel.LeftHandSide.NonTerminal, 1, 2, new AndForestNode(a_1_2), new AndForestNode( a_1_2, new SymbolForestNode( B.ProductionModel.LeftHandSide.NonTerminal, 2, 2, new AndForestNode(new SymbolForestNode(B.ProductionModel.LeftHandSide.NonTerminal, 2, 2))))))); AssertForestsAreEqual(expected, actual); }
private static void AssertLeoAndClassicParseAlgorithmsCreateSameForest(IEnumerable <IToken> tokens, IGrammar grammar) { var leoEngine = new ParseEngine(grammar); var classicEngine = new ParseEngine(grammar, new ParseEngineOptions(optimizeRightRecursion: false)); Assert.IsTrue(RunParse(leoEngine, tokens), "Leo Parse Failed"); Assert.IsTrue(RunParse(classicEngine, tokens), "Classic Parse Failed"); var nodeComparer = new StatefulForestNodeComparer(); var leoParseForestRoot = leoEngine.GetParseForestRootNode(); var classicParseForestRoot = classicEngine.GetParseForestRootNode(); Assert.IsTrue(nodeComparer.Equals( classicParseForestRoot, leoParseForestRoot), "Leo and Classic Parse Forest mismatch"); }
public void ParseEnginePredicationShouldCreateInternalNode() { ProductionExpression S = "S", A = "A"; S.Rule = (Expr)A; A.Rule = (Expr)'a'; var grammar = new GrammarExpression(S, new[] { S, A }).ToGrammar(); var tokens = Tokenize("a"); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, tokens); /* S_0_1 -> A_0_1 * A_0_1 -> 'a' */ var S_0_1 = parseEngine.GetParseForestRootNode() as ISymbolForestNode; Assert.IsNotNull(S_0_1); Assert.AreEqual(1, S_0_1.Children.Count); var S_0_1_1 = S_0_1.Children[0] as IAndForestNode; Assert.IsNotNull(S_0_1_1); Assert.AreEqual(1, S_0_1_1.Children.Count); var A_0_1 = S_0_1_1.Children[0] as ISymbolForestNode; Assert.IsNotNull(A_0_1); Assert.AreEqual(1, A_0_1.Children.Count); var A_0_1_1 = A_0_1.Children[0] as IAndForestNode; Assert.IsNotNull(A_0_1_1); Assert.AreEqual(1, A_0_1_1.Children.Count); var a_0_1 = A_0_1_1.Children[0] as ITokenForestNode; Assert.IsNotNull(a_0_1); Assert.AreEqual("a", a_0_1.Token.Value); }
private static void AssertLeoAndClassicParseAlgorithmsCreateSameForest(string input, IGrammar grammar) { var leoEngine = new ParseEngine(grammar); var classicEngine = new ParseEngine(grammar, new ParseEngineOptions(optimizeRightRecursion: false)); var leoTester = new ParseTester(leoEngine); var classicTester = new ParseTester(classicEngine); leoTester.RunParse(input); classicTester.RunParse(input); var nodeComparer = new StatefulForestNodeComparer(); var leoParseForestRoot = leoEngine.GetParseForestRootNode(); var classicParseForestRoot = classicEngine.GetParseForestRootNode(); Assert.IsTrue(nodeComparer.Equals( classicParseForestRoot, leoParseForestRoot), "Leo and Classic Parse Forest mismatch"); }
private static InternalTreeNode GetTreeNode(Grammar grammar, string input) { var parseEngine = new ParseEngine(grammar); var parseRunner = new ParseRunner(parseEngine, input); while (!parseRunner.EndOfStream()) { Assert.IsTrue(parseRunner.Read()); } Assert.IsTrue(parseEngine.IsAccepted()); var parseForest = parseEngine.GetParseForestRootNode(); Assert.IsNotNull(parseForest); var internalNode = parseForest; var treeNode = new InternalTreeNode(internalNode); return(treeNode); }
public void ParseEngineWhenMultipleLeoItemsExistOnSearchPathShouldCreateCorrectParseTree() { var grammar = CreateRegularExpressionStubGrammar(); var input = Tokenize("aaa"); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, input); var parseForestRoot = parseEngine.GetParseForestRootNode(); var parseForest = parseForestRoot; var R_0_3 = CastAndCountChildren <ISymbolForestNode>(parseForest, 1); AssertNodeProperties(R_0_3, "R", 0, 3); var E_0_3 = GetAndCastChildAtIndex <ISymbolForestNode>(R_0_3, 0); AssertNodeProperties(E_0_3, "E", 0, 3); var T_0_3 = GetAndCastChildAtIndex <ISymbolForestNode>(E_0_3, 0); AssertNodeProperties(T_0_3, "T", 0, 3); var F_0_1 = GetAndCastChildAtIndex <ISymbolForestNode>(T_0_3, 0); AssertNodeProperties(F_0_1, "F", 0, 1); var A_0_1 = GetAndCastChildAtIndex <ISymbolForestNode>(F_0_1, 0); AssertNodeProperties(A_0_1, "A", 0, 1); var T_1_3 = GetAndCastChildAtIndex <ISymbolForestNode>(T_0_3, 1); AssertNodeProperties(T_1_3, "T", 1, 3); var F_1_2 = GetAndCastChildAtIndex <ISymbolForestNode>(T_1_3, 0); AssertNodeProperties(F_1_2, "F", 1, 2); var T_2_3 = GetAndCastChildAtIndex <ISymbolForestNode>(T_1_3, 1); AssertNodeProperties(T_2_3, "T", 2, 3); var F_2_3 = GetAndCastChildAtIndex <ISymbolForestNode>(T_2_3, 0); AssertNodeProperties(F_2_3, "F", 2, 3); }
private static InternalTreeNode GetTreeNode(IGrammar grammar, string input) { var parseEngine = new ParseEngine(grammar); var parseRunner = new ParseRunner(parseEngine, input); while (!parseRunner.EndOfStream()) { Assert.IsTrue(parseRunner.Read()); } Assert.IsTrue(parseEngine.IsAccepted()); var parseForest = parseEngine.GetParseForestRootNode(); Assert.IsTrue(parseForest is IInternalForestNode); var internalNode = parseForest as IInternalForestNode; var disambiguationAlgorithm = new SelectFirstChildDisambiguationAlgorithm(); var treeNode = new InternalTreeNode(internalNode, disambiguationAlgorithm); return(treeNode); }
public void NodeVisitorShouldWalkSimpleRegex() { var regexGrammar = new RegexGrammar(); var regexParseEngine = new ParseEngine(regexGrammar); var regexLexer = new ParseRunner(regexParseEngine, @"[(]\d[)]"); while (!regexLexer.EndOfStream()) { if (!regexLexer.Read()) { Assert.Fail($"error parsing input at position {regexLexer.Position}"); } } Assert.IsTrue(regexParseEngine.IsAccepted()); var nodeVisitor = new LoggingNodeVisitor( new SelectFirstChildDisambiguationAlgorithm()); var root = regexParseEngine.GetParseForestRootNode(); root.Accept(nodeVisitor); Assert.AreEqual(31, nodeVisitor.VisitLog.Count); }
public void ParseEngineGivenLongProductionRuleShouldCreateCorrectParseTree() { ProductionExpression S = "S", A = "A", B = "B", C = "C", D = "D"; S.Rule = (Expr) A + B + C + D + S | '|'; A.Rule = 'a'; B.Rule = 'b'; C.Rule = 'c'; D.Rule = 'd'; var grammar = new GrammarExpression(S, new[] { S, A, B, C, D }).ToGrammar(); var input = Tokenize("abcdabcdabcdabcd|"); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, input); var parseForestRoot = parseEngine.GetParseForestRootNode(); var pasreForestNode = parseForestRoot; var S_0_17 = CastAndCountChildren <ISymbolForestNode>(pasreForestNode, 2); }
public void ParseEngineLeoItemsShouldGenerateProperParseTree() { ProductionExpression S = "S", A = "A"; S.Rule = A; A.Rule = 'a' + A | 'b'; var grammar = new GrammarExpression(S, new[] { S, A }).ToGrammar(); var tokens = Tokenize("ab"); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, tokens); /* S_0_2 -> A_0_2 * A_0_2 -> a_0_1 A_1_2 * A_1_2 -> b_1_2 */ var parseForestRoot = parseEngine.GetParseForestRootNode(); var root = parseForestRoot; var S_0_2 = root as ISymbolForestNode; Assert.IsNotNull(S_0_2); Assert.AreEqual(1, S_0_2.Children.Count); var S_0_2_1 = S_0_2.Children[0] as IAndForestNode; Assert.IsNotNull(S_0_2_1); Assert.AreEqual(1, S_0_2_1.Children.Count); var A_0_2 = S_0_2_1.Children[0] as ISymbolForestNode; Assert.IsNotNull(A_0_2); Assert.AreEqual(1, A_0_2.Children.Count); var A_0_2_1 = A_0_2.Children[0] as IAndForestNode; Assert.IsNotNull(A_0_2_1); Assert.AreEqual(2, A_0_2_1.Children.Count); var a_0_1 = A_0_2_1.Children[0] as ITokenForestNode; Assert.IsNotNull(a_0_1); Assert.AreEqual("a", a_0_1.Token.Value); var A_1_2 = A_0_2_1.Children[1] as ISymbolForestNode; Assert.IsNotNull(A_1_2); Assert.AreEqual(1, A_1_2.Children.Count); var A_1_2_1 = A_1_2.Children[0] as IAndForestNode; Assert.IsNotNull(A_1_2_1); Assert.AreEqual(1, A_1_2_1.Children.Count); var b_1_2 = A_1_2_1.Children[0] as ITokenForestNode; Assert.IsNotNull(b_1_2); Assert.AreEqual("b", b_1_2.Token.Value); }
public void ParseEnginePassThroughRecursiveItemsShouldCreateVirtualNodes() { ProductionExpression S = "S", A = "A", B = "B"; S.Rule = A; A.Rule = 'a' + B; B.Rule = A | 'b'; var grammar = new GrammarExpression(S, new[] { S, A, B }).ToGrammar(); var tokens = Tokenize("aaab"); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, tokens); /* S_0_4 -> A_0_4 * A_0_4 -> 'a' B_1_4 * B_1_4 -> A_1_4 * A_1_4 -> 'a' B_2_4 * B_2_4 -> A_2_4 * A_2_4 -> 'a' B_3_4 * B_3_4 -> 'b' */ var parseForestRoot = parseEngine.GetParseForestRootNode(); var root = parseForestRoot; var S_0_4 = root as ISymbolForestNode; Assert.IsNotNull(S_0_4); Assert.AreEqual(1, S_0_4.Children.Count); var S_0_4_1 = S_0_4.Children[0] as IAndForestNode; Assert.IsNotNull(S_0_4_1); Assert.AreEqual(1, S_0_4_1.Children.Count); var A_0_4 = S_0_4_1.Children[0] as ISymbolForestNode; Assert.IsNotNull(A_0_4); Assert.AreEqual(1, A_0_4.Children.Count); var A_0_4_1 = A_0_4.Children[0] as IAndForestNode; Assert.IsNotNull(A_0_4_1); Assert.AreEqual(2, A_0_4_1.Children.Count); var a_0_1 = A_0_4_1.Children[0] as ITokenForestNode; Assert.IsNotNull(a_0_1); Assert.AreEqual("a", a_0_1.Token.Value); var B_1_4 = A_0_4_1.Children[1] as ISymbolForestNode; Assert.IsNotNull(B_1_4); Assert.AreEqual(1, B_1_4.Children.Count); var B_1_4_1 = B_1_4.Children[0] as IAndForestNode; Assert.IsNotNull(B_1_4_1); Assert.AreEqual(1, B_1_4_1.Children.Count); var A_1_4 = B_1_4_1.Children[0] as ISymbolForestNode; Assert.IsNotNull(A_1_4); Assert.AreEqual(1, A_1_4.Children.Count); var A_1_4_1 = A_1_4.Children[0] as IAndForestNode; Assert.IsNotNull(A_1_4_1); Assert.AreEqual(2, A_1_4_1.Children.Count); var a_1_2 = A_1_4_1.Children[0] as ITokenForestNode; Assert.IsNotNull(a_1_2); Assert.AreEqual("a", a_1_2.Token.Value); var B_2_4 = A_1_4_1.Children[1] as ISymbolForestNode; Assert.IsNotNull(B_2_4); Assert.AreEqual(1, B_2_4.Children.Count); var B_2_4_1 = B_2_4.Children[0] as IAndForestNode; Assert.IsNotNull(B_2_4_1); Assert.AreEqual(1, B_2_4_1.Children.Count); var A_2_4 = B_2_4_1.Children[0] as ISymbolForestNode; Assert.IsNotNull(A_2_4); Assert.AreEqual(1, A_2_4.Children.Count); var A_2_4_1 = A_2_4.Children[0] as IAndForestNode; Assert.IsNotNull(A_2_4_1); Assert.AreEqual(2, A_2_4_1.Children.Count); var a_2_3 = A_2_4_1.Children[0] as ITokenForestNode; Assert.IsNotNull(a_2_3); Assert.AreEqual("a", a_2_3.Token.Value); var B_3_4 = A_2_4_1.Children[1] as ISymbolForestNode; Assert.IsNotNull(B_3_4); Assert.AreEqual(1, B_3_4.Children.Count); var B_3_4_1 = B_3_4.Children[0] as IAndForestNode; Assert.IsNotNull(B_3_4_1); Assert.AreEqual(1, B_3_4_1.Children.Count); var b_3_4 = B_3_4_1.Children[0] as ITokenForestNode; Assert.IsNotNull(b_3_4); Assert.AreEqual("b", b_3_4.Token.Value); }
public void ParseEngineShouldParseMidGrammarRightRecursionAndHandleNullRootTransitionItem() { ProductionExpression S = "S", A = "A", B = "B", C = "C"; S.Rule = (Expr)A | A + S; A.Rule = (Expr)B | B + C; B.Rule = (Expr)'.'; C.Rule = (Expr)'+' | '?' | '*'; var grammar = new GrammarExpression(S, new[] { S, A, B, C }).ToGrammar(); var tokens = Tokenize(".+"); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, tokens); var parseForestRoot = parseEngine.GetParseForestRootNode(); var parseForest = parseForestRoot; Assert.IsNotNull(parseForest); // S_0_2 -> A_0_2 // A_0_2 -> B_0_1 C_1_2 // B_0_1 -> '.'_0_1 // C_1_2 -> '+'_1_2 var S_0_2 = parseForest as ISymbolForestNode; Assert.IsNotNull(S_0_2); Assert.AreEqual(1, S_0_2.Children.Count); var S_0_2_1 = S_0_2.Children[0] as IAndForestNode; Assert.IsNotNull(S_0_2_1); Assert.AreEqual(1, S_0_2_1.Children.Count); var A_0_2 = S_0_2_1.Children[0] as ISymbolForestNode; Assert.IsNotNull(A_0_2); Assert.AreEqual(1, A_0_2.Children.Count); var A_0_2_1 = A_0_2.Children[0] as IAndForestNode; Assert.IsNotNull(A_0_2_1); Assert.AreEqual(2, A_0_2_1.Children.Count); var B_0_1 = A_0_2_1.Children[0] as ISymbolForestNode; Assert.IsNotNull(B_0_1); Assert.AreEqual(1, B_0_1.Children.Count); var B_0_1_1 = B_0_1.Children[0] as IAndForestNode; Assert.IsNotNull(B_0_1_1); Assert.AreEqual(1, B_0_1_1.Children.Count); var dot_0_1 = B_0_1_1.Children[0] as ITokenForestNode; Assert.IsNotNull(dot_0_1); Assert.AreEqual(".", dot_0_1.Token.Value); var C_1_2 = A_0_2_1.Children[1] as ISymbolForestNode; Assert.IsNotNull(C_1_2); var C_1_2_1 = C_1_2.Children[0] as IAndForestNode; Assert.IsNotNull(C_1_2_1); Assert.AreEqual(1, C_1_2_1.Children.Count); var plus_1_2 = C_1_2_1.Children[0] as ITokenForestNode; Assert.IsNotNull(plus_1_2); Assert.AreEqual("+", plus_1_2.Token.Value); }
public void ParseEngineGivenAmbiguousGrammarShouldCreateMulipleParsePaths() { // example 3 section 4, Elizabeth Scott var tokens = Tokenize("abbb"); ProductionExpression B = "B", S = "S", T = "T", A = "A"; S.Rule = (Expr)A + T | 'a' + T; A.Rule = (Expr)'a' | B + A; B.Rule = null; T.Rule = (Expr)'b' + 'b' + 'b'; var grammar = new GrammarExpression(S, new[] { S, A, B, T }) .ToGrammar(); var parseEngine = new ParseEngine(grammar); ParseInput(parseEngine, tokens); var S_0_4 = parseEngine.GetParseForestRootNode() as ISymbolForestNode; Assert.IsNotNull(S_0_4); AssertNodeProperties(S_0_4, nameof(S), 0, 4); Assert.AreEqual(2, S_0_4.Children.Count); var S_0_4_1 = S_0_4.Children[0] as IAndForestNode; Assert.IsNotNull(S_0_4_1); Assert.AreEqual(2, S_0_4_1.Children.Count); var a_0_1 = S_0_4_1.Children[0] as ITokenForestNode; Assert.IsNotNull(a_0_1); Assert.AreEqual("a", a_0_1.Token.Value); var T_1_4 = S_0_4_1.Children[1] as ISymbolForestNode; Assert.IsNotNull(T_1_4); AssertNodeProperties(T_1_4, nameof(T), 1, 4); Assert.AreEqual(1, T_1_4.Children.Count); var S_0_4_2 = S_0_4.Children[1] as IAndForestNode; Assert.IsNotNull(S_0_4_2); Assert.AreEqual(2, S_0_4_2.Children.Count); var A_0_1 = S_0_4_2.Children[0] as ISymbolForestNode; Assert.IsNotNull(A_0_1); AssertNodeProperties(A_0_1, nameof(A), 0, 1); Assert.AreEqual(2, A_0_1.Children.Count); var A_0_1_1 = A_0_1.Children[0] as IAndForestNode; Assert.IsNotNull(A_0_1_1); Assert.AreEqual(1, A_0_1_1.Children.Count); Assert.AreSame(a_0_1, A_0_1_1.Children[0]); var A_0_1_2 = A_0_1.Children[1] as IAndForestNode; Assert.IsNotNull(A_0_1_1); Assert.AreEqual(2, A_0_1_2.Children.Count); Assert.AreSame(A_0_1, A_0_1_2.Children[1]); var B_0_0 = A_0_1_2.Children[0] as ISymbolForestNode; Assert.IsNotNull(B_0_0); AssertNodeProperties(B_0_0, nameof(B), 0, 0); Assert.AreEqual(1, B_0_0.Children.Count); var B_0_0_1 = B_0_0.Children[0] as IAndForestNode; Assert.IsNotNull(B_0_0_1); Assert.AreEqual(1, B_0_0_1.Children.Count); var nullToken = B_0_0_1.Children[0] as ITokenForestNode; Assert.IsNotNull(nullToken); Assert.AreEqual(string.Empty, nullToken.Token.Value); var T_1_4_1 = T_1_4.Children[0] as IAndForestNode; Assert.IsNotNull(T_1_4_1); Assert.AreEqual(2, T_1_4_1.Children.Count); var T_1_3 = T_1_4_1.Children[0] as IIntermediateForestNode; Assert.IsNotNull(T_1_3); Assert.AreEqual(1, T_1_3.Children.Count); var b_3_4 = T_1_4_1.Children[1] as ITokenForestNode; Assert.IsNotNull(b_3_4); Assert.AreEqual("b", b_3_4.Token.Value); var T_1_3_1 = T_1_3.Children[0] as IAndForestNode; Assert.IsNotNull(T_1_3_1); Assert.AreEqual(2, T_1_3_1.Children.Count); var b_1_2 = T_1_3_1.Children[0] as ITokenForestNode; Assert.IsNotNull(b_1_2); Assert.AreEqual("b", b_1_2.Token.Value); var b_2_3 = T_1_3_1.Children[1] as ITokenForestNode; Assert.IsNotNull(b_2_3); Assert.AreEqual("b", b_2_3.Token.Value); }