Heinrich Apfelmus apfelmus at quantentunnel.de
Mon Nov 1 05:13:41 EDT 2010

```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.
*  lookAhead  is very useful for avoiding capturing input in the second
argument of  manyTill

Regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com

```