编译原理——SLR(1)分析过程

编译原理——SLR(1)分析过程

编译原理课程上的一次实验

程序中手动建立了ACTION表GOTO表(为什么不用项目集的方法?答:因为本小白能力不足没能搞出来。咳咳,重点是体会分析过程)。

实现对指定txt文件中文法的分析,并对输入的字符串(这里不需要手动输入,输入串**‘i+i*i#’**已在程序内)进行过程分析。

有问题可留言或私聊讨论哈~

txt文件内容:

S->E
E->E+T 
E->T 
T->T*F 
T->F 
F->(E) 
F->i

源代码:

NN=[]
#自然树集合:
for i in range(100):
    NN.append(str(i))
#定义终结符:
VT=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','+','_','*',"/",'(',')','#']

#定义非终结符:
VN=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z" ]

#终结符匹配函数:
def VT_matching(p):
    for word in VT:
        if p==word:
            return 1

#非终结符匹配函数:
def VN_matching(p):
    for word in VN:
        if p==word:
            return 1


#从文件提取文法:
with open(r'D:\PC\txt\SLR(1).txt') as f:
    predictions = []                  #使用predictions来记录所有文法,以列表的形式
    while True:
        line=f.readline().split()             #按行读取并去掉空格
        predictions=predictions+line
        if not line:break
    print("文法(predictions)为:",predictions)

#扫描非终结符:
Vn=[]      #Vn是非终结符列表
Vn_copy=[]
for prediction in predictions:
    p=prediction      #p是一个字符串
    if (VN_matching(p[0])==1):
        Vn.append(p[0])
for i in Vn:
    if(i not in Vn_copy):
        Vn_copy.append(i)
Vn=Vn_copy
print("文法中的非终结符(Vn)为:",Vn)

#扫描终结符:
Vt=["#"]      #Vt是终结符列表,初始化时就有#
for prediction in predictions:     #prediction是一个字符串
    for t in prediction:
        if (VT_matching(t)==1 ):
            Vt.append(t)
            set(Vt)      #set语句去除Vt中的重复元素
print("文法中的终结符(Vt)为:",Vt)

#建立文法字典Prediction_dic{}:
Prediction_dic={}
def PREDICTION_DIC():
    global Prediction_dic
    c=0
    d=0
    rn=""
    R=[]
    while (d<len(predictions)):
        rn="r"+str(d)
        R.append(rn)
        d+=1
    P={}      #函数内的文法字典,便于建立后直接赋予Prediction_dic
    while (c<len(predictions)):
        P[R[c]]=predictions[c]
        c+=1
    Prediction_dic=P.copy()

PREDICTION_DIC()
print("文法序号字典(Prediction_dic)为:",Prediction_dic)

Action_col={
    'i':0,
    '+':1,
    '*':2,
    '(':3,
    ')':4,
    '#':5
}
print("终结符字典(Action_col)为:",Action_col)

Goto_col={
    'E':0,
    'T':1,
    'F':2
}
print("非终结符字典(Goto_col)为",Goto_col)

#初始化ACTION
ACTION=[["None"]*6 for i in range(12)]
ACTION[0][0]='5'
ACTION[0][3]='4'
ACTION[1][1]='6'
ACTION[1][5]='acc'
ACTION[2][1]='r2'
ACTION[2][2]='7'
ACTION[2][4]='r2'
ACTION[2][5]='r2'
ACTION[3][1]='r4'
ACTION[3][2]='r4'
ACTION[3][4]='r4'
ACTION[3][5]='r4'
ACTION[4][0]='5'
ACTION[4][3]='4'
ACTION[5][1]='r6'
ACTION[5][2]='r6'
ACTION[5][4]='r6'
ACTION[5][5]='r6'
ACTION[6][0]='5'
ACTION[6][3]='4'
ACTION[7][0]='5'
ACTION[7][3]='4'
ACTION[8][1]='6'
ACTION[8][4]='11'
ACTION[9][1]='r1'
ACTION[9][2]='7'
ACTION[9][4]='r1'
ACTION[9][5]='r1'
ACTION[10][1]='r3'
ACTION[10][2]='r3'
ACTION[10][4]='r3'
ACTION[10][5]='r3'
ACTION[11][1]='r5'
ACTION[11][2]='r5'
ACTION[11][4]='r5'
ACTION[11][5]='r5'
print("ACTION:",ACTION)

#初始化GOTO
GOTO=[["None"]*3 for i in range(12)]
GOTO[0][0]='1'
GOTO[0][1]='2'
GOTO[0][2]='3'
GOTO[4][0]='8'
GOTO[4][1]='2'
GOTO[4][2]='3'
GOTO[6][1]='9'
GOTO[6][2]='3'
GOTO[7][2]='10'
print("GOTO",GOTO)

def DeleteLF(s):
    temp=''
    d=1
    while (d<len(s)):
        temp=temp+s[d]
        d=d+1
    s=temp
    return s


#string=['i','+','i','*','i','#']      #输入字符串
string='i+i*i#'
SStack=[0]      #初始化状态栈
CStack=['#']      #初始化符号栈
action=''      #记录ACTION
goto=''      #单字符记录GOTO

def PROCESS():
    global string
    global action
    global goto
    #步骤一的初始化
    char=string[0]      #记录输入的第一个字符
    print("分析开始:")
    print("步骤 1 : ")
    print("状态栈:",SStack)
    print("符号栈:",CStack)
    print("输入串:",string)
    action=ACTION[SStack[len(SStack)-1]][Action_col.get(char)]  # 状态栈末位和输入串首位匹配,结果输入action
    print("action:", action)
    print("goto:", goto)
    step=2
    #while (SStack != ['#', 'E'] or CStack!= ['#']):      #结束循环条件
    while (1):
        print("步骤",step,":")
        if (action in NN):      #若上一步骤action是一个状态(自然数):
            SStack.append(action)  # 结束后action进入状态栈末尾
            CStack.append(string[0])      #输入串周字符进入符号栈
            string=DeleteLF(string)      #删除输入的首字符
            char=string[0]
            action=ACTION[int(SStack[len(SStack)-1])][int(Action_col.get(char))]      #状态栈末位和输入串首位匹配,结果输入action
            if action[0]=='r':      #若本步骤action已经是r.编写goto
                pre=Prediction_dic.get(action)      #调出文法
                left=pre.split('->')[0]      #文法左部
                right=pre.split('->')[1]      #文法右部
                l=len(right)      #l记录文法右部长度
                goto=int(GOTO[int(SStack[len(SStack)-l-1])][Goto_col.get(left)])      #计算出goto,got这里为整型
        else :      #剩下的,若上一步骤的action为文法序号r
            #goto入栈
            #char=string[0]
            pre=Prediction_dic.get(action)     #调出文法
            left=pre.split('->')[0]      #文法左部
            right=pre.split('->')[1]      #文法右部
            l=len(right)      #l记录文法右部长度
            #以下为符号栈的出栈:
            d=0
            while (d<l):      #l有多少位
                CStack.pop()      #删除符号栈最后一个元素
                d=d+1
            #以下为符号栈的入栈:
            CStack.append(left)
            #以下为状态栈的出栈:
            c=0
            while (c<l):
                SStack.pop()
                c=c+1
            #以下为状态栈的入栈:
            SStack.append(goto)
            action=action=ACTION[SStack[int(len(SStack)-1)]][Action_col.get(char)]
            if (action in NN):      #若本步骤的action值是一个数字
                goto=''      #goto值设置为空
            elif (action!='acc'):      #若action不为接受
                pre=Prediction_dic.get(action)      #调出文法
                left=pre.split('->')[0]  # 文法左部
                right=pre.split('->')[1]  # 文法右部
                l=len(right)  # l记录文法右部长度
                goto=int(GOTO[int(SStack[len(SStack)-l-1])][Goto_col.get(left)])      #计算出goto,这里为整型
            else:      #action='acc'
                print("状态栈:", SStack)
                print("符号栈:", CStack)
                print("输入串:", string)
                print("action:", action)
                break
        step+=1
        print("状态栈:", SStack)
        print("符号栈:", CStack)
        print("输入串:", string)
        print("action:",action)
        print("goto:",goto)
    print("分析结束!")
PROCESS()

运行截图(部分):

发布了5 篇原创文章 · 获赞 2 · 访问量 241

猜你喜欢

转载自blog.csdn.net/Mo_Shao/article/details/104195354