这个语法LR(1)怎么样而不是SLR(1)?

时间:2012-05-08 20:07:59

标签: parsing grammar conflict context-free-grammar lr

我有以下语法,我被告知是LR(1)但不是SLR(1):

  

S :: = A | b A c | d c | b d a

     

A :: = d

我不明白为什么会这样。你会如何证明这一点?

4 个答案:

答案 0 :(得分:11)

我没有足够的业力来评论上述答案,我对这个问题有点迟,但是...

我已经把这个语法看作其他地方的一个例子,OP实际上是一个错字。它应该是:

S :: = A a | b A c | d c | b d a

A :: = d

,即 S 的第一个条款是' A a',而不是'a A '。

这个的情况下,为A设置的FOLLOWS是{$,a,c},状态8中存在SLR冲突。

答案 1 :(得分:10)

解决这个问题的一种方法是尝试为语法构造LR(1)和SLR(1)解析器。如果我们在这样做的过程中发现任何转移/减少或减少/减少冲突,我们可以证明语法不得属于这些语言类别之一。

让我们从SLR(1)解析器开始吧。首先,我们需要为语法计算LR(0)配置集。这些可以在这里看到:

(1)
S -> .aA
S -> .bAc
S -> .dc
S -> .bda

(2)
S -> a.A
A -> .d

(3)
S -> aA.

(4)
A -> d.

(5)
S -> b.Ac
S -> b.da
A -> .d

(6)
S -> bA.c

(7)
S -> bAc.

(8)
S -> bd.a
A -> d.

(9)
S -> bda.

(10)
S -> d.c

(11)
S -> dc.

接下来,我们需要获取所有非终结符的FOLLOW集。这显示在这里:

FOLLOW(S) = { $ }
FOLLOW(A) = { $, c }

鉴于此,我们可以返回并将LR(0)配置集升级为SLR(1)配置集:

(1)
S -> .aA    [ $ ]
S -> .bAc   [ $ ]
S -> .dc    [ $ ]
S -> .bda   [ $ ]

(2)
S -> a.A    [ $ ]
A -> .d     [ $, c ]

(3)
S -> aA.    [ $ ]

(4)
A -> d.     [ $, c ]

(5)
S -> b.Ac   [ $ ]
S -> b.da   [ $ ]
A -> .d     [ $, c ]

(6)
S -> bA.c   [ $ ]

(7)
S -> bAc.   [ $ ]

(8)
S -> bd.a   [ $ ]
A -> d.     [ $, c ]

(9)
S -> bda.   [ $ ]

(10)
S -> d.c    [ $ ]

(11)
S -> dc.    [ $ ]

有趣的是,这里没有冲突!唯一可能的转换/减少冲突处于状态(8),但此处没有冲突,因为转移操作在a上,而减少在$上。因此,这个语法实际上 SLR(1)。由于任何SLR(1)语法也是LR(1),这意味着语法是SLR(1)和LR(1)。

希望这有帮助!

答案 2 :(得分:1)

我考虑过编写一个web-app来确定CFG的第一组和后续组以及LR(0),SLR(1)和LR(1)表。这样可以让你轻松尝试。

但幸运的是我先搜索了一下,发现这样的工具已经存在(我没想到会出现这种情况)。你可以在这里找到这个工具:

http://smlweb.cpsc.ucalgary.ca/

它希望输入格式如下:

S -> a A | b A c | d c | b d a.
A -> d.

使用此工具,我已经验证了其他人已经说过的内容:有问题的语法 SLR(1)。 (我给出了问题的-1)。

在Toby Hutton提出修改后,它不再是SLR(1),但仍然是LR(1)。

答案 3 :(得分:0)

1)给定的语法在自上而下的解析中为LL(1),在自下而上的解析中为LALR(1)。

2)在创建解析表时,并且该解析表没有多个条目,那么语法倾向于参加LALR(1)。

3)如果您的解析表有多个条目(我是指发生冲突),则该语法被称为SLR(1)。

4)语法被称为LR(1),因为它的解析表或ACTION / GOTO表没有冲突,并且我们都知道在LR(1)发生冲突期间,我们合并了数据并得到了LALR。

LR(0)或SLR或SLR(1)相同

LR(1)或CLR相同

LALR或LALR(1)相同

(1)参数定义语法分析器的内部构建效率类型。

谢谢。