如何在特殊的解析函数内在ply-yacc中引发错误?

问题描述

我正在与库层一起为命令解析器。代码

def p_expr(v):
    'expr : token'
    ... # action with token,set expr value and return
    ??? raise error ??? # yacc must stop parse and call p_error
    
def p_error(p):
    print('Error!')
    

如何引发错误

解决方法

请注意,遇到语法错误时,Ply不会“停止解析”。如果语法是通过错误恢复构建的,则它会尝试进行错误恢复,并且作为最后的选择,它重新开始解析,就好像输入已经被删除一样。为此,请尝试在calculator example in the Ply distribution中输入1+2 error 3+4。它将为error打印一条错误消息(因为它期望一个运算符),然后重新启动解析,以便输出7。

如果您希望解析器在发现错误时停止运行,则需要从p_error引发异常。通常最好为这种事情定义自己的异常类。避免使用SyntaxError,因为Ply在某些情况下会特别处理该问题,如下所述。

通常,只是停止解析器并不是您真正想做的-如果您不想尝试错误恢复,通常至少应该在重新开始解析之前至少做一些诸如丢弃输入行的操作

如果您只是想停止解析器,并在p_error中引发一个异常来完成此操作,那么从解析器操作中发出自己的错误的最佳方法是使用当前标记调用p_error。 / p>

如果要触发Ply的正常错误恢复过程,请从解析器操作中提高SyntaxError。但是,作为manual indicates,它不会调用p_error,因此在产生错误之前,您必须自己进行操作。

如果您在p_error中执行panic mode recovery,则可能无法自定义错误检测功能。发起SyntaxError绕过通话p_error;尽管您可以自己自由调用p_error,但是没有机制可以将新令牌传递回解析器。 (紧急模式恢复并不是最佳的错误恢复技术,并非总是必须返回替换令牌。因此,本段可能不适用。)