grammar - 为什么LL语法不能是左递归的?

标签 grammar ll left-recursion

dragon book中,LL语法定义如下:

当且仅当对于任何产生式A -> a|b时,以下两个条件均适用,语法为LL。


FIRST(a)FIRST(b)不相交。这意味着它们不能同时导出EMPTY
如果b可以派生EMPTY,则a不能派生任何以FOLLOW(A)开头的字符串,即FIRST(a)并且FOLLOW(A)必须不相交。


而且我知道LL语法不能保留递归,但是正式原因是什么?我猜左递归语法将与规则2相矛盾,对吗?例如,我写了以下语法:

S->SA|empty
A->a


因为FIRST(SA) = {a, empty}FOLLOW(S) ={$, a},所以FIRST(SA)FOLLOW(S)并非不相交,因此此语法不是LL。但是我不知道是否是FIRST(SA)FOLLOW(S)不相左的左递归,还是有其他原因?换句话说,每个左递归语法都会产生违反LL语法条件2的情况吗?

最佳答案

好吧,我知道了,如果一个语法包含左递归产生,例如:

S->SA


然后以某种方式必须包含另一个生产来“完成”递归,例如:

S->B


并且由于FIRST(B)是FIRST(SA)的子集,因此它们是联合的,这违反了条件1,因此在填充与FIRST(B)和FIRST(SA)中的终端相对应的解析表条目时必须存在冲突。总而言之,左递归语法可能导致两个或多个生产的FIRST集具有共同的末端,从而违反了条件1。

关于grammar - 为什么LL语法不能是左递归的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16165352/

相关文章:

c - 返回 char* 以在 C 中打印

string - 为什么在尝试将字符串添加到此字符串的末尾时,haskell 会停止?

scala - 使用 scala-parser-combinators 的递归定义

java - 是什么让 Java 比 C 更容易解析?

c++ - C++ 翻译单元的语法

regex - Perl6 中的语法有点过于贪婪

python - 如何使用 Pyparsing 解析嵌套函数调用?

ruby - 如何手动构建 AST?

compiler-construction - 是否有任何语言语法示例可以让Yacc表达但不能为Antlr4表达?

ANTLR4 又一个左递归