Compiler construction 如果不使用经典方法并将其转换为LL(1),则查找语法不是LL(1)

Compiler construction 如果不使用经典方法并将其转换为LL(1),则查找语法不是LL(1),compiler-construction,grammar,context-free-grammar,compiler-theory,Compiler Construction,Grammar,Context Free Grammar,Compiler Theory,假设我有这样的语法: 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)?我想我必须同时使用ε求导消去法和左递归消去法,但这有点棘手,而且我多次尝试都无法将其转换为LL(1) 提前谢谢。这两个

假设我有这样的语法:

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)?我想我必须同时使用ε求导消去法和左递归消去法,但这有点棘手,而且我多次尝试都无法将其转换为LL(1)


提前谢谢。

这两个
S
/
A
B
/
C
都涉及到

因为对于任何k,没有左递归语法(直接或间接)是LL(k),所以可以通过显示左递归循环来证明该语法不是LL(1)。(另一方面,如果你有一个工具可以计算第一个和第二个集合,“经典”方法非常简单。)

消除间接左递归需要首先找到一种可能的非终结点拓扑类型,然后通过用非终结点的右侧替换非终结点的某些用法来打破派生循环。然后,可以应用简单的左递归消除算法


你可以找到这种转换的具体例子,或者在任何关于解析理论的好教材中。(当然,也可以通过搜索术语“间接左递归”并查找具有一定可信度的页面。)

这两个
S
/
A
B
/
C
都涉及到

因为对于任何k,没有左递归语法(直接或间接)是LL(k),所以可以通过显示左递归循环来证明该语法不是LL(1)。(另一方面,如果你有一个工具可以计算第一个和第二个集合,“经典”方法非常简单。)

消除间接左递归需要首先找到一种可能的非终结点拓扑类型,然后通过用非终结点的右侧替换非终结点的某些用法来打破派生循环。然后,可以应用简单的左递归消除算法


你可以找到这种转换的具体例子,或者在任何关于解析理论的好教材中。(当然,也可以通过搜索术语“间接左递归”并查找具有一定可信度的页面。)

可以直接看出语法不是LL(1),因为您可以通过S(第一个选项)->A(第二个选项)->S从自身到达S,其间不消耗任何标记。这将导致递归下降解析器中的无限递归。对于像@rici这样的人,我将把转换留给ll(1)——我可能会这样做(如果可能的话),但这对我来说也不是例行公事。可以直接看出,语法不是ll(1),因为你可以通过s(第一个选项)->A(第二个选项)->s从自身到达s,其间不消耗任何标记。这将导致递归下降解析器中的无限递归。对于像@rici这样的人,我将把转换留给ll(1)——我可能会这样做(如果可能的话),但这对我来说也不是例行公事。