
Apologies to Christian for the double post, didn't look at the To-field. Am Thursday 20 August 2009 20:21:30 schrieben Sie:
Daniel Fischer wrote:
Am Donnerstag 20 August 2009 13:44:15 schrieb Martijn van Steenbergen:
Goedemiddag café,
Consider the following function, using parsec-3.0.0:
la :: Parsec String () (Maybe Char) la = lookAhead (optionMaybe anyChar)
*Lookahead> parseTest (char 'a' <|> char 'b') "a" 'a' *Lookahead> parseTest (char 'a' <|> char 'b') "b" 'b' *Lookahead> parseTest (la *> char 'a' <|> char 'b') "a" 'a' *Lookahead> parseTest (la *> char 'a' <|> char 'b') "b" parse error at (line 1, column 2): unexpected "b" expecting "a"
The first three work fine and as expected, but the fourth example fails where I would expect success. I know <|> won't try the rhs if the lhs consumed input, but lookAhead's documentation promises not to consume any input. Is this a bug in Parsec or am I missing something?
Bad bug in Parsec (from the beginning, the same happens in parsec-2), I'd say.
I'd say, its a feature. lookAhead returns whatever its argument returns. So in this case it returns "Consumed" without consuming.
In that case, the comment "lookAhead p parses p without consuming any input." from the parsec-3 docs is highly misleading. But lookAhead returning Consumed is not only counterintuitive, try parseTest (many la) "a" for a nice memory bomb.
You can always wrap around a "try" to force the alternative:
parseTest (try (la >> char 'a') <|> char 'b') "b"
Cheers Christian
Maybe it should have been:
la >> (char 'a' <|> char 'b')
in the first place.

Daniel Fischer wrote:
Bad bug in Parsec (from the beginning, the same happens in parsec-2), I'd say. I'd say, its a feature. lookAhead returns whatever its argument returns. So in this case it returns "Consumed" without consuming.
In that case, the comment
"lookAhead p parses p without consuming any input."
from the parsec-3 docs is highly misleading.
Yes, it isn't even documented in http://legacy.cs.uu.nl/daan/parsec.html I'ld say not consuming something after a successful lookAhead is an error (and if the argument of lookAhead consumes nothing, that is also odd.) In most cases "try" is the better alternative, where the result of try should be used as input for the following parser: (try identifierStart >>= indentifierRest) <|> constant
But lookAhead returning Consumed is not only counterintuitive, try
parseTest (many la) "a"
for a nice memory bomb.
It's as dangerous as using "setInput" and making the input longer (for recursive calls). But I don't see any disadvantages if "lookAhead" would return "Empty (Ok ...)", so I'ld also propose to change it (as you did). Cheers Christian
participants (2)
-
Christian Maeder
-
Daniel Fischer