我有一个ply的问题,我必须收到一个带有令牌列表和语法(bnf)的文件,我写了一个语法来识别输入,它几乎正常工作(只是小问题,我们正在解决它们),例如,这是一个有效的输入文件
#tokens = NUM PLUS TIMES
exp : exp PLUS exp | exp TIMES exp
exp : NUM
(在这种情况下,我们不关心模棱两可的语法或其他什么,这是输入的一个例子)
分别解析每一行都很好,但我想用这些规则解析整个文件:我尝试使用循环来分别扫描和解析每一行,但我无法控制第一个(并且非常重要)规则,所以我在.py文件中尝试了这个:
我定义了t_NLINEA(新行)我还有问题使用\ n字符作为文字并且文件是使用rU模式打开以避免有关\ r \ n或\ n字符的冲突,所以我添加了这些规则:< / p>
def p_S(p):
'''S : T N U'''
print("OK")
def p_N(p): '''N:NLINEA N''' 通
def p_N2(p): '''N:''' 通
def p_U(p): '''U:R N U''' 通
def p_U2(p): '''你:''' 通
(正如我上面告诉你的那样,我使用了N规则,因为在我的语法中没有接受\ n文字,我将\ n添加到“文字”变量中)
T是解析#tokens声明的规则,R用于解析语法规则,如果我在单行字符串中使用它们,T和R工作正常,但是当我添加上面写的产品时,我得到一个语法解析fisrt gramar规则时出错,例如A : B C
我的语法错误:
有什么建议吗? 感谢
答案 0 :(得分:0)
Ply试图根据您的规则找出“起始规则”。根据您所编写的内容,它将使“exp”成为开始规则,即每个字符串或文件只有一个表达式。如果你想要多个表达式,你可能需要一个表达式列表:
def p_exp_list(p):
"""exp_list :
| exp_list exp
"""
if len(p) == 1:
p[0] = []
else:
p[0] = p[1] + [p[2]]
然后你的起始规则是“exp_list”。这将允许每行上有多个表达式。如果你想限制每行一个表达式,那么如何:
def p_line_list(p):
"""line_list :
| line_list line
"""
if len(p) == 1:
p[0] == []
else:
p[0] = p[1] + [p[2]]
def p_line(p):
"""line : exp NL"""
p[0] = p[1]
我认为你不能使用换行作为文字,(因为它可能会搞乱正则表达式)。您可能需要更具体的令牌规则:
t_NL = r'[\r*\n]'
非常确定这会有效,但还没有尝试过,因为还不够。
至于“#token”行,你可以跳过它,如果它没有出现在其他任何地方:
def t_COMMENT(t):
r'#.*$'
pass # ignore this token