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()); }
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); }