The documentation for Parsec.Expr.buildExpressionParser says:
Prefix and postfix operators of the same precedence can only occur once (i.e. --2 is not allowed if - is prefix negate).
However, I would like to parse such strings.
Concretely, consider the following grammar:
sentence:
| identifier
| "~" sentence
| sentence & sentence
| "!" sentence
Where operator precedence is: "~"
binds stronger than "&"
binds stronger than "!"
For example, I would like the sentence
! ~a & b
to be parsed as
! ( (~a) & b )
And the sentence
~ ! a & b
as
~( ! ( a & b) )
Parsec allows me to do this (and specify the operator precedence), however, I would like to be able to chain prefixes, e.g. ~ ~ ! ~ a
.
Parsec does not allow this.
I have found the solution for chaining prefixes, but this solution does not allow me to specify a different operator priority for the different prefix operators (either both "~" and "!" bind stronger than "&", or none of them does)
Does anyone have a solution for this?
Edit:
Partial solution that gets the operator bindings correct, but allows no chaining: http://lpaste.net/143362
Partial solution with chaining but that has a wrong binding for the "~" operator: http://lpaste.net/143364
Edit: Some more clarifications related to the latest answer.
I actually want &
to be associative. Left or right does not matter. Left vs right associativity only matters between operators of the same precedence.
For your examples, it is all resolved by noting that &
binds stronger than !
(&
has greater operator precedence)
Hence, the expression you were worried about:
a & ! b & c
should become:
(first bind &
where possible)
a & ! (b & c)
Similarly, ! a & ! b & c
should be parsed
(first bind &)
! a & ! (b & c)
, thus ! a & (! (b & c))
, thus ! (a & (! (b & c)))