[Haskell-cafe] A simple attoparsec question

Evan Laforge qdunkan at gmail.com
Tue Mar 1 22:58:01 CET 2011


>  parseConstant = Reference <$> try parseLocLabel
>              <|> PlainNum <$> decimal
>              <|> char '#' *> fmap PlainNum hexadecimal
>              <|> char '\'' *> (CharLit <$> notChar '\n') <* char '\''
>              <|> try $ (char '"' *> (StringLit . B.pack <$>
>                    manyTill (notChar '\n') (char '"')))
>              <?> "constant"
>
> The problem is, that attoparsec just silently fails on this kind of
> strings and tries other parsers afterwards, which leads to strange
> results. Is there a way to force the whole parser to fail, even if
> there's an alternative parser afterwards?

If none of the alternatives consume any characters, then the next
alternative will be tried.  But this is a question for your grammar,
i.e. it sounds like you have 'parseConstant <|> parseSomethingElse'
and you want parseSomethingElse to not be tried?  Then omit it!

If your string parser isn't working how you want, I recommend breaking
out the different kinds of literals, like chars and strings, and
testing at the REPL to make sure they work on their own.  BTW, if you
use takeWhile you can avoid the extra pack.  I like to use a between
combinator: 'between a b mid = a >> mid <* b'.  It's hard to read the
applicative soup above, and I wouldn't trust it to be totally correct,
instead I'd simplify with functions and test interactively.

The 'try' is also redundant, I think.



More information about the Haskell-Cafe mailing list