Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsec: Consume all input

Tags:

haskell

parsec

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?

like image 254
MathematicalOrchid Avatar asked Apr 25 '13 07:04

MathematicalOrchid


1 Answers

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.

like image 179
Tikhon Jelvis Avatar answered Oct 31 '22 17:10

Tikhon Jelvis