SLR(1)语法分析实验
目录
实验目的
1. 了解自底向上分析方法的基本思想(移进-归约),熟悉LR分析的主要概念,理解LR(0)项目集构造方法,掌握SLR(1)分析表构造算法。
2. 掌握LR语法分析器的设计与调试。
实验内容
针对CP语言中简单赋值语句文法G[S’]:
[0] S’ → S
[1] S → i := E
[2] E → E+T
[3] E → E-T
[4] E → T
[5] T → T*F
[6] T → T/F
[7] T →F
[8] F→ (E)
[9] F→ i
通过手工计算或算法构造,判断该文法是否SLR(1)文法。若是,设计出相应的SLR(1)分析表。并实现赋值语句的SLR(1)语法分析器。
1. 输入:是词法分析输出的二元组序列,即任意简单算术表达式经过专题1程序输出后得到的结果。【上述文法中i即对应词法分析的标识符, +-*/分别对应词法分析得到的运算符】
2. 处理:基于分析表进行 SLR(1)语法分析,有出错信息。
3. 输出:打印分析过程,并判断输入串是否合法。
源代码
action={0:{'id':'s2'},
1:{'$':'Acc'},
2:{':':'s17'},
3:{'(':'s7','id':'s8'},
4:{'+':'s9','$':'r1','-':'s18'},
5:{'+':'r4','-':'r4','*':'s10','/':'s11','$':'r4',')':'r4'},
6:{'+':'r7','-':'r7','*':'r7','/':'r7','$':'r7',')':'r7'},
7:{'(':'s7','id':'s8'},
8:{'+':'r9','-':'r9','*':'r9','/':'r9','$':'r9',')':'r9'},
9:{'(':'s7','id':'s8'},
10:{'(':'s7','id':'s8'},
11:{'(':'s7','id':'s8'},
12:{'+':'s9',')':'s16','-':'s18'},
13:{'+':'r2','-':'r2','*':'s10','/':'s11','$':'r2',')':'r2'},
14:{'+':'r5','-':'r5','*':'r5','/':'r5','$':'r5',')':'r5'},
15:{'+':'r6','-':'r6','*':'r6','/':'r6','$':'r6',')':'r6'},
16:{'+':'r8','-':'r8','*':'r8','/':'r8','$':'r8',')':'r8'},
17:{'=':'s3'},
18:{'(':'s7','id':'s8'},
19:{'+':'r3','-':'r3','*':'s10','/':'s11','$':'r3',')':'r3'}}
goto={0:{'S':1},
3:{'E':4,'T':5,'F':6},
7:{'E':12,'T':5,'F':6},
9:{'T':13,'F':6},
10:{'F':14},
11:{'F':15},
18:{'T':19,'F':6}
}
ss={'s0':0,'s1':1,'s2':2,'s3':3,'s4':4,'s5':5,'s6':6,'s7':7,'s8':8,'s9':9,'s10':10,'s11':11,'s12':12,'s13':13,'s14':14,'s15':15,'s16':16,'s17':17,'s18':18,'s19':19}
rs={'r0':[1,'S`'],'r1':[4,'S'],'r2':[3,'E'],'r3':[3,'E'],'r4':[1,'E'],'r5':[3,'T'],'r6':[3,'T'],'r7':[1,'T'],'r8':[3,'F'],'r9':[1,'F']}
def analise(lis):
stack=[0]
word=[]
i=1
while i<len(lis):
first=lis[i].split(',')[0][1:]
second=lis[i].split(',')[1][0]
if first =='id':
word.append('id')
else:
word.append(second)
i+=1
word.append('$')
print('{:<80}{:<80}'.format("栈", "句子"))
try:
while len(word)>0:
word_st = stack[0]
word1 = word[0]
print('{:<80}{:<80}'.format(str(stack),str(word)))
if action[word_st][word1] == 'Acc':
return True
if action[word_st][word1][0]=='s':
stack.insert(0,word1)
stack.insert(0,ss[action[word_st][word1]])
word.pop(0)
else:
i = rs[action[word_st][word1]][0]*2
while i > 0:
stack.pop(0)
i -= 1
stack.insert(0,rs[action[word_st][word1]][1])
stack.insert(0,goto[stack[1]][stack[0]])
except:
return False
return False
def main():
with open('demo3.txt',encoding='utf-8') as words:
contents = words.read()
first_w = contents.split('\n') #将文件内句子拆分
list1=[]
list2=[]
list3=[]
list4=[]
list5=[]
list6=[]
i=0
n=0
while i<len(first_w):
if first_w[i]=='1、':
for j in range(i+1,len(first_w)):
if first_w[j] == '2、':
n=j
break
list1.append(first_w[j])
if first_w[i]=='2、':
for j in range(i+1,len(first_w)):
if first_w[j] == '3、':
n=j
break
list2.append(first_w[j])
if first_w[i]=='3、':
for j in range(i+1,len(first_w)):
if first_w[j] == '4、':
n=j
break
list3.append(first_w[j])
if first_w[i]=='4、':
for j in range(i+1,len(first_w)):
if first_w[j] == '5、':
n = j
break
list4.append(first_w[j])
if first_w[i]=='5、':
for j in range(i+1,len(first_w)):
if first_w[j] == '6、':
n = j
break
list5.append(first_w[j])
if first_w[i]=='6、':
for j in range(i+1,len(first_w)):
list6.append(first_w[j])
n=len(first_w)
i=n
try:
if analise(list2):
print("语法正确!")
else:
print("语法错误!")
except:
print("语法错误!")
main()
测试案例
1、
j:=k-m+m
<id,j>
<operator,:>
<operator,=>
<id,k>
<operator,->
<id,m>
<operator,+>
<id,m>
2、
i:=i+i
<id,i>
<operator,:>
<operator,=>
<id,i>
<operator,+>
<id,i>
3、
i:=i*((i-i))/(i+i)
<id,i>
<operator,:>
<operator,=>
<id,i>
<operator,*>
<delimiter,(>
<delimiter,(>
<id,i>
<operator,->
<id,i>
<delimiter,)>
<delimiter,)>
<operator,/>
<delimiter,(>
<id,i>
<operator,+>
<id,i>
<delimiter,)>
4、
i:=(i+i(
<id,i>
<operator,:>
<operator,=>
<delimiter,(>
<id,i>
<operator,+>
<id,i>
<delimiter,(>
5、
i:=i*(i-i)/i
<id,i>
<operator,:>
<operator,=>
<id,i>
<operator,*>
<delimiter,(>
<id,i>
<operator,->
<id,i>
<delimiter,)>
<operator,/>
<id,i>
6、
i:=i+-i
<id,i>
<operator,:>
<operator,=>
<id,i>
<operator,+>
<operator,->
<id,i>
部分结果
案例二