python - 如何在 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解析器做类似的事情???
解决方案
to 的参数p_error
通常是一个标记(因此原型会更好地编写def p_error(t):
),因此您可以将错误添加到与您在词法分析器中使用的列表相同的列表中。但这并不理想。首先,因为这是保留错误(词汇和句法)的奇怪位置,其次是因为有时参数p_error
是None
(当错误发生在输入末尾时)。
更好的解决方案是使解析器成为类而不是全局,这在 Ply 文档中进行了相当简短的解释(主要通过参考关于使词法分析器成为类的部分)。通常,您会在 Parser 类的__init__
方法中构建解析器,并将其保存为self.parser
. 然后所有p_*
成员函数都接受一个self
参数,就像任何类函数一样,您可以将错误列表存储为成员属性。(您可以parser
使用 usingself.parser
但我认为在对象实例本身中保留错误列表比将其添加到解析器实例更干净。)
推荐阅读
- java - 如何将文件设置为只读以无法通过 Java 更改此设置
- selenium - 如何在 Selenium 的 Shadow DOM 中定位 svg 元素
- javascript - 如何在非常暗的图像上最好地应用 SVG 滤镜
- python - Atom 中的 platformio-ide-terminal 设置错误
- autodesk-forge - 旋转截面框
- sql - 一个表可以有两个不同的列设置为主键吗?鉴于两列都具有唯一值而不是空值
- python - 按可能不存在于所有元素中的第 n 个元素对迭代列表进行排序
- javascript - 将自定义增值税字段添加到 woocommerce 电子邮件
- sql - Dbeaver 中的连接字符串和按 ID 分组
- ansible - 在剧本中执行 python 脚本