一、实验目的
利用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 版权所有,侵权必告