这不完全是家庭作业,但它与我的学习有关:
例如语法就像:
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表中存在一个我无法删除的冲突,这意味着我已经错过了一些步骤,或者在我无法找到的步骤中存在一些错误。请告诉我我做错了什么,以及如何解决这个问题。我一直在研究这个问题很长一段时间。
答案 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 -> a
与N -> b
的制作不同。
如您所见,在任何其他地方添加作品N
会破坏该规则。
你可以创建一个N -> id=
语法(但这可能不是你想要的),它可以在任何地方生成LL(2)
。 (id=E
集由2个元素字符串组成)。
另外,如果你再看一下所呈现的语法:
FIRST2
这是一个很高的机会,我在上面的解决方案中所做的运算符优先级是实际应用的正确选择。看看吧!