有没有一种简单的方法来判断一个文法是否是LL(1)、LR(0)、SLR(1)...只看语法而不做任何复杂的分析?

例如:要确定 BNF 语法是否为 LL(1),您必须计算 First 和 Follow 集 - 在某些情况下这可能非常耗时。

有人知道如何更快地做到这一点吗?任何帮助将不胜感激!

有帮助吗?

解决方案

首先,有点迂腐。你不能确定是否 语言 是LL(1)从检查一语,只能使有关的发言 语法 本身。这是完全可以写非LL(1)法用语言对于这一LL(1)法存在。

有说出来的办法:

  • 你可以写一个分析器的语法和程序的计算,并按照第一组和其他属性。毕竟,这就是很大的优势,负责法,他们是机器容易理解。

  • 检查的语法和寻找 侵犯 该限制的各种法类型。例如:LL(1)允许对权利,但不左递归,因此,语法含有左递归是不LL(1).(对于其他语法性质的你必须花一些时间与的定义,因为我不记得其他任何东西掉我的头顶现在:).

其他提示

在回答您的主要问题:对于一个非常简单的语法,它可能是能够确定它是否是LL(1)无需构建FIRST和FOLLOW集,e.g

  

A→A + A |一个

     

不是LL(1),而

     

A→A | B'/ P>

但是,当你得到比这更复杂,你需要做一些分析。

  

A→B |一个结果   B→A + A

此不LL(1),但它可能不会立即明显

算术语法规则迅速得到非常复杂的:

  

EXPR→术语{ '+' 术语},点击   项→{因子“*”因素}点击   因素→号码| '(' EXPR ')'

此语法仅处理的乘法和加法,和已经它不是立即清楚的语法是否为LL(1)。它仍然可以通过语法寻求对其进行评估,但作为语法的增长它变得越来越feasable。如果我们定义了一个完整的编程语言的语法,它几乎肯定会采取一些复杂的分析。

这是说,有几个明显的蛛丝马迹,该语法不是LL(1) - 像A→A + A以上 - 如果你可以找到任何这些在你的语法,你就会知道它需要如果你正在写一个递归下降解析器被改写。但是,没有任何快捷方式,以验证该语法 LL(1)。

一方面,“语言/语法是否模棱两可”,是 一个已知的不可判定的问题邮寄信件停顿 问题。

直接从皮书"编译器:原则、技术和工具"通过Aho,et。al。

页223:

一个克语语法是LL(1) 如果且只有如果 每当一个-> 阿尔法 | beta 是两个不同的制作G以下条件举行:

  1. 对于没有终端"a"做两个 阿尔法beta 获得串的开始与"a"
  2. 在大多数中的一个 阿尔法beta 可以推导出空字符串
  3. 如果 beta 可以达到的空洞的过渡,通过为零或多个过渡,然后 阿尔法 不得任意字符串的开始有终端在按照(A)。同样,如果 阿尔法 可以达到的空洞的过渡,通过为零或多个过渡,然后 beta 不得任意字符串的开始有终端在按照(A)

从本质上讲,这是一个问题的验证文法通过对不相交性测试,也不涉及左递归。或者更简洁的语法克是左递归或含糊不能LL(1).

检查文法是否是模糊的或没有。如果是,则语法不LL(1)因为没有歧义文法是LL(1)。

亚存在用于LL快捷方式(1)的语法

1),如果A-> B1 | B2 | ....... | BN     然后第一(B1)相交的第一(B2)相交。首先(BN)=空集则是LL(1)的语法

2)如果A-> B1 |小量      然后B1相交如下(A)是空集

3)如果G是任何语法,使得每个非终端导出只有一个生产则语法是LL(1)

p0 S' → E
p1 E → id
p2 E → id ( E )
p3 E → E + id
  • 构建的LR(0)DFA,按照设定的电子和SLR行动/goto表。
  • 这是一个LR(0)语法?证明你的答案。
  • 使用单反表示的步骤(转变,削减,接受)的LR析程序分析:
    id ( id + id )
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top