将语法转换为LL(1)语法:一些问题

时间:2012-03-30 21:48:04

标签: compiler-construction grammar compiler-theory

这不完全是家庭作业,但它与我的学习有关:

例如语法就像:

  

E - > E + E | E * E | -E |(E)| ID

删除歧义后,它变为(从最低优先级运算符开始)

E->-F|F
F->F+G|G
G->G*H|H
H->(E)|id

删除左递归并离开保理后(在这种情况下不需要),最终的LL1语法是:

E->-F|F
F->GF'
F'->+GF'|e
G->HG'
B->*HG'|e
H->(E)|id

这给出了一个无错误的解析器表,它可以正常工作。 现在关于我面临的问题,假设语法是这样的:

  

E - > E + E | E * E | ID = E |(E)| ID

现在我无法生成没有冲突的解析表,这意味着我的最终语法不是LL1。以下是步骤:

消除歧义后

E->id=F|F
F->F+G|G
G->G*H|H
H->(E)|id

删除左递归并离开保理后,语法变为:

E->id=F|F
F->GF'
F'->+GF'|e
G->HG'
B->*HG'|e
H->(E)|id

但是Parser表中存在一个我无法删除的冲突,这意味着我已经错过了一些步骤,或者在我无法找到的步骤中存在一些错误。请告诉我我做错了什么,以及如何解决这个问题。我一直在研究这个问题很长一段时间。

1 个答案:

答案 0 :(得分:2)

让我们说:

E -> E+E|E*E|id=E|(E)|id

将成为:

E -> E+E|E*E|(E)|E'
E' -> id=E|id

然后你可以去除歧义和左手递归并得到:

E -> GF       FIRST(E) = FIRST(G)
F -> +GF|e
G -> HG'      FIRST(G) = FIRST(H)
G' -> *HG'|e
H -> (E)|E'   FIRST(H) = {(} + FIRST(E') = {(, id} 
E' -> idE''   FIRST(E') = {id}
E'' -> =E|e   FIRST(E'') = {=} + {#}

当然,问题是,你失去了给定的运算符优先级。

对于任何非终结N语法不会是LL(1)FIRST(N -> a)中会有任何公共元素FIRST(N -> b)的{​​{1}},N -> aN -> b的制作不同。

如您所见,在任何其他地方添加作品N会破坏该规则

你可以创建一个N -> id=语法(但这可能不是你想要的),它可以在任何地方生成LL(2)。 (id=E集由2个元素字符串组成)。

另外,如果你再看一下所呈现的语法:

FIRST2

这是一个很高的机会,我在上面的解决方案中所做的运算符优先级是实际应用的正确选择。看看吧!