【问题标题】:Finding a grammar is not LL(1) without using classical methods and transforming it to LL(1)如果不使用经典方法并将其转换为 LL(1),则找到语法不是 LL(1)
【发布时间】:2018-12-04 11:18:57
【问题描述】:

假设我有这个语法:

S -> A C x | u B A
A -> z A y | S u | ε
B -> C x | y B u
C -> B w B | w A

这个语法显然不是 LL(1),我可以找到它来构建解析表。但是,如果不使用经典方法,即不构造解析表或发现任何冲突,我有什么方法可以证明这个语法不是 LL(1)?

另外,我怎样才能将此语法转换为 LL(1)?我认为我必须同时使用 epsilon-derivation 消除和左递归消除,但这有点棘手,而且我尝试过很多次都无法将其转换为 LL(1)。

提前谢谢你。

【问题讨论】:

  • 通过S(first Alternative)->A(second Alternative)->S可以从自身到达S,可以直接看出语法不是LL(1),中间没有代币消耗。这将导致递归下降解析器中的无限递归。对于像@rici 这样的人,我将把转换留给 LL(1) - 我可能会这样做(如果可能的话),但这对我来说不是例行公事(或者)。

标签: compiler-construction grammar context-free-grammar compiler-theory


【解决方案1】:

S/AB/C 都涉及indirect left-recursion

由于没有左递归语法(直接或间接)对于任何 k 都是 LL(k),因此您可以简单地通过显示左递归循环来证明该语法不是 LL(1)。 (另一方面,如果你有一个计算 FIRST 和 FOLLOW 集的工具,“经典”方法真的很简单。)

消除间接左递归涉及首先找到非终结符的一种可能的拓扑类型,然后通过用非终结符的右侧替换非终结符的某些用途来打破推导循环。之后,就可以应用简单的左递归消除算法了。

您可以在here on StackOverflowhere 或任何有关解析理论的优秀教科书中找到这种转换的具体示例。 (或者,当然,通过搜索术语“间接左递归”并寻找具有一定可信度的页面。)

【讨论】:

    猜你喜欢
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多