SLR(1),LALR(1),LR(1)文法的区别

三个文法的简单介绍

  • SLR(1)
    • SLR(1)的使用条件
    • SLR(1)带来的问题
  • LR(1)
    • 向前搜索符的构造
    • LR(1)的问题
  • LALR(1)
    • LALR(1)的问题

SLR(1)

SLR(1):简单的LR(1)文法。不带向前搜索符,为了解决LR(0)中移进-规约冲突和规约-规约冲突。

SLR(1)的使用条件

SLR(1)只能用于存在移进-规约冲突和规约-规约冲突的文法中对应的FOLLOW集合交集为空。

SLR(1)带来的问题

文法G为:
(0)S`–>S
(1)S–>aAd
(2)S–>bAc
(3)S–>aec
(4)S–>bed
(5)A–>e

经过转化函数可以得出状态转换图
其中会存在
(1)S–>ae·c
(2)A–>e·
按照正常的SLR(1)分析,遇到d,c都要利用产生式(2)进行规约,但是根据文法我们会发现
S`–>S–>aAd–>aed
–>S–>aec 不难发现,对于ae来说,只有遇到c才应该移进,遇到d时应该用产生式(2)进行规约。
这就出现了矛盾的问题。

LR(1)

为了解决SLR(1)中的问题,我们用向前搜索符代替follow集合的做法。因此产生了LR(1)。

向前搜索符的构造

Sˊ–>•S 作为初始产生式,#就是他的向前搜索符。记作 Sˊ–>•S,#

S–>•aAd 的向前搜索符:根据产生式右部存在S的,除去S之后一直到最后(也就是#)的整个字符串求first集所以S–>•aAd,#。

LR(1)的问题

以前没有向前搜索符的时候,产生式集合一致就是相同状态,现在会出现产生式集合一致,向前搜索符不一致的两种状态。
例如依然针对文法G:
(0)S`–>S
(1)S–>aAd
(2)S–>bAc
(3)S–>aec
(4)S–>bed
(5)A–>e
经过项目集的构造会出现以下情况:

I3 I6
B-->a•B,a/b B-->a•B,#
B-->•aB,a/b B-->•aB,#
B-->•b,a/b B-->•b,#
这种集合成为同心集。明显发现同心集的存在只会让状态变多,占据太多的内存。

LALR(1)

为了解决LR(1)冗余的问题,针对同心集的合成后依然不会产生冲突,说明该文法是LALR(1)的文法。

LALR(1)的问题

因为同心集的合并,例如原本在I3状态下出错的#,合并之后就不会出现错误,会出现报错延迟,浪费步骤。但是报错位置依然准确。

你可能感兴趣的:(复习,编译原理)