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); }
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 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 NodeVisitorShouldEnumerateAllParseTrees() { ProductionExpression And = "AND", Panda = "Panda", AAn = "AAn", ShootsLeaves = "ShootsAndLeaves", EatsShootsLeaves = "EatsShootsLeaves" ; And.Rule = (Expr)'a' + 'n' + 'd'; var and = new GrammarExpression(And, new[] { And }).ToGrammar(); Panda.Rule = (Expr)'p' + 'a' + 'n' + 'd' + 'a'; var panda = new GrammarExpression(Panda, new[] { Panda }).ToGrammar(); AAn.Rule = (Expr)'a' | (Expr)'a' + 'n'; var aAn = new GrammarExpression(AAn, new[] { AAn }).ToGrammar(); ShootsLeaves.Rule = (Expr)"shoots" | (Expr)"leaves"; var shootsLeaves = new GrammarExpression(ShootsLeaves, new[] { ShootsLeaves }).ToGrammar(); EatsShootsLeaves.Rule = (Expr)'e' + 'a' + 't' + 's' | (Expr)'s' + 'h' + 'o' + 'o' + 't' + 's' | (Expr)'l' + 'e' + 'a' + 'v' + 'e' + 's'; var eatsShootsLeaves = new GrammarExpression(EatsShootsLeaves, new[] { EatsShootsLeaves }).ToGrammar(); ProductionExpression S = "S", NP = "NP", VP = "VP", NN = "NN", NNS = "NNS", DT = "DT", CC = "CC", VBZ = "VBZ"; S.Rule = NP + VP + '.'; NP.Rule = NN | NNS | DT + NN | NN + NNS | NNS + CC + NNS; VP.Rule = VBZ + NP | VP + VBZ + NNS | VP + CC + VP | VP + VP + CC + VP | VBZ; CC.Rule = new GrammarLexerRule(nameof(CC), and); DT.Rule = new GrammarLexerRule(nameof(DT), aAn); NN.Rule = new GrammarLexerRule(nameof(NN), panda); NNS.Rule = new GrammarLexerRule(nameof(NNS), shootsLeaves); VBZ.Rule = new GrammarLexerRule(nameof(VBZ), eatsShootsLeaves); var grammar = new GrammarExpression( S, new[] { S, NP, VP, CC, DT, NN, NNS, VBZ }, new[] { new LexerRuleModel(_whitespace) }) .ToGrammar(); var sentence = "a panda eats shoots and leaves."; var parseEngine = new ParseEngine(grammar); var parseRunner = new ParseRunner(parseEngine, sentence); while (!parseRunner.EndOfStream()) { Assert.IsTrue(parseRunner.Read(), $"Error parsing position: {parseRunner.Position}"); } Assert.IsTrue(parseRunner.ParseEngine.IsAccepted()); }