python | 编译原理,语法分析——LR(1)文法实现

本文介绍了LR(1)文法的概念,包括其从左向右扫描和最右推导的特性,并详细阐述了LR(1)分析表的组成,如action表和goto表的结构及功能。通过实例解释了action表和goto表的使用,并给出了《编译原理》书中关于预测分析的伪代码,最后展示了手动生成的LR(1)预测分析表和运行结果。
摘要由CSDN通过智能技术生成

LR(1)文法的意思是从左向右扫描,最右推导,往前多看一个字符。
LR(1)文法也需要构造要给预测分析表,但是LR(1)的的预测分析表有两部分,分别是action表和goto表。

action表的横坐标是不同的状态标号,纵坐标是不同的终结符,goto表的横坐标也是不同状态标号,纵坐标是不同的非终结符。
action表中有si、rj、acc和空白,其中si表示推进至状态i,将当前输入符号和状态i入栈,rj按第j个产生式进行规约,栈首弹出,利用产生式生成,入栈,转移状态也同时入栈。acc表示接受,即算法结束。空白表示出错。
goto表中表示从某个状态规约后,遇到产生式左边某个非终结符后转移到的状态。
我们以下面这个预测分析表为例:
(这里是部分预测分析表)
在这里插入图片描述
《编译原理(第3版)》(陈意云等编著)这本书里把用预测分析表进行预测的方法用伪代码写了出来,我写在下方。

令a是w$的第一个符号
while(1){
   
	令s是栈顶的状态
	if(action[s,a] == 移进t){
   
		把a和t依次压入栈
		令a是下一个输入符号
	}else if(action[s,a] == 规约 A -> beta){
   
		栈顶退掉2 *|beta|个符号
		令t是现在的栈顶状态
		把A和goto[t,A]压入栈
		输出产生式A -> beta
	}else if(action[s,a] == 接受)	break;
	else	调用错误恢复例程
}

给大家一个表作为演示。
在这里插入图片描述
这里我是手动生成的预测分析表:

vt = ['id','+','*','(',')','$']
vn = ['E','T','F']

actionData = [['' for i in range(len(vt))] for j in range(12)]
Action = pd.DataFrame(data = actionData,index=range(12),columns=vt)
gotoData = [[-1 for i in range(len(vn))] for j in range(12)] 
Goto = pd.DataFrame(data = gotoData,index=range(12),columns=vn)

Action.loc[0]['id'] = 's 5'
Action.loc[0]['('] = 's 4'
Action.loc[1]['+'] = 's 6'
Action.loc[1]['$'] = 'acc'
Action.loc[2]['+'] = 'r 2'
Action.loc[2]['*'] = 's 7'
Action.loc[2][')'] = 'r 2'
Action.loc[2]['$'] = 'r 2'
Action.loc[3]['+'] = 'r 4'
Action.loc[3]['*'] = 'r 4'
Action.loc[3][')'] = 'r 4'
Action.loc[3]['$'] = 'r 4'
Action.loc[4]['id'] = 's 5'
Action.loc[4]['('] = 's 4'
Action.loc[5]['+'] = 'r 6'
Action.loc[5]['*'] = 'r 6'
Action.loc[5][')'] = 'r 6'
Action.loc[5]['$'] = 'r 6'
Action.loc[6]['id'] = 's 5'
Action.loc[6]['('
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值