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