Closed duncanmorris closed 6 years ago
I think to do this properly the parsers would need to statically expose the first chars they might accept so collisions could be detected and not put in the predictor. It would also mean the predictor table could be built during setup, rather then dynamically at runtime.
I don't really have time to dig deep on this, and this is definitely going to be a confusing bug for anyone hitting it so I've dropped the predictor from the Any
parser. It wasn't shaving that much time off anyway.
The predictor feature of the
Any
function breaks if one parser is a substring of another. I've got code to produce a minimal version of the issue.The parsing always works if the most specific (longest) parser is matched. If the least specific (shortest) parser matches, the predictor returns this template the next time it is called which means
Any
fails to match the more specific parser. We callAny
with the most specific parsers first leading to the least specific parser, but the predictor means the order isn't always enforced.We have solved this by creating a function called
NonPredictiveAny
that removes the predictive parts of the function. This comes at the expense of not being able to return the longest error (sinceError.pos
isn't exported). I thought you might have a better solution and/or might want to add an equivalent ofNonPredictiveAny
for others who have the same issue.Code to reproduce.
And a test suite.