Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

many1Till quirk can cause stack overflows and O(n!) parser complexity with recursive grammars #111

Open
zotanmew opened this issue Nov 26, 2024 · 0 comments

Comments

@zotanmew
Copy link

Unlike manyTill p endp, many1Till p endp runs p first, even if endp would match immediately. This, when used in a recursive grammar, can cause parsers that work perfectly fine on most inputs to produce stack overflows - despite a modest recursion depth of <10, and can cause inputs of reasonable length to stall for long / indefinite periods (I think O(n!)).

The documentation currently reads:

The parser many1Till p endp behaves like manyTill p endp, except that it requires p to succeed at least one time.

many1Till p endp is an optimized implementation of pipe2 p (manyTill p endp) (fun hd tl -> hd::tl)

I would suggest that many1Till (and skipMany1Till) be changed to the equivalent of notFollowedBy endp >>. many1Till p endp. If that behavior change is not wanted, I'd strongly recommend documenting this quirk in a more obvious way, and with a disclaimer that this can cause problems with recursive grammars.

I'm also not sure if similar issues exist in other primitives - this is the only one I've encountered so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant