繁体   English   中英

使用解析器重新同步处理PLY.yacc错误

[英]PLY.yacc error handling using parser resynchronization

我正在尝试在解析过程中实现用户友好的语法错误处理。 根据我在官方PLY 文档中的观察。 一种方法是在第一个SyntaxError发生时引发异常并终止解析。 但是,正如文档所建议的,我想做类似的事情来使用解析器重新同步技术。

该文件说:

处理语法错误的最完善的方法是编写包含错误标记的语法规则。 例如,假设您的语言对这样的打印语句具有语法规则:

 def p_statement_print(p): 'statement : PRINT expr SEMI' ... 

为了解决表达错误的可能性,您可以编写一个附加的语法规则,如下所示:

 def p_statement_print_error(p): 'statement : PRINT error SEMI' print("Syntax error in print statement. Bad expression") 

我有一个这样的语法摘录:

def p_operation(self, p) -> None:
    '''
    operation : unaryOperation
              | binaryOperation
    '''

def p_unaryOperation(self, p) -> None:
    '''
    unaryOperation : unaryOperation L_SQUARE_BRACKET projection R_SQUARE_BRACKET
                   | RELATION_NAME
    '''

def p_projection(self, p) -> None:
    '''
    projection : multipleAttributes
               | attribute
    '''

def p_multipleAttributes(self, p) -> None:
    '''
    multipleAttributes : projection COMMA attribute
    '''

def p_attribute(self, p) -> None:
    '''
    attribute : ATTRIBUTE
    '''

我不确定如何定义包括error令牌的新规则。 我应该用error令牌替换每个非终端吗?

期待收到您的答复! 非常感谢你的帮助

您绝对不应该为每个非终端添加错误产生。

当存在某些令牌时,重新同步将正常工作,这些令牌通常会将解析上下文重置为已知状态。 在具有清晰的语句结尾标记的语言中(在您引用的示例中为分号),该标记可以很好地用作重新同步点。 丢弃文本直到下一个分号,然后再从那里进行解析不会在100%的时间内起作用,但是在许多情况下它确实起作用。

括号和括号也可以用作重新同步点,但是启发式方法不那么可靠,因为许多语法错误是括号或括号不匹配的结果。 例如,扫描缺少的右方括号可能会丢弃整个输入。

在没有明确的语句定界符的语言中,重新同步更为复杂,包括像Python这样的语言,其中的换行符仅在不嵌套在括号内的情况下才终止语句。 丢弃最多换行符可能会起作用,但是您可能必须处理扫描程序和解析器之间的反馈,该反馈确定何时将换行符作为令牌发送以及何时将其作为空白符跳过。

缩进不一致可能是有用的重新同步触发器,但有几点警告。 首先,您一定不能拒绝带有“误导”缩进的有效输入,因此触发器在重新同步过程中比在正常解析过程中需要更加敏感。 其次,跟踪不一致的缩进肯定需要解析器->扫描器反向通道。 因此,它比简单的紧急恢复要花更多的时间,但它可能是有效的。

最重要的是,只有很少的通用算法可以实现良好的错误报告和恢复。 您需要基于语言的句法本质来制定策略。

理想情况下,您将希望通过检查解析器对常见错误的响应来优化代码,但是只有在进行实际部署并看到常见错误之后才能真正做到这一点。 因此,我能提供的最佳建议是从一个简单的恢复策略开始,看看它如何处理不同的语法错误,尤其是您偶然创建的语法错误(或您的朋友和合作者的语法错误)。 保留遇到的各种语法错误的存档,可用于测试对诊断和恢复代码的改进。 别指望它是完美的,因为这是一个难题,但是请尽一切可能使它更准确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM