[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