杭电编译原理专题五(python实现)

语法制导翻译技术实现中间代码生成

目录

                实验目的

                实验内容

                源代码 

                测试案例

                部分结果


 

实验目的

1. 掌握语法制导翻译的相关基本概念

2. 熟悉作为中间代码形式的三地址代码

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

通过设计赋值语句转换为三地址代码的语法制导定义【课件或教材中均有相关参考案例】,对专题4的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']}

ID={'F':{},'E':{},'T':{},'id':{}}
'''
[0]	S’ → S   
[1]	S → i := E      emit(id:=E.place)
[2]	E → E1+T1       E.place:=newtemp
                    emit(E.place:=E1.place+T1.place:)
[3]	E → E1-T1       E.place:=newtemp
                    emit(E.place:=E1.place-T1.place:)
[4]  E → T1         E.place:=T1.place
[5]  T → T1*F1      T.place:=newtemp
                    emit(E.place:=T1.place*F1.place:)
[6]  T → T1/F1      T.place:=newtemp
                    emit(E.place:=T1.place/F1.place:)
[7]	T →F1           T.place:=F1.place
[8]  F→ (E1)        F.place:=E1.place
[9]  F→ i           F.place:=id
'''

#生成中间变量
newtemp=[]
def mk_newtemp():
    i=len(newtemp)
    i+=1
    t="t%s"%i
    newtemp.append(t)
    return t

#插入符号表中
def insert_ID(word,val=None):
    if word=='id':
        i=len(ID['id'])+1
        t="id%s"%i
        ID['id'][t]={}
        ID['id'][t]['val']=val
        return t
    if word=='F':
        i = len(ID['F']) + 1
        t = "F%s" % i
        ID['F'][t]={}
        ID['F'][t]['val'] = val
        return t
    if word=='T':
        i = len(ID['T']) + 1
        t = "T%s" % i
        ID['T'][t]={}
        ID['T'][t]['val'] = val
        return t
    if word=='E':
        i = len(ID['E']) + 1
        t = "E%s" % i
        ID['E'][t]={}
        ID['E'][t]['val'] = val
        return t

#规则处理
def regulate(oder,lis):
    if oder=='r1':
        print('id:=',ID['E'][lis[0]]['val'])
        rs1='S'
        rs2='S'
        return rs1, rs2
    if oder=='r2':
        t=mk_newtemp()
        val="{0}+{1}".format(ID['E'][lis[2]]['val'],ID['T'][lis[0]]['val'])
        print(t,'=',val)
        rs1 = insert_ID('E',t)
        rs2='E'
        return rs1, rs2
    if oder=='r3':
        t = mk_newtemp()
        val = "{0}-{1}".format(ID['E'][lis[2]]['val'], ID['T'][lis[0]]['val'])
        print(t, '=', val)
        rs1 = insert_ID('E', t)
        rs2='E'
        return rs1, rs2
    if oder=='r4':
        val = "{0}".format(ID['T'][lis[0]]['val'])
        rs1 = insert_ID('E', val)
        rs2='E'
        return rs1, rs2
    if oder=='r5':
        t = mk_newtemp()
        val = "{0}*{1}".format(ID['T'][lis[2]]['val'], ID['F'][lis[0]]['val'])
        print(t, '=', val)
        rs1 = insert_ID('T', t)
        rs2='T'
        return rs1, rs2
    if oder=='r6':
        t = mk_newtemp()
        val = "{0}/{1}".format(ID['T'][lis[2]]['val'], ID['F'][lis[0]]['val'])
        print(t, '=', val)
        rs1 = insert_ID('T', t)
        rs2='T'
        return rs1, rs2
    if oder=='r7':
        val = "{0}".format(ID['F'][lis[0]]['val'])
        rs1 = insert_ID('T', val)
        rs2='T'
        return rs1, rs2
    if oder=='r8':
        val = "{0}".format(ID['E'][lis[1]]['val'])
        rs1 = insert_ID('F', val)
        rs2='F'
        return rs1, rs2
    if oder=='r9':
        val = "{0}".format(ID['id'][lis[0]]['val'])
        rs1 = insert_ID('F', val)
        rs2='F'
        return rs1, rs2

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':
            t=insert_ID('id',second)
            word.append(t)
        else:
            word.append(second)
        i+=1
    word.append('$')
    print(word)
    while len(word) > 0:
        word_st = stack[0]
        word1 = word[0]
        word_r = []  # 保存归约的句子
        # 归约时按原处理
        if 'id' in word1:
            word1 = 'id'
        if 'F' in str(word_st):
            word_st = 'F'
        if 'T' in str(word_st):
            word_st = 'T'
        if 'E' in str(word_st):
            word_st = 'E'

        if action[word_st][word1] == 'Acc':
            return True
        if action[word_st][word1][0] == 's':
            stack.insert(0, word[0])
            stack.insert(0, ss[action[word_st][word1]])
            word.pop(0)
        else:
            i = rs[action[word_st][word1]][0] * 2
            for j in range(1,i,2):
                word_r.append(stack[j])
            while i > 0:
                stack.pop(0)
                i -= 1
            rs1,rs2=regulate(action[word_st][word1],word_r)
            stack.insert(0, rs1)
            stack.insert(0, goto[stack[1]][rs2])
    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(list1):
            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>

部分结果

案例五

 3dae1651d965437c94d59599428d3553.png

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
杭州电子科技大学编译原理实验sysy是一个基于SysY语言的编译器实验项目。SysY是一种具有C语言风格的高级语言,旨在让学生通过实践来深入理解编译原理的基本概念和核心技术。 在这个实验项目中,我们需要实现一个能够将SysY代码转换为RISC-V汇编代码的编译器。具体而言,编译器需要完成词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等多个阶段的工作。 首先,词法分析阶段负责对SysY代码进行扫描,将代码划分为一个个的词素,并进行词法分析,生成词法单元。 接下来,语法分析阶段将词法单元按照SysY语言的语法规则进行组织,生成抽象语法树。语法分析是编译过程中的核心环节,它确保了代码的结构符合语法规定。 然后,在语义分析阶段,我们检查抽象语法树中的语义错误,并进行类型检查和作用域分析等。这一阶段可以确保代码在语义上是正确的。 接下来,编译器需要利用抽象语法树生成中间代码。中间代码是一种介于源代码和目标代码之间的代码表示形式,它可以简化后续的代码优化和目标代码生成。 然后,在代码优化阶段,我们可以对中间代码进行一系列优化操作,以提高代码的执行效率。常见的优化包括常量折叠、公共子表达式消除、死代码消除等。 最后,在目标代码生成阶段,我们将经过优化的中间代码转换为RISC-V汇编代码。目标代码生成需要将抽象的中间代码转化为具体的机器指令,以便在计算机硬件上执行。 总之,杭电编译原理实验sysy是一个涵盖词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等多个阶段的编译器实验项目。通过完成这个项目,学生可以深入理解编译原理的各个方面,并且掌握实际编译器的构建过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江不厌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值