Malcolm Wallace wrote:
Nils Schweinsberg wrote:

Vo Minh Thu wrote:
 So you have to either factorize you parsers or use
the 'try'.

This is exactly what gives me headaches. It's hard to tell where you need try/lookAhead and where you don't need them. And I don't really feel comfortable wrapping everything into try blocks...

Have you considered using a different set of parser combinators, a set that is actually composable, and does not require the mysterious "try"? I would recommend polyparse (because I wrote it), but uuparse would also be a fine choice.

I second that, the semantics of Parsec are quite tricky. It's worth learning them properly if you insist on using Parsec. If you don't want to do that, it's easier to use a different library.


The two defining properties of Parsec's alternative  <|>  combinator are:

1) If a parser p consumes a character, then it will take precedence over its alternatives p <|> q = p .

2) Parsers that are in sequence with an alternative don't have any influence on which alternative is chosen.

   (p <|> q) >>= k  =   p >>= k  if  p  succeeds
                        q >>= k  if  p  does not succeed

   but  p >>= k  might not succeed
   even if  p  does succeed and  q >>= k  would succeed.


I found the following rule of thumbs helpful:

* Try to use alternatives p <|> q only when p and q recognize different first characters. * Don't do recursion yourself, use premade combinators like many1 etc. instead. * lookAhead is very useful for avoiding capturing input in the second argument of manyTill


Regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to