在ply(python)中解析具有特定格式的文件

时间:2013-11-06 16:36:37

标签: string file parsing multiline ply

我有一个ply的问题,我必须收到一个带有令牌列表和语法(bnf)的文件,我写了一个语法来识别输入,它几乎正常工作(只是小问题,我们正在解决它们),例如,这是一个有效的输入文件

#tokens = NUM PLUS TIMES
exp : exp PLUS exp | exp TIMES exp
exp : NUM

(在这种情况下,我们不关心模棱两可的语法或其他什么,这是输入的一个例子)

分别解析每一行都很好,但我想用这些规则解析整个文件:

  • #tokens必须只在第一行,所以如果我们在语法后面有#tokens声明则无效
  • 每行“code”
  • 后可以有0个或更多空行
  • 您可以拥有任意数量的语法规则

我尝试使用循环来分别扫描和解析每一行,但我无法控制第一个(并且非常重要)规则,所以我在.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我的语法错误:

有什么建议吗? 感谢

1 个答案:

答案 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