编译原理之递归下降语法分析程序(实验)

一、实验目的

利用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 版权所有,侵权必告

 

 

posted @ 2019-11-29 18:16  诚哥博客  阅读(2433)  评论(0编辑  收藏  举报