Jason Dusek wrote:
> 2009/04/17 minh thu <noteed at gmail.com>:
>> 2009/04/17 Michael Mossey <mpm at alumni.caltech.edu>:
>>> I wonder how I can get the manyTill to be happy with eof
>>> before finding the //? I tried
>>>>>> parseText = manyTill anyChar (try (string "//") <|> eof)
>>>>>> but got a type error.
>> You can use 'notFollowedBy' [...]
>> You get a type error because `string "//"` parses to a
> `String` while `eof` parses to a `()`. Instead you might use:
>> parseText = manyTill anyChar (try (string "//" >> return ()) <|> eof)
>> --
> Jason Dusek
Ah.. I think I get it... in the function manyTill, the second argument type doesn't
matter.. doesn't have to match the first argument type.
Here's what I have so far. It works, but it's a bit weird to consume the // as part
of the text rather than the keyword. That happens because the try( string "//" ),
which is part of the end arg to manyTill, consumes the // when it succeeds. But maybe
it is the most natural way to express the problem.
parseKeyword :: Parser String
parseKeyword = many1 (alphaNum <|> char '_')
parseText :: Parser String
parseText = manyTill anyChar ((try (string "//") >> return ())
<|> eof)
parsePair :: Parser (String,String)
parsePair = do k <- parseKeyword
t <- parseText
return (k,t)
parseFile :: Parser [(String,String)]
parseFile = do _ <- parseText -- to skip any text at beginning and 'sync up'
p <- many parsePair
return p