Skip to content

Commit

Permalink
Merge pull request #78 from nblumhardt/many-backtracking
Browse files Browse the repository at this point in the history
Fixes #76, incorrect remainder used when Many() backtracks
  • Loading branch information
nblumhardt committed Jan 8, 2019
2 parents 5df2f89 + f0d7592 commit 2ddd2d5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/Superpower/Combinators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ public static TextParser<T[]> Repeat<T>(this TextParser<T> parser, int count)
if (!r.Backtrack && r.IsPartial(@from))
return TokenListParserResult.CastEmpty<TKind, T, T[]>(r);
return TokenListParserResult.Value(result.ToArray(), input, r.Remainder);
return TokenListParserResult.Value(result.ToArray(), input, from);
};
}

Expand Down Expand Up @@ -444,7 +444,7 @@ public static TextParser<T[]> Many<T>(this TextParser<T> parser)
if (!r.Backtrack && r.IsPartial(from))
return Result.CastEmpty<T, T[]>(r);
return Result.Value(result.ToArray(), input, r.Remainder);
return Result.Value(result.ToArray(), input, from);
};
}

Expand Down Expand Up @@ -476,7 +476,7 @@ public static TextParser<Unit> IgnoreMany<T>(this TextParser<T> parser)
if (!r.Backtrack && r.IsPartial(from))
return Result.CastEmpty<T, Unit>(r);
return Result.Value(Unit.Value, input, r.Remainder);
return Result.Value(Unit.Value, input, from);
};
}

Expand Down
25 changes: 25 additions & 0 deletions test/Superpower.Tests/Combinators/ManyCombinatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,30 @@ public void TokenManyFailsWithPartialItemMatch()
var list = ab.Many();
AssertParser.Fails(list, "ababa");
}

[Fact]
public void ManySucceedsWithBacktrackedPartialItemMatch()
{
var ab = Character.EqualTo('a').Then(_ => Character.EqualTo('b'));
var ac = Character.EqualTo('a').Then(_ => Character.EqualTo('c'));
var list = Span.MatchedBy(ab.Try().Many().Then(_ => ac));
AssertParser.SucceedsWithAll(list, "ababac");
}

[Fact]
public void ManyReportsCorrectErrorPositionForNonBacktrackingPartialItemMatch()
{
var ab = Character.EqualTo('a').Then(_ => Character.EqualTo('b'));
var list = ab.Many();
AssertParser.FailsWithMessage(list, "ababac", "Syntax error (line 1, column 6): unexpected `c`, expected `b`.");
}

[Fact]
public void ManyReportsCorrectRemainderForBacktrackingPartialItemMatch()
{
var ab = Character.EqualTo('a').Then(_ => Character.EqualTo('b'));
var list = Span.MatchedBy(ab.Try().Many()).Select(s => s.ToStringValue());
AssertParser.SucceedsWith(list, "ababac", "abab");
}
}
}

0 comments on commit 2ddd2d5

Please sign in to comment.