コード例 #1
0
ファイル: EbnfParser.cs プロジェクト: DinkDev/Pliant
#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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }
コード例 #5
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }
コード例 #6
0
    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());
    }
コード例 #7
0
        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);
        }
コード例 #8
0
        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");
        }
コード例 #9
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }
コード例 #10
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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");
        }
コード例 #11
0
        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);
        }
コード例 #12
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }
コード例 #13
0
ファイル: TreeNodeTests.cs プロジェクト: patrickhuber/Pliant
        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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }
コード例 #16
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }
コード例 #17
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }
コード例 #18
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }
コード例 #19
0
ファイル: ParseEngineTests.cs プロジェクト: DinkDev/Pliant
        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);
        }