文法
G(s):
S -> (S)S|Aa
A -> b|ε
该文法是一个可以输出a,b和括号的文法,在使用自顶向下分析(递归下降法)的时候要消除文法的左递归和左公共因子避免回溯。
SELECT(S -> (S)S) = {(};SELECT(S -> Aa) = {b,a};
SELECT( A -> b) = {b};SELECT( A -> ε) = {a};
显然,该文法不为左递归文法,各非终结符的各产生式的SELECT集不相交,因此该文法不含有左公共因子。所以该文法可以进行递归下降分析。
递归下降程序
class Syntax_Analysis():
#递归下降法
"""
G(s):
S -> (S)S|Aa
A -> b|ε
"""
def __init__(self, token):
self.token = token + '#' # token的末尾加一个#来判断是否分析完成
self.i = 0
def S(self): # S -> (S)S|Aa
if self.token[self.i] == '(': # SELECT(S -> (S)S) = {(}
self.i += 1
if self.S() and self.token[self.i] == ')':
self.i += 1
if self.S():
return True
else:
return False
elif self.token[self.i] == 'a' or self.token[self.i] == 'b': # SELECT(S -> Aa) = {a,b}
if self.A() and self.token[self.i] == 'a':
self.i += 1
return True
else:
return False
def A(self): # A -> b|ε
if self.token[self.i] == 'b': # SELECT(A -> b) = {b}
self.i += 1
return True
elif self.token[self.i] == 'a': # SELECT(A -> ε) = {a}
return True
else:
return False
def run(self):
if self.S() and self.token[self.i] == '#':
return self.token[0:len(self.token)-1] + "为合法符号串"
elif self.i < len(self.token) - 1:
return self.token[0:len(self.token)-1] + "为非法的符号串\t\t"+"参考错误:出错字符位于第"+str(self.i+1)+"处, 该字符为 "+self.token[self.i]
else:
return self.token[0:len(self.token)-1] + "为非法的符号串\t\t"+"参考错误:出错字符位于末尾"
if __name__ == "__main__":
print("递归下降分析程序")
token = ['(ba)a','(ba)ba','(ba)'] #token为词法分析输出的单词流
for i in token:
parser = Syntax_Analysis(i)
print("输出结果:" + parser.run())