使用非终端从生产中删除左递归

时间:2011-02-04 04:05:10

标签: context-free-grammar

HI,

我制作了以下表格:

Expr ---> Primary | UnaryOp Expr | Expr BinOp Expr | id=Expr | id[Expr]=Expr.

任何人都可以通过删除左递归来帮助我将其转换为LL(1)形式吗?我已经反对这一点,但我仍然无法得到它:(。以下是我的尝试。


Expr ---> Primary Expr' | UnaryOp Expr Expr' | id=Expr Expr' | id[Expr]=Expr Expr'

Expr' ---> BinOp Expr Expr' | epsilon

以上转换是否正确?我在这做什么?。

我使用了wikipedia中找到的以下一般规则。


A --->  Ab | B
转换时

A' --->  aA'
A  --->  BA' 

3 个答案:

答案 0 :(得分:0)

DragonBook很好地解释了如何从LR(0)转换为LL(1),以及哪些语法不是LL(1)等。如果你热衷于学习这个,你应该看看这本书的解释。

答案 1 :(得分:0)

Expr ---> Primary Expr' | UnaryOp Expr | id=Expr | id[Expr]=Expr
Expr' ---> BinOp Expr | epsilon

包含左递归的语法是Expr ---> Expr BinOp Expr 已经完成的是,从

中删除左递归

通过与文章

比较来检查这是否正确

http://en.wikipedia.org/wiki/Left_recursion

答案 2 :(得分:0)

Expr ---> Primary | UnaryOp Expr | Expr BinOp Expr | id=Expr | id[Expr]=Expr

通过这种方式很容易想到左递归移除。 你在第三个表达式'Expr BinOp Expr'中有一个左边的重复。你知道左'Expr'一词将在某个时间被其他终端和表达式取代(这就是我们如何避免左递归)。所以我们这样做 - >用其他表达式替换有问题的术语,

Expr ---> Primary BinOp Expr | UnaryOp Expr BinOp Expr | id=Expr  BinOp Expr | id[Expr]=Expr BinOp Expr | ( Primary | UnaryOp Expr | id=Expr | id[Expr]=Expr )

我们看到'BinOp Expr'重复出现。把它提取到另一个语法,这是最终的结果

Expr' --> e | BinOp Expr

Expr -- > Primary Expr' | UnaryOp Expr Expr' | id=Expr Expr' | Primary Expr' | id[Expr]=ExprExpr' 

注意e:表示表达式也可以是Primary,UnaryOp Expr等中的任何一个