編譯原理之遞歸下降語法分析程序(實驗)


一、實驗目的

利用C語言編制遞歸下降分析程序,並對簡單語言進行語法分析。

編制一個遞歸下降分析程序,實現對詞法分析程序所提供的單詞序列的語法檢查和結構分析。

 

二、實驗原理

每個非終結符都對應一個子程序。

該子程序根據下一個輸入符號(SELECT集)來確定按照哪一個產生式進行處理,再根據該產生式的右端:

  • 每遇到一個終結符,則判斷當前讀入的單詞是否與該終結符相匹配,若匹配,再讀取下一個單詞繼續分析;不匹配,則進行出錯處理
  • 每遇到一個非終結符,則調用相應的子程序

 

三、實驗要求說明

輸入單詞串,以“#”結束,如果是文法正確的句子,則輸出成功信息,打印“success”,否則輸出“error”,並指出語法錯誤的類型及位置。

例如:

輸入begin a:=9;b:=2;c:=a+b;b:=a+c end #

輸出success

輸入a:=9;b:=2;c:=a+b;b:=a+c end #

輸出‘end' error

 

四、實驗步驟

1.待分析的語言的語法(參考P90)

2.將其改為文法表示,至少包含

–語句

–條件

–表達式

E -> E+T | T
T -> T*F | F
F -> (E) | i

3. 消除其左遞歸

E -> TE'
E' -> +TE' | ε
T -> FT'
T' -> *FT' | ε
F -> (E) | i

4. 提取公共左因子

 

5. SELECT集計算

SELECT(E->TE) =FIRST(TE')=FIRSI(T)-FIRST(F)U{*}={(, i, *}
SELECT(E'->+TE')=FIRST(+TE')={+}
SELECT(E'->ε)=follow(E')=follow(E)={#, )}
SELECT(T -> FT')=FRIST(FT')=FIRST(F)={(, i}
SELECT(T'->*FT')=FRIST(*FT')={*}
SELECT(T'->ε)=follow(T')=follow(T)={#, ), +}
SELECT(F->(E))=FRIST((E)) ={(}
SELECT(F->i)=FRIST(i) ={i}

6. LL(1)文法判斷

  其中SELECT(E'->+TE')與SELECT(E'->ε)互不相交,SELECT(T'->*FT')與SELECT(T'->ε)互不相交,SELECT(F->(E))與SELECT(F->i)互不相交,故原文法為LL(1)文法。

7. 遞歸下降分析程序

  1 '''
  2     by Rakers
  3 '''
  4 
  5 import re
  6 
  7 types = {'begin':1,
  8          'if':2,
  9          'then':3,
 10          'while':4,
 11          'do':5,
 12          'end':6,
 13          'l(l|d)*':10,
 14          'dd*':11,
 15          '+':13,
 16          '-':14,
 17          '*':15,
 18          '/':16,
 19          ':':17,
 20          ':=':18,
 21          '<':20,
 22          '<=':21,
 23          '<>':22,
 24          '>':23,
 25          '>=':24,
 26          '=':25,
 27          ';':26,
 28          '(':27,
 29          ')':28,
 30          '#':0,
 31          'i':-1
 32         }
 33 
 34 # 當前讀到的字符
 35 syn = ''
 36 synIndex = 0
 37 
 38 # 所有字符
 39 syns = []
 40 
 41 kk = 0
 42 
 43 # 語法分析方法
 44 def syntaxAnalysis(strs):
 45     strs += ' '     # 補位
 46     syns = []
 47     index = 0
 48     while index < len(strs):
 49         for key in types.keys():
 50             if index+len(key) < len(strs):
 51                 if strs[index:index+len(key)] == key:
 52 
 53                     if re.match('^[<>:]$', strs[index]) and strs[index+1] == '=':
 54                         key = strs[index:index+2]
 55                     ss = strs[index:index+len(key)]
 56                     # print((ss, types.get(ss)))
 57                     syns.append({ss:types.get(ss)})
 58                     index += len(key)-1
 59                     break
 60                 elif re.match('^[a-zA-Z0-9_]+', strs[index:]):
 61                     ss = re.match('^([a-zA-Z0-9_]+)', strs[index:]).group()
 62                     if not types.get(ss):
 63                         if re.match('[a-zA-Z]+', ss):
 64                             # print((ss, 10))
 65                             syns.append({ss: 10})
 66                         elif re.match('\\d+', ss):
 67                             # print((ss, 11))
 68                             syns.append({ss: 11})
 69                         else:
 70                             print((ss, '其他'))
 71                     else:
 72                         # print((ss, types.get(ss)))
 73                         syns.append({ss:types.get(ss)})
 74                     index += len(ss)
 75                     # index += len(strs[index:strs.find(ss, index)])
 76         index += 1
 77     return syns
 78 
 79 
 80 def scaner():
 81     global syn, synIndex
 82     syn = syns[synIndex][list(syns[synIndex].keys())[0]]
 83     synIndex += 1
 84 
 85 
 86 def lrparser():
 87     global kk
 88     if syn == types['begin']:
 89         scaner()
 90         yucu()
 91 
 92         if syn == types['end']:
 93             scaner()
 94             if syn == types['#'] and kk == 0:
 95                 print("語句語法正確!!!")
 96         else:
 97             if kk != 1:
 98                 print("發生錯誤! 缺少end")
 99             kk = 1
100     else:
101         print("發生錯誤! 缺少begin")
102         kk = 1
103     return
104 
105 
106 def yucu():
107     statement()
108     while syn == types[';']:
109         scaner()
110         statement()
111     return
112 
113 
114 def statement():
115     global kk
116     if syn == types['l(l|d)*']:
117         scaner()
118         if syn == types[':=']:
119             scaner()
120             expression()
121         else:
122             print(":=error!")
123             kk = 1
124     else:
125         print("l(l|d)*error!")
126         kk = 1
127     return
128 
129 
130 def expression():
131     term()
132     while syn == types['+'] or syn == types['-']:
133         scaner()
134         term()
135     return
136 
137 
138 def term():
139     factor()
140     while syn == types['*'] or syn == types['/']:
141         scaner()
142         factor()
143     return
144 
145 
146 def factor():
147     global kk
148     if syn == types['l(l|d)*'] or syn == types['dd*']:
149         scaner()
150     elif syn == types['(']:
151         scaner()
152         expression()
153         if syn == types[')']:
154             scaner()
155         else:
156             print("語法錯誤, 缺少')'")
157             kk = 1
158     else:
159         print("表達式錯誤")
160         kk = 1
161     return
162 
163 
164 if __name__ == '__main__':
165     print('-'*30, 'Rakers語法分析程序', '-'*30)
166     strs = input('請輸入待分析語句:')
167     syns = syntaxAnalysis(strs)
168     scaner()
169     lrparser()

 

 

 

Rakers 版權所有,侵權必告

 

 


免責聲明!

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



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