public void AycockHorspoolAlgorithmShouldAcceptVulnerableGrammar()
        {
            var a = new TerminalLexerRule(
                new CharacterTerminal('a'),
                new TokenType("a"));

            ProductionExpression
                SPrime = "S'",
                S = "S",
                A = "A",
                E = "E";

            SPrime.Rule = S;
            S.Rule = (Expr)S | A + A + A + A;
            A.Rule = (Expr)"a" | E;

            var expression = new GrammarExpression(
                SPrime,
                new[] { SPrime, S, A, E });

            var grammar = expression.ToGrammar();

            var parseEngine = new ParseEngine(grammar);
            parseEngine.Pulse(new Token("a", 0, a.TokenType));

            var privateObject = new PrivateObject(parseEngine);
            var chart = privateObject.GetField("_chart") as Chart;

            Assert.IsNotNull(chart);
            Assert.AreEqual(2, chart.Count);
            Assert.IsTrue(parseEngine.IsAccepted());
        }
示例#2
0
        private bool TryParseExistingToken()
        {
            var anyLexemes = this.tokenLexemes.Count > 0;

            if (!anyLexemes)
            {
                return(false);
            }

            var i    = 0;
            var size = this.tokenLexemes.Count;

            while (i < size)
            {
                var lexeme = this.tokenLexemes[i];
                if (lexeme.IsAccepted())
                {
                    i++;
                }
                else
                {
                    if (i < size - 1)
                    {
                        this.tokenLexemes[i]        = this.tokenLexemes[size - 1];
                        this.tokenLexemes[size - 1] = lexeme;
                    }

                    size--;
                }
            }

            var anyMatches = size > 0;

            if (!anyMatches)
            {
                return(false);
            }

            i = this.tokenLexemes.Count - 1;
            while (i >= size)
            {
                this.tokenLexemes.RemoveAt(i);
                i--;
            }

            if (!ParseEngine.Pulse(this.tokenLexemes))
            {
                return(false);
            }

            for (i = 0; i < this.triviaAccumulator.Count; i++)
            {
                foreach (var tokenLexeme in this.tokenLexemes)
                {
                    tokenLexeme.AddLeadingTrivia(this.triviaAccumulator[i]);
                }
            }

            this.triviaAccumulator.Clear();
            this.previousTokenLexemes.Clear();
            this.previousTokenLexemes.AddRange(this.tokenLexemes);

            this.tokenLexemes.Clear();

            return(true);
        }