python | 編譯原理,語法分析——LL(1)文法實現 中

上一個文章實現了對LL(1)文法各非終結符求first集和follow集,我們這篇文章則是繼續求得LL(1)的預測分析集。

看一下預測分析集的求解方法:
在這裏插入圖片描述
這裏我們需要求對於一個串的first集,求解方法如下:

任意符號α的FIRST集求法:
1. α爲終結符,則把它自身加入FIRSRT(α)
2. α爲非終結符,則:
(1)若存在產生式α->a...,則把a加入FIRST(α),其中a可以爲ε
(2)若存在一串非終結符Y1,Y2, ..., Yk-1,且它們的FIRST集都含空串,且有產生式α->Y1Y2...Yk...,那麼把FIRST(Yk)-{ε}加入FIRST(α)。如果k-1抵達產生式末尾,那麼把ε加入FIRST(α)
   注意(2)要連續進行,通俗地描述就是:沿途的Yi都能推出空串,則把這一路遇到的Yi的FIRST集都加進來,直到遇到第一個不能推出空串的Yk爲止。
重複1,2步驟直至每個FIRST集都不再增大爲止。

這地方借鑑自:【編譯原理】語法分析LL(1)分析法的FIRST和FOLLOW集

通過這一步驟編寫求一個串的first集合:

dirFirst = defaultdict(set)
def getDirFirst(curPro):
   res = []
   # 對於一個字符串求first集
   for i in range(1,len(curPro)):
       if curPro[i] in vt:
           res.append(curPro[i])
           break
       elif curPro[i] in vn:
           if 'epsilon' in first[curPro[i]]:
               res.extend(first[curPro[i]])
           else:
               res.extend(first[curPro[i]])
               break
   # 去重
   ress = []
   for i in res:
       if i not in ress:
           ress.append(i)
   return ress

對於文法G的每個產生式 A->α ,進行如下處理
(1)對於FIRST(α)中每個終結符號a,將 A->α 加入到 M[A,a] 中。
(2)如果 ε在FIRST(α)中,那麼對於FOLLOW(A)中每個終結符號b,將 A->α 加入到 M[A,b] 中。如果 ε在FIRST(α),且FOLLOW(A)A>αM[A,在FOLLOW(A)中,也將 A->α 加入到 M[A,] 中。

求預測分析表:
1.先構建一個這樣的表
在這裏插入圖片描述
2.然後依次填入非終結符號
在這裏插入圖片描述
3.按照規則1填寫其餘內容
在這裏插入圖片描述
4.按照規則2填寫內容
在這裏插入圖片描述
至此整個構建全部完成

此處借鑑自:FIRST集合、FOLLOW集合以及LL(1)文法

預測分析表中我們爲了兩個字符串作爲兩維表的索引,利用pandas中的DataFrame存儲表格信息。

dfData = [[[] for i in range(len(vt))] for i in range(len(vn))]
M = pd.DataFrame(data = dfData,index=vn,columns=vt)
# print(M)
# print(M.loc['E']['+'])
def getM():
    #step1
    for curPro in productions:
        A = curPro[0]
        dirFirst = getDirFirst(curPro)
        # print(A)
        # print(dirFirst)
        for a in dirFirst:
            if a=='epsilon':
                continue
            M.loc[A][a].append(curPro)
    #step2
    for curPro in productions:
        A = curPro[0]
        dirFirst = getDirFirst(curPro)
        # print(curPro)
        # print(' ',dirFirst)
        if 'epsilon' in dirFirst:
            for b in follow[A]:
                M.loc[A][b].append(curPro)
getM()
print(M)

運行結果爲:

id               (                )                 +  \                   * epsilon                $  
E   [[E, T, E']]    [[E, T, E']]               []                []                   []      []               []  
T   [[T, F, T']]    [[T, F, T']]               []                []                    []      []               []  
E'            []              []  [[E', epsilon]]  [[E', +, T, E']]                   []      []  [[E', epsilon]]  
T'            []              []  [[T', epsilon]]   [[T', epsilon]]   T [[T', *, F, T']]      []  [[T', epsilon]]  
F      [[F, id]]  [[F, (, E, )]]               []                []                    []      []               []  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章