首页 > 解决方案 > 如何在 PLY yacc 中存储错误

问题描述

我正在使用 ply.yacc 构建解析器,并且我对将所有语法错误存储在列表中很感兴趣。我想要这样的东西:

parser = yacc.yacc()
parser.errors = []
parser.parse(program)
print(parser.errors) # do something with parser.errors

问题是当我定义处理错误的规则时

def p_error(p):
    ...

我不知道如何访问解析器实例,所以我可以将错误附加到我的列表中。对于词法分析器,我使用了 ply.lex并解决了这个问题,因为在规则定义中作为参数传递的标记t具有对词法分析器的引用。

def t_error(t):
  t.lexer.error.append(LexicographicError(t.lineno, t.value[0]))

有没有办法用yacc解析器做类似的事情???

标签: pythonyaccply

解决方案


to 的参数p_error通常是一个标记(因此原型会更好地编写def p_error(t):),因此您可以将错误添加到与您在词法分析器中使用的列表相同的列表中。但这并不理想。首先,因为这是保留错误(词汇和句法)的奇怪位置,其次是因为有时参数p_errorNone(当错误发生在输入末尾时)。

更好的解决方案是使解析器成为类而不是全局,这在 Ply 文档中进行了相当简短的解释(主要通过参考关于使词法分析器成为类的部分)。通常,您会在 Parser 类的__init__方法中构建解析器,并将其保存为self.parser. 然后所有p_*成员函数都接受一个self参数,就像任何类函数一样,您可以将错误列表存储为成员属性。(您可以parser使用 usingself.parser但我认为在对象实例本身中保留错误列表比将其添加到解析器实例更干净。)


推荐阅读