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

Unexpected parsing behavior when composing parsers programmatically #298

Open
Amaumaury opened this issue Nov 24, 2023 · 2 comments
Open

Comments

@Amaumaury
Copy link

I'm trying to build a simple parser using fastparse which succeeds when the given input is one of the words defined in a given list. Concretely this is what my code looks like:

val words = List("a", "b", "c", "d")

def reader[$: P] = words.map(f => P( f )).reduce((l, r) => l | r )

fastparse.parse(input, reader(_))

The parser fails when input is "a", "b", or "c" and succeeds when given "d". Precisely, the parser seems to succeed when "d" appears in the input and all other characters are from the list of words.

From my understanding this parser should succeed on "a", "b", "c" and "d". Am I missing something ?

@Amaumaury Amaumaury changed the title Unexpected parsing behavior in fastparse when composing parsers programmatically Unexpected parsing behavior when composing parsers programmatically Nov 26, 2023
@lihaoyi
Copy link
Member

lihaoyi commented Jan 11, 2024

This is a known issue, the workaround is to do something like this

val words = List("a", "b", "c", "d")

def reader[$: P] = words.map(f => () => P( f )).foldLeft(Fail)((l, r) => l | r() )

fastparse.parse(input, reader(_))

Basically the call to P( f ) runs immediately, which is causing problems because .map and .reduce are eager. To defer evaluation, we need to wrap it in a () => and only call it when necessary

@Amaumaury
Copy link
Author

Thanks a lot for answering. I'm sorry I was not able to identify this as a known issue before posting.

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

2 participants