So I'm still trying to get comfortable using Parsec, but I'm slowly working it into my toolbox.
When I have a file I need to parse, I find myself reading the file in as a string, and then passing the contents to parsec:
problem <- readFile input
case runParser myParser () input problem of
Left err -> hPutStrLn stderr $ "Error: " ++ show err
Right cs -> -- continue processing...
This seems like a fairly common pattern though - is there some existing function that I can use that takes a ParsecT String u IO a
and a FilePath
and parses the contents? I can't find anything in hoogle, but that might just be a failure of imagination.
Not ParsecT
, but there's parseFromFile
:: Parser a -> String -> IO (Either ParseError a)
. However, if your code snippet is accurate, you don't actually need the IO
in your parser, so this shouldn't be a problem. Something like this should produce the behaviour you want:
import Text.Parsec.String
import System.Exit
parse :: Parser a -> String -> IO a
parse p fileName = parseFromFile p fileName >>= either report return
where
report err = do
hPutStrLn stderr $ "Error: " ++ show err
exitFailure
It's still a little verbose, but you can define report
somewhere common and use it throughout your program; then parse
is a one-liner.
parseFromFile
inText.Parsec.String
orText.Parsec.ByteString
, but they only work with pure parsers (e.g.ParsecT String () Identity a
) - hammar 2012-04-05 22:47