【编译原理-专题三】LL语法分析

程序功能描述

针对CP语言中简单算术表达式文法G[E]:
E→TE’
E’→ATE’|ε
T→FT’
T’→MFT’ |ε
F→(E) | i
A → + | -
M → * | /
打印出对应的FIRST、FOLLOW集,构造预测分析表,并编写LL(1)语法分析程序,并给出测试句子的分析过程。
能够根据表达式文法构造出fist集,follow集,和预测表。并且能够对输入的表达式给出分析过程,并且判断是否为LL语法。

主要数据结构描述

Firstbox、followbox字典:构建元素映射到多个元素(集合)的字典
ss栈:分析过程中的分析表
数组:存储y数据

设计方法

  • LL:左扫描,左推导。
    1.从文件或其他方式导入\储存文法(实质就是几行符号流) 并把其中的终结字符和非终结字符存在数组\列表里
    2.把文法每行的“或”(|)切分成两个即A->B|C 切分为A->B和A->C
  • 求FIRST集的算法思想
    若X->a…,则将终结符a加入FIRST(X)中;
    若X->e ,则将终结符e加入FIRST(X)中(e表示空集);
    若 X->BCD…E,则将First(B)所有元素(除了空集)加入 First(X),然后检测First(B),若First(B)中不存在空集, 即e,则停止,若存在则向B的后面查看,将First(C)中所有元素(除了空集)加入First(X),然后再检测First(C)中是否有e…直 到最后,若E之前的所有非终结符的First集中都含有e,则检测到E时,将First(E)也加入First(X),若First(E)中含有e,则将 e加入First(X)。
  • 求FOLLOW集的算法思想
    对于文法G中每个非终结符A构造FOLLOW(A)的办法是,连续使用下面的规则,直到每个FOLLOW不在增大为止.
    (1) 对于文法的开始符号S,置#于FOLLOW(S)中;
    (2) 若A->aBb是一个产生式,则把FIRST(b){ε}加至FOLLOW(B)中;
    (3) 若A->aB是一个产生式,或A->aBb是一个产生式而b=>ε(即ε∈FIRST(b))则把FOLLOW(A)加至FOLLOW(B)中
  • 生成预测分析表的算法思想
    构造分析表M的算法是:
    (1) 对文法G的每个产生式A->a执行第二步和第三步;
    (2) 对每个终结符a∈FIRST(a),把A->a加至M[A,a]中;
    (3) 若ε∈FIRST(a),则把任何b∈FOLLOW(A)把A->a加至M[A,b]中;
  • 对符号串的分析过程
    预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号行事的,对于任何(X,a),总控程序
    每次都执行下述三种可能的动作之一;
    (1) 若X=a=‘符号’,则宣布分析成功,停止分析过程.
    (2) 若X=a≠”$”,则把X从STACK栈顶逐出,让a指向下一个输入符号.
    (3) 若X是一个非终结符,则查看分析表M,若M[A,a]中存放着关于X的一个产生式,那么,首先把X逐出STACK栈顶,然后
    把产生式的右部符号串按反序一一推进STACK栈(若右部符号为ε,则意味着不推什么东西进栈).在把产生式的右部

函数定义

Fist(item)函数,在切分后的文法中 如果A->a…… (a为终结字符)则把a放入A的follow中 如果A->B ……(B为非终结) 则先递归求B的first,然后放入A的first。

def first(item): 
    if item[1] in vt:
        firstbox[item[0]].add(item[1])
    else:
        for find in stack:
            if find[0]==item[1]:
                first(find)
            firstbox[item[0]] = firstbox[item[1]]|firstbox[item[0]]

follow(vi_item)和函数。
存在 ……Ab(b为非终结),则把b放入A的follow ;存在AB(B为非终结),则把B的first放入A的follow;存在B=EAC,且C的first中含有‘ε’,则把B的follow放入A的follow;若A为某段的最后字符,则把‘$’放入A的follow;若B=……A,则把B的follow放入A的follow

def follow(vi_item):
    for i in stack:
        j=1
        while j<len(i)-1:
            if (i[j]==vi_item)&(i[j+1] in vt): # 存在 Ab 则把b放入
                followbox[vi_item].add(i[j+1])
            if (i[j]==vi_item)&(i[j+1] in vi): #存在AB 则把B的first放入
                followbox[vi_item]=followbox[vi_item]|firstbox[i[j+1]]-{
   'ε'}
            if (i[j] in vi)&('ε' in firstbox[i[j+1]]): #存在 A=EBC 且C的first中有空
                followbox[i[j]]=followbox[i[0]]|followbox[i[j]]
            j+=1
        if i[len(i)-1] ==vi_item:#为某行最后一个字符
            followbox[vi_item].add('$')  
        if (i[0]==vi_item)&(i[len(i)-1] in vi):#A=....B
            followbox[i[len(i)-1]]=followbox[vi_item
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值