The root of the problem is saving the existing ps.Errorhttps://github.com/vektah/goparsify/blob/3e20a3b9244aa003fcaf26a625ef48246aef55f7/combinator.go#L48 which was originally added as part of the old branch prediction code and no longer makes sense. The error from an Any parser should be the longest error from its child parsers, and it should not worry about its caller's last error, as it is doing now.
Here's what goes wrong in the example from @austin-distilled: After str1 fails with the error {pos:3,expected:"1"}, parser recovers and tries str2. However, the recovered error retains its pos value, and because str2 starts by saving the recovered error as longestError, that error preempts the actual error from the (implicit) Exact("str2") parser when str2 returns. The recovered error then makes parser incorrectly think that str2 succeeded before parser even tries str.
I've returned Any to its old behavior by starting with an empty longestError. Since the ps.Cut condition was also an obsolete piece of the branch prediction logic, I removed it too.
fixes #3
The root of the problem is saving the existing
ps.Error
https://github.com/vektah/goparsify/blob/3e20a3b9244aa003fcaf26a625ef48246aef55f7/combinator.go#L48 which was originally added as part of the old branch prediction code and no longer makes sense. The error from anAny
parser should be the longest error from its child parsers, and it should not worry about its caller's last error, as it is doing now.Here's what goes wrong in the example from @austin-distilled: After
str1
fails with the error{pos:3,expected:"1"}
,parser
recovers and triesstr2
. However, the recovered error retains itspos
value, and becausestr2
starts by saving the recovered error aslongestError
, that error preempts the actual error from the (implicit)Exact("str2")
parser whenstr2
returns. The recovered error then makesparser
incorrectly think thatstr2
succeeded beforeparser
even triesstr
.I've returned
Any
to its old behavior by starting with an emptylongestError
. Since theps.Cut
condition was also an obsolete piece of the branch prediction logic, I removed it too.