What is an unambiguous grammar equivalent to to the following ambiguous grammar for a language of expressions with let and addition?
E ⇒ let id = E in E
E ⇒ E + E
E ⇒ num
The ambiguity should be solved so that:
- addition is left associative
- addition has higher precedence than let expressions when it appears on the right
- addition has lower precedence than let expressions when it appears on the left
Using braces to show the grouping of sub-expressions, the following illustrates how expressions should be interpreted:
num + num + num
=> { num + num } + num
let id = num in num + num
=> let id = num in { num + num }
num + let id = num in num
=> num + { let id = num in num }
Consider the expression
E1 + E2
E1
cannot have the formlet ID = E3
becauselet ID = E3 + E2
must be parsed aslet ID = (E3 + E2)
. This restriction is recursive: it also cannot have the formE4 + let ID = E3
.E2
can have the formlet ID = E3
but it cannot have the formE3 + E4
(becauseE1 + E3 + E4
must be parsed as(E1 + E3) + E4
). OnlyE1
can have the formE3 + E4
.It's straight-forward (but repetitive) to translate these restrictions to BNF:
To make the pattern clearer, we can add the
*
operator:It is possible to implement this in bison (or other similar parser generators) using precedence declarations. But the precedence solution is harder to reason about, and can be confusing to incorporate into more complicated grammars.