系统维持一个分析表和一个分析栈,根据当前扫描到的符号,选择当前语法变量(处于栈顶)的候选式进行推导——希望找到相应的输入符号串的最左推导
本程序使用文法G为:
E → E+T | T
T → T*F | F
F → (E) | i
消除左递归:
E → TE’
E’ → +TE’ | ε
T → FT’
T’ → *FT’ | ε
F → (E) | i
可以求得:
FIRST(TE’)={(,id} FIRST(+TE’)={+}
FIRST(FT’)={(,id} FIRST(FT’)={}
FIRST((E))={(} FIRST(id)={id}
FOLLOW( E’)={ ), # }
FOLLOW( T’)={ +, ), # }
表达式文法的预测分析表为:
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 21 20:54:57 2020
@author: 侯明会
"""
#文法G为:E → E+T | T
# T → T*F | F
# F → (E) | i
#消除左递归:E → TE'
# E' → +TE' | ε
# T → FT'
# T' → *FT' | ε
# F → (E) | i
#FOLLOW( E')={ ), # }; FOLLOW( T')={ +, ), # };
#FIRST(TE')={(,id}; FIRST(id)={id}; FIRST(+TE')={+};
#FIRST(FT')={(,id}; FIRST(*FT')={*}; FIRST((E))={(}
def error():
print("failed to match!")
def display(buffer,stack):
list=['#']
while buffer!=list or stack!=list:
m=stack[-1]
stack.pop()
b=buffer[0]
if m=='E':
if b=='i' or b=='(':
stack.append('E1')
stack.append('T')
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack)+" 输出:E->TE'")
elif b=='+' or b=='*' or b==')' or b=='#':
error()
break
elif m=='E1':
if b=='i' or b=='*' or b=='(':
error()
break
elif b=='+':
stack.append('E1')
stack.append('T')
stack.append('+')
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack)+" 输出:E'->+TE'")
elif b==')' or b=='#':
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack)+" 输出:E'->ε")
elif m=='T':
if b=='i' or b=='(':
stack.append('T1')
stack.append('F')
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack)+" 输出:T->FT'")
elif b=='+' or b=='*' or b==')' or b=='#':
error()
break
elif m=='T1':
if b=='i' or b=='(':
error()
break
elif b=='+' or b==')' or b=='#':
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack)+" 输出:T'->ε")
elif b=='*':
stack.append('T1')
stack.append('F')
stack.append('*')
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack)+" 输出:T'->*FT'")
elif m=='F':
if b=='i':
stack.append('i')
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack)+" 输出:F->i")
elif b=='+' or b=='*' or b==')' or b=='#':
error()
break
elif b=='(':
stack.append(')')
stack.append('E')
stack.append('(')
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack)+" 输出:F->(E)")
elif m=='i' or m=='+' or m=='*' or m=='(' or m==')':
if m==b:
buffer.pop(0)
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack))
if __name__=='__main__':
s=input('请输入以#结尾的字符串:')
buffer=list(s)#输入缓冲区
stack=['#','E']#栈
print("输入缓冲区:"+str(buffer)+" 栈:"+str(stack))
display(buffer,stack)
实验结果