PLY Python中的词法分析器错误处理

3

t_error()函数用于处理在检测到非法字符时发生的词法分析错误。我的问题是:我如何使用此函数获取有关错误更具体的信息?例如错误类型,错误出现在哪个规则或部分中等等。

3个回答

3
通常情况下,t_error()函数只能获得非常有限的信息。作为输入,它接收一个令牌对象,其中值已设置为剩余的输入文本。对该文本的分析完全由您决定。您可以使用t.lexer.skip(n)函数让词法分析器跳过一定数量的字符,这就是全部功能。
除了存在与任何已知令牌的正则表达式不匹配的输入字符之外,没有“错误类型”的概念。由于词法分析器与解析器分离,因此无法直接获取有关解析引擎状态的任何信息,也无法找出正在解析哪个语法规则。即使您可以获取状态(它只是LALR状态机的基础状态号),解释它也可能非常困难,因为解析器可能处于匹配几十个可能的语法规则的中间阶段,寻找约简动作。
我的建议如下:如果您需要在t_error()函数中获得其他信息,则应设置某种对象,该对象在您的代码的词法分析器和解析器组件之间共享。您应明确地使编译器的不同部分根据需要更新该对象(例如,可以在特定语法规则中更新它)。
顺便说一句,坏令牌通常只有很少的几种处理方法。实际上,您获得的是不包含语言字母表中任何已知部分(例如,没有已知符号)的输入文本。因此,甚至没有可以提供给解析器的任何令牌值。通常,唯一的处理方法是报告错误的输入,将其丢弃并继续。
作为对Raymond答案的补充,我也不建议在t_error()函数中修改词法分析器对象的任何属性。

1

1
Ply在一个名为cpp.py的文件中包含了一个示例的ANSI-C风格的词法分析器(lexer)。它展示了如何从t_error()中提取一些信息的示例。
def t_error(t):
    t.type = t.value[0]
    t.value = t.value[0]
    t.lexer.skip(1)
    return t

在该函数中,您还可以访问词法分析器的公共属性:

  • lineno - 当前行号
  • lexpos - 输入字符串中的当前位置

还有一些其他属性没有列为公共属性,但可能提供一些有用的诊断信息:

  • lexstate - 当前词法分析器状态
  • lexstatestack - 词法分析器状态堆栈
  • lexstateinfo - 状态信息
  • lexerrorf - 错误规则(如果有)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接