考虑表达式
E1 + E2
E1
不能有形式,因为必须被解析为. 这个限制是递归的:它也不能有.let ID = E3
let ID = E3 + E2
let ID = (E3 + E2)
E4 + let ID = E3
E2
可以有形式,但不能有形式(因为必须解析为)。只能有形式。let ID = E3
E3 + E4
E1 + E3 + E4
(E1 + E3) + E4
E1
E3 + E4
将这些限制转换为 BNF 很简单(但重复):
Expr ⇒ Sum
Sum ⇒ SumNoLet '+' Atom
| Atom
SumNoLet ⇒ SumNoLet '+' AtomNoLet
| AtomNoLet
AtomNoLet ⇒ num
| id
| '(' Expr ')'
Atom ⇒ AtomNoLet
| 'let' id '=' Expr
为了使模式更清晰,我们可以添加*
操作符:
Expr ⇒ Sum
Sum ⇒ SumNoLet '+' Prod
| Prod
SumNoLet ⇒ SumNoLet '+' ProdNoLet
| ProdNoLet
Prod ⇒ ProdNoLet '*' Atom
| Atom
ProdNoLet ⇒ ProdNoLet '*' AtomNoLet
| AtomNoLet
AtomNoLet ⇒ num
| id
| '(' Expr ')'
Atom ⇒ AtomNoLet
| 'let' id '=' Expr
可以使用优先声明在野牛(或其他类似的解析器生成器)中实现这一点。但是优先解决方案更难推理,并且可能会混淆到更复杂的语法中。