如何判断一种语言是否是LL(1) LR(0) SLR(1)
有没有一种简单的方法可以通过查看语法而不进行任何复杂的分析来确定语法是否为 LL(1)、LR(0)、SLR(1)...?
例如:要确定 BNF 语法是否为 LL(1),您必须计算 First 和 Follow 集合 - 在某些情况下这可能非常耗时。
有人知道如何更快地做到这一点吗? 任何帮助将不胜感激!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
首先,有点迂腐。您无法通过检查语法来确定语言是否为LL(1),您只能对语法本身做出陈述。完全有可能为存在 LL(1) 语法的语言编写非 LL(1) 语法。
解决了这个问题:
您可以为语法编写一个解析器,并让一个程序首先计算并遵循集合和其他属性。毕竟,这是 BNF 语法的一大优势,它们是机器可理解的。
检查语法并查找违反各种语法类型约束的情况。例如:LL(1)允许右递归但不允许左递归,因此包含左递归的语法不是LL(1)。 (对于其他语法属性,您将不得不花一些时间来处理定义,因为我现在记不起任何其他内容:)。
First off, a bit of pedantry. You cannot determine whether a language is LL(1) from inspecting a grammar for it, you can only make statements about the grammar itself. It is perfectly possible to write non-LL(1) grammars for languages for which an LL(1) grammar exists.
With that out of the way:
You could write a parser for the grammar and have a program calculate first and follow sets and other properties for you. After all, that's the big advantage of BNF grammars, they are machine comprehensible.
Inspect the grammar and look for violations of the constraints of various grammar types. For instance: LL(1) allows for right but not left recursion, thus, a grammar that contains left recursion is not LL(1). (For other grammar properties you're going to have to spend some quality time with the definitions, because I can't remember anything else off the top of my head right now :).
回答你的主要问题:对于一个非常简单的语法,可以在不构造 FIRST 和 FOLLOW 集的情况下确定它是否是 LL(1),例如
群岛
但当你变得比这更复杂时,你需要做一些分析。
这不是 LL(1),但可能不会立即显而易见
算术的语法规则很快就会变得非常复杂:
该语法仅处理乘法和加法,并且目前还不能立即明确该语法是否为 LL(1)。仍然可以通过查看语法来评估它,但随着语法的增长,它变得不太可行。如果我们要为整个编程语言定义语法,那么几乎肯定需要进行一些复杂的分析。
也就是说,有一些明显的迹象表明该语法不是 LL(1) - 就像上面的 A → A + A - 如果您可以在语法中找到其中任何一个,您就会知道它需要重写如果您正在编写递归下降解析器。但是没有捷径可以验证语法是 LL(1)。
In answer to your main question: For a very simple grammar, it may be possible to determine whether it is LL(1) without constructing FIRST and FOLLOW sets, e.g.
is.
But when you get more complex than that, you'll need to do some analysis.
This is not LL(1), but it may not be immediately obvious
The grammar rules for arithmetic quickly get very complex:
This grammar handles only multiplication and addition, and already it's not immediately clear whether the grammar is LL(1). It's still possible to evaluate it by looking through the grammar, but as the grammar grows it becomes less feasable. If we're defining a grammar for an entire programming language, it's almost certainly going to take some complex analysis.
That said, there are a few obvious telltale signs that the grammar is not LL(1) — like the A → A + A above — and if you can find any of these in your grammar, you'll know it needs to be rewritten if you're writing a recursive descent parser. But there's no shortcut to verify that the grammar is LL(1).
一方面,“语言/语法是否模糊”,是一个已知的不可判定问题,例如帖子通信和停止问题。
One aspect, "is the language/grammar ambiguous", is a known undecidable question like the Post correspondence and halting problems.
直接摘自 Aho 等人所著的《编译器:原理、技术和工具》一书。等人。
第 223 页:
文法 G 是 LL(1) 当且仅当每当 A -> 时阿尔法 | beta 是 G 的两个不同产生式,满足以下条件:
本质上这是一个问题验证语法通过了成对不相交测试并且也不涉及左递归。或者更简洁地说,左递归或二义性的文法 G 不能是 LL(1)。
Straight from the book "Compilers: Principles, Techniques, & Tools" by Aho, et. al.
Page 223:
A grammar G is LL(1) if and only if whenever A -> alpha | beta are two distinct productions of G, the following conditions hold:
Essentially this is a matter of verifying the grammar passes the Pairwise Disjointness Test and also does not involve Left Recursion. Or more succinctly a grammar G that is left-recursive or ambiguous cannot be LL(1).
检查语法是否有二义性。如果是,则该文法不是 LL(1),因为没有二义性文法是 LL(1)。
Check whether the grammar is ambiguous or not. If it is, then the grammar is not LL(1) because no ambiguous grammar is LL(1).
是的,ll(1) 语法有快捷方式
1) if A->B1|B2|.......|Bn
那么first(B1)intersection first(B2)intersection .first(Bn)=空集那么它是ll(1)语法
2)如果A->B1|epsilon
则 B1 交集 follow(A) 为空集
3) 如果 G 是任意文法,使得每个非终结符仅导出一个产生式,则该文法为 LL(1)
ya there are shortcuts for ll(1) grammar
1) if A->B1|B2|.......|Bn
then first(B1)intersection first(B2)intersection .first(Bn)=empty set then it is ll(1) grammar
2) if A->B1|epsilon
then B1 intersection follow(A)is empty set
3) if G is any grammar such that every non terminal derives only one production then the grammar is LL(1)
id ( id + id )
id ( id + id )