15
votes

One common problem I have with Parsec is that it tends to ignore invalid input if it occurs in the "right" place.

As a concrete example, suppose we have integer :: Parser Int, and I write

expression = sepBy integer (char '+')

(Ignore whitespace issues for a moment.)

This correctly parses something like "123+456+789". However, if I feed it "123+456-789", it merrily ignores the illegal "-" character and the trailing part of the expression; I actually wanted an error message telling me about the invalid input, not just having it silently ignore that part.

I understand why this happens; what I'm not sure about is how to fix it. What is the general method for designing parsers that consume all supplied input and succeed only if all of it is a valid expression?

1

1 Answers

32
votes

It's actually pretty simple--just ensure it's followed by eof:

parse (expression <* eof) "<interactive>" "123+456-789"

eof matches the end of the input, even if the input is just a string and not a file.

Obviously, this only makes sense at the top level of your parser.