I am converting some functioning Haskell code that uses Parsec to instead use Attoparsec in the hope of getting better performance. I have made the changes and everything c
You give quite little information which is why I think it is hard to give you good help. However there are a couple of comments I would like to give:
If you write an attoparsec parser that consumes as much input as possible before failing, you must tell the partial result continuation when you've reached the end of your input.
I've run into this problem before and my understanding is that it's caused by the way that <|>
works in the definition of sepBy
:
sepBy1 :: Alternative f => f a -> f s -> f [a]
sepBy1 p s = scan
where scan = liftA2 (:) p ((s *> scan) <|> pure [])
This will only move to pure []
once (s *> scan)
has failed, which won't happen just because you're at the end of the input.
My solution has been just to call feed
with an empty
ByteString on the Result
returned by parse
. This might be kind of a hack, but it also seems to be how attoparsec-iteratee deals with the issue:
f k (EOF Nothing) = finalChunk $ feed (k S.empty) S.empty
As far as I can tell this is the only reason that attoparsec-iteratee
works here and plain old parse
doesn't.