我有以下语法,我被告知是LR(1)但不是SLR(1):
S :: = A | b A c | d c | b d a
A :: = d
我不明白为什么会这样。你会如何证明这一点?
答案 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)参数定义语法分析器的内部构建效率类型。
谢谢。