LL(1)文法-------python實現


廢話不多說直接開干!

對文法G的句子進行確定的自頂向下語法分析的充分必要條件是,G的任意兩個具有相同左部的
產生式A—>α|β 滿足下列條件:
(1)如果α、β均不能推導出ε,則 FIRST(α) ∩ FIRST(β) = ∅。
(2)α 和 β 至多有一個能推導出 ε。
(3)如果 β *═> ε,則 FIRST(α) ∩ FOLLOW(A) = ∅。
將滿足上述條件的文法稱為LL(1)文法。
 
 
概要
第一個L代表從左向右掃描輸入符號串,第二個L代表產生最左推導,1代表在分析過程中執行每一步推導都要向前查看一個輸入符號——當前正在處理的輸入符號。
LL(1)文法既不是二義性的,也不含左遞歸,對LL(1)文法的所有句子均可進行確定的自頂向下語法分析。
需要注意的是,並不是所有的語言都可以用LL(1)文法來描述,而且不存在判定某語言是否是LL(1)文法的算法。也就是說,確定的自頂向下分析只能實現一部分上下文無關語言的分析,這就是LL(1)文法所產生的語言。另外,在上述LL(1)文法的條件中,要求:ε ∈ FIRST(α1),ε ∈ FIRST(α2),…ε ∈ FIRST(αn) 中至多有一個成立。——————來自百度百科
 
直接代碼開搞,首先舉個栗子!
處理好之后的文法:
 

 

 然后經過各種推到最后得到

 

 上面那個分析表

萬事具備,開始制造東風

直接來個代碼

  1 import copy
  2 
  3 strs = ['#', 'E']  # 當做棧來使用,棧是先進后出那我就從-1開始
  4 list1 = [['E->TE\'', '', '', '', '', 'E->TE\'', '', ''],
  5          ['', 'E\'->ATE\'', 'E\'->ATE\'', '', '', '', 'E\'->ε', 'E\'->ε'],
  6          ['T->FT\'', '', '', '', '', 'T->FT\'', '', ''],
  7          ['', 'T\'->ε', 'T\'->ε', 'T\'->MFT\'', 'T\'->MFT\'', '', 'T\'->ε', 'T\'->ε'],
  8          ['F->i', '', '', '', '', 'F->(E)', '', ''],
  9          ['', 'A->+', 'A->-', '', '', '', '', ''],
 10          ['', '', '', 'M->*', 'M->/', '', '', '']
 11          ]
 12 list2 = ['E', 'E\'', 'T', 'T\'', 'F', 'A', 'M']
 13 list3 = ['i', '+', '-', '*', '/', '(', ')', '#']
 14 s1 = ''  # 全局變量s1
 15 
 16 
 17 def out1():
 18     print("分析棧\t\t余留輸入串\t\t分析表中產生式")
 19 
 20 
 21 def out2(str1, str2, str3, str4):
 22     print("%s\t\t%s\t\t%s %s" % (str1, str2, str3, str4))
 23 
 24 
 25 str1 = []
 26 str2 = []
 27 str3 = ''
 28 str4 = ''
 29 s1 = input("請輸入要分析的字符串:")
 30 s1 += '#'
 31 for i in s1:
 32     str2.append(i)
 33 out1()
 34 
 35 for i in s1:
 36 
 37     while True:
 38         str1 = copy.copy(strs)
 39 
 40         sout = strs.pop()  # 取出最后一個元素
 41 
 42         str3 = 'M[' + sout + ',' + i + ']'
 43         try:
 44 
 45             num1 = list2.index(sout)
 46             num2 = list3.index(i)
 47             if list1[num1][num2] != '':
 48                 schan = list1[num1][num2]
 49                 if schan[-1] == 'ε':
 50                     # strs.pop()
 51                     strs.append(sout)
 52                     str1 = copy.copy(strs)
 53                     num1 = list2.index(strs[-1])
 54                     num2 = list3.index(i)
 55                     schan = list1[num1][num2]
 56                     str4 = schan
 57                     stop1 = 1
 58                     sums = ''
 59                     for j in schan[::-1]:
 60                         if j == '>':
 61                             break
 62                         elif j == '\'':
 63                             sums += j
 64                             stop1 = 2
 65                         else:
 66                             if stop1 == 1:
 67                                 strs.append(j)
 68                             else:
 69                                 sums = j + '\''
 70                                 strs.append(sums)
 71                                 sums = ''
 72                                 stop1 = 1
 73                 else:
 74                     str4 = schan
 75                     stop1 = 1
 76                     sums = ''
 77                     for j in schan[::-1]:
 78                         if j == '>':
 79                             break
 80                         elif j == '\'':
 81                             sums += j
 82                             stop1 = 2
 83                         else:
 84                             if stop1 == 1:
 85                                 strs.append(j)
 86                             else:
 87                                 sums = j + '\''
 88 
 89                                 strs.append(sums)
 90                                 sums = ''
 91                                 stop1 = 1
 92         except:
 93             if False:
 94                 str3 = ''
 95                 str4 = '成功'
 96                 out2(str1, str2, str3, str4)
 97                 break
 98             else:
 99                 str3 = 'Pop'
100                 str4 = 'Nextsym'
101                 strs.pop()
102                 if str1[-1] != 'ε':
103                     out2(str1, str2, str3, str4)
104                     str1.pop()
105                     strs = copy.copy(str1)
106 
107                     break
108                 else:
109                     str1.pop()
110                     str1.pop()
111                     strs = copy.copy(str1)
112         if str2[-1] == '#':
113             if str1[-1] == '#':
114                 str3 = ''
115                 str4 = '成功'
116                 out2(str1, str2, str3, str4)
117                 break
118             elif str1[-1] != '#':
119                 str3 = ''
120                 str4 = '失敗'
121                 out2(str1, str2, str3, str4)
122                 break
123             else:
124                 str3 = ''
125                 if str4 != 'Nextsym':
126                     out2(str1, str2, str3, str4)
127         else:
128             out2(str1, str2, str3, str4)
129 
130     str2.pop(0)  # 移除第一個元素

運行結果:

 

 

 

 輸出格式有需要的朋友可以自行修改一下!

 

 

里面使用了淺拷貝,為什么要使用淺拷貝呢?原因就是我使用深拷貝錯了,關於python的深拷貝和淺拷貝,首先來個官方的介紹:

 

 反正我看的不咋明白,來個實例解釋一下吧!開干!!!!

import copy

a = ['a','b','c','d']  # 首先我們定義了一個我們用於操作的數組

b = a  # 此時進行深拷貝

print("這是a的地址" + str(id(a)))
print("這是b的地址" + str(id(b)))
print("a的地址是否和b一樣呢?" + str(id(a) == id(b)))

c = copy.copy(a) #此時進行淺拷貝

print("這是a的地址" + str(id(a)))
print("這是c的地址" + str(id(c)))
print("a的地址是否和c一樣呢?" + str(id(a) == id(c)))
#然並軟貌似看不出啥東西來,你以為這就結束了?醒醒快開學了
#下面來個我的驗證方法,網上有好多將這個深拷貝和淺拷貝的但是我沒看懂


#進入正題
a.pop()#現在我移除一下a中的最后一個元素
print("a中的元素:"+str(a))
print("深拷貝b中的元素:"+str(b))
print("淺拷貝c中的元素:"+str(c))

運行結果:

 

 

網上有些資料說copy方式復制的是淺拷貝,我也沒有去看官方的文檔,所以我從定奪,有資料的小伙伴可以發給我一下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM