我已经得出以下语法:
S -> a | aT
T -> b | bR
R -> cb | cbR
我理解为了使语法成为LL(1),它必须是非模糊的和右递归的。问题是我不完全理解左递归和右递归语法的概念。我不知道以下语法是否正确递归。我真的很感激左递归和右递归语法概念的简单解释,如果我的语法是LL(1)。
非常感谢。
答案 0 :(得分:5)
这个语法不是LL(1)。在LL(1)解析器中,应该始终可以根据当前的非终结符号和输入的下一个标记来确定接下来要使用的生产。
让我们来看看这个作品,例如:
S→a |在
现在,假设我告诉你当前的非终结符号是S而下一个输入符号是a。你能确定使用哪种产品吗?不幸的是,没有更多的上下文,你不能这样做:也许你假设使用S→a,也许你应该使用S→aT。使用类似的推理,您可以看到所有其他产品都有类似的问题。
这与左或右递归没有任何关系,而是LL(1)语法中相同非终结符的两个产生不能有非空公共前缀的事实。事实上,一个简单的启发式方法,用于检查语法是否不 LL(1),看看你是否能找到两个这样的生产规则。
希望这有帮助!
答案 1 :(得分:4)
语法只有一个递归规则:最后一个,其中R是左边的符号,也出现在右边。它是右递归的,因为在语法规则中,R是最右边的符号。该规则引用R,该引用最右边。
语言是LL(1)。我们如何知道这是因为我们可以轻松地构造一个递归下降解析器,它不使用回溯,最多只使用一个前瞻标记。
但是这样的解析器将基于稍微修改过的语法版本。
例如,两个作品:S -> a
和S -> a T
可以合并为一个可以由EBNF S -> a [ T ]
表达的作品。 (S
派生a
,后跟可选T
)。此规则可由单个解析函数处理,以识别S
。
该函数与a
匹配,然后查找可选的T
,它将由下一个输入符号b
表示。
我们可以为此写一个LL(1)语法:
S -> a T_opt
T_opt -> b R_opt
T_opt -> <empty>
... et cetera
T
的可选性通过使T
(我们重命名为T_opt
)能够导出空字符串,然后缩减为{{{{{ 1}},这样我们就不会有两个以S
开头的短语。
总而言之,语言是LL(1),但它的给定语法不是。由于语言是LL(1),因此可以找到另一个LL(1)的语法,并且该语法与给定语法的距离不远。