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

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>

部分结果

案例二

 

07b18b1116ac4d5eba47f726912fe0e9.png

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 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、付费专栏及课程。

余额充值