Python求first 和follow 集


FIRST = {}

FOLLOW = {}

sentences = [
'E->TG',
'G->+TG',
'G->-TG',
'G->ε',
'T->FS',
'S->*FS',
'S->/FS',
'S->ε',
'F->(E)',
'F->i',]

#初始化 first 集 和follow集合字典的键值对中的 值 为空
def initail():
    for str  in sentences :
        part_begin = str.split("->")[0]
        part_end = str.split("->")[1]
        FIRST[part_begin] = ""
        FOLLOW[part_begin] = "#"


###求first集 中第第一部分针对 ->  直接推出第一个字符为终结符 部分
def getFirst():
    for str in sentences:
        part_begin = str.split("->")[0]
        part_end = str.split("->")[1]
        if not part_end[0].isupper():
            FIRST[part_begin] = FIRST.get(part_begin) + part_end[0]

##求first第二部分 针对 A -> B型  把B的first集加到A 的first集合中
def getFirst_2():
    for str in sentences:
        part_begin = ''
        part_end = ''
        part_begin += str.split('->')[0]
        part_end += str.split('->')[1]
        ##如果型如A ->B 则把B的first集加到A 的first集中去
        if part_end[0].isupper():
            FIRST[part_begin] = FIRST.get(part_begin) + FIRST.get(part_end[0])


def   getFisrt_3():
    while(1):
        test = FIRST
        getFirst_2()
        ##去除重复项
        for i , j  in FIRST.items():
            temp = ""
            for word in list(set(j)):
                temp += word
            FIRST[i] = temp
        if test == FIRST:
            break


def   getFOLLOW_3():
    while(1):
        test = FOLLOW
        getFollow()
        ##去除重复项
        for i , j  in FOLLOW.items():
            temp = ""
            for word in list(set(j)):
                temp += word
            FOLLOW[i] = temp
        if test == FOLLOW:
            break

##计算follow集的第一部分,先计算 S -> A b 类型的
def getFollow():
    for str in sentences:
        part_begin = str.split("->")[0]
        part_end = str.split("->")[1]
        ##如果是 S->a 直接推出终结符 则 continue
        if len(part_end) == 1:
            continue
        ##否则执行下面的操作
        else:
            #将->后面的分开再倒序
            temp = []
            for i in part_end:
                temp.append(i)
            temp.reverse()
            #如果非终结符在句型的末端则把"#" 加入进去
            if temp[0].isupper() :
                FOLLOW[temp[0] ]= FOLLOW.get(temp[0]) + FOLLOW.get(part_begin)
                temp1 = temp[0]
                for i in temp[1:]:
                    if not i.isupper():
                        temp1 = i
                    else:
                        if temp1.isupper():
                            FOLLOW[i] = FOLLOW.get(i) + FIRST.get(temp1).replace("ε","")
                        if ('ε' in FIRST.get(temp1)):
                            FOLLOW[i] = FOLLOW.get(i) + FOLLOW.get(part_begin)
                        else:
                            FOLLOW[i] = FOLLOW.get(i) + temp1
                        temp1 = i
            # 如果终结符在句型的末端
            else:
                temp1 = temp[0]
                for i in temp[1:]:
                    if not i.isupper():
                        temp1 = i
                    else:
                        if temp1.isupper():
                            FOLLOW[i] = FOLLOW.get(i) + FIRST.get(temp1)
                        else:
                            FOLLOW[i] = FOLLOW.get(i) + temp1
                        temp1 = i

initail()
getFirst()
getFisrt_3()
getFisrt_3()
#print(  FIRST )
getFOLLOW_3()
getFOLLOW_3()
#print(FOLLOW)

for i ,j in FIRST.items() :
    str = j[0]
    for temp in j[1:]:
        str = str+ ',' +temp
    print("FIRST("+ i + ")" + " = {"+str+"}")

for i ,j in FOLLOW.items():
    str = j[0]
    for temp in j[1:]:
        str = str + ',' + temp
    print("FOLLOW("+ i + ")" + " = {"+str+"}")

在这里插入图片描述

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值