LR文法处理空产生式

在进行课程实践的时候遇到了这个问题。
对于空产生式E->$,应当在LR计算闭包时,直接生成E->#

也就是说,当我们在对类似项目A->αEβ计算其闭包时,若E可推导出空字符串,则直接生成E->#这样可以直接归约的项目。

特别的,对于LR1文法,如果生成了这样的可以直接归约的项目,则当最新的token属于First(βa)时,其中β和a分别为A->αEβ,a中E的后续序列和A的前看符号,程序可以根据预测分析表判断出现在应该归约。

对于归约操作,程序应当在归约时检测项目是否形如E->#,若符合,则表明当前进行的是空产生式的归约,则不须从符号栈中弹出任何符号,同样的,也不需要进行状态回溯,直接在符号栈中压入一个归约结果E即可。

示例

以LR1处理如下语法为例:

block -> { blockItem }
blockItem -> decl blockItem
blockItem -> $

对于以上的语法,初始项目集为:

// I0
block' -> #block, $
block -> #{ blockItem }, $

求GOTO(I0, block),则有:

// I1
block' -> block#, $

I1即为最终的结果,此处不是重点,只是顺带一提
而求GOTO(I0, {),则有:

// I2
block -> {# blockItem }, $
blockItem -> #decl blockItem, }
blockItem -> #$, }

此时,根据I0和’{‘,得到了block -> {# blockItem }, $

然后对其求闭包,可以看到有blockItem -> #decl blockItem, }blockItem -> #$, },第二个即为根据空产生式的产生的项目,表示如果当前输入缓存区前端的符号为’{',则直接凭空产生一个blockItem到栈中。

下面为具体文本的归约过程:

"{}"
// 移入
block -> {# blockItem } 
 // 归约
block -> { blockItem #}
// 移入
block -> {blockItem}# 
// 归约
block' -> block#

如上,对于"{}",根据语法规则,我们知道其可以最终归约到block。

机器首先读取到’{‘符号,然后将其移入。此时项目为block -> {#blockItem},输入缓存区前端的符号为’{‘。

此时机器查预测分析表,找到I2项目集blockItem -> #$, }的这条规则,发现blockItem可以直接凭空产生,同时要求前看符号为’}‘,而此时正好满足要求,于是机器不再移入,而是直接压入一个blockItem到栈中,不移入输入缓存区的符号,归约操作也不消耗栈内的符号。

上一段为拟人描述,实际中,预测分析表可以使用哈希表实现,机器根据当前的状态和前看符号查找到应当使用的规则,获取到该规则的归约结果blockItem和归约条件$,根据编程时的判断程序,$表示不需要弹出任何栈内符号,于是机器直接push一个blockItem到栈中。

最后机器根据当前状态block->{ blockItem #}和前看符号’}‘,将’}'也从输入缓存区取出,push到栈中,归约到block,最终完成归约过程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
当我们对一个上下文无关文法进行语法分析时,通常需要将其转换为消除左递归和删除产生文法。删除产生的过程是将文法所有可以推导出串的产生都删除,并将其产生右部符号去除或替换。下面是一些详细的步骤: 1. 找到所有可以推导出串的非终结符号。这些非终结符号所对应的产生必须包含符号,或者可以通过其他的产生推导出符号。 2. 对于每个可以推导出串的非终结符号,将其所对应的产生分为两类:包含符号的产生和不包含符号的产生。如果一个非终结符号的所有产生都包含符号,则需要为其添加一个新的产生,该产生的右部为符号。 3. 删除所有包含符号的产生。对于每个包含符号的产生,可以将其产生右部符号去除或替换。如果将其去除,则需要在结果产生保留原来的符号顺序和位置。如果将其替换为其他的符号,则需要为其添加新的产生。 4. 对于包含非终结符号的产生,需要考虑其所对应的非终结符号是否可以推导出串。如果该非终结符号可以推导出串,则需要将其所在的产生进行类似步骤3的操作。如果该非终结符号不可以推导出串,则不做任何处理。 5. 重复步骤3和步骤4,直到所有可以推导出串的产生都被删除或替换为不包含符号的产生。 完成上述步骤之后,我们就得到了一个不包含产生文法。这个文法可以用于进行语法分析,例如使用 LL(1) 分析器或 LR 分析器等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值