[Haskell-beginners] Baffled by Parsec
Daniel Fischer
daniel.is.fischer at web.de
Sat Feb 21 16:10:36 EST 2009
Am Samstag, 21. Februar 2009 21:04 schrieb Colin Paul Adams:
> The tutorials I've found don't tell me what I want to know :-(
>
> I have lines that begin with an integer, then white-space, and then
> further structure to the end-of-line.
>
> So for a starter, could you show me how to write a parser for the
> integer (returning an Int), and how to combine it with a parser for
> the rest of the line (take that as written - it isn't, but I'll try to
> do that myself given such a kick-start).
>
> Thanks.
-- could also be Parser Int, if you don't need user-state
parseInt :: GenParser Char st Int
parseInt = do
neg <- (char '-' >> return True) <|> (optional (char '+') >> return False)
digs <- many1 digit
let n | neg = negate $ read digs
| otherwise = read digs
return n
parseLine :: GenParser Char st LineStructure
parseLine = do
-- spaces here, if there may be whitespace at the beginning of lines
num <- parseInt
spaces
things <- parseRemainderOfLine
return (combine num things)
The strategy is always the same, you write parsers for small things and
combine their results.
Note that things are somewhat tricky if the structure you want to parse isn't
very strict, if one of your possible parsers at some point in the parsing
process can fail, but not immediately and you need to backtrack, you have to
use the 'try' combinator as in
combo = (try parser1) <|> parser2
, but try is bad for performance, so use it only where it's necessary.
The latter part is notoriously difficult to identify for the inexperienced, so
until you know parsec better, it's okay to insert a few 'try's more than
necessary.
HTH, otherwise ask again,
Daniel
More information about the Beginners
mailing list