使用像BISON这样的解析器生成器,同时仍然优雅地处理错误的输入

时间:2009-05-06 02:38:23

标签: parsing bison

我需要一种语言解析器并不是那么复杂。唯一的问题是,我从不希望解析器在收到格式错误的输入时引发错误。相反,我希望它继续下去,尽可能多地了解输入,类似于Web浏览器中的HTML解析器。

我自然而然地想要使用解析器生成器,但我对它们没有那么多经验,而且我所看到的Bison和Antlr的所有示例都有一些脆弱的解析器,它们会在遇到语法时立即放弃错误。这是可行的吗,还是我应该考虑手动滚动它?考虑到语言,它可能(我认为)不会那么困难。

2 个答案:

答案 0 :(得分:1)

我不确定在一般情况下你是否可以使用解析器生成器做到这一点。至少,不是以完全自动的方式。请考虑以下格式不正确的表达式:

a - b + c ) * d

解析器应该怎么做呢?当它遇到第一个非法令牌,即闭合括号时,它可能以某种方式猜测用户打算在某处打开括号,但在哪里?任何放置它的地方都会产生不同的价值。

相反,它可能只是假装以前发生的一切都没发生过。然后它会以

结束
* d

哪个仍然格格不入。

答案 1 :(得分:1)

您需要考虑检查点来设计语法。通过检查点,我的意思是C的分号,Python的换行符或COBOL的句号(作为示例)。这个检查点是有多少编译器恢复,以便他们可以报告的不仅仅是发现的第一个错误。

我没有使用Bison,但是YACC允许你覆盖错误处理,我希望等效的GNU工具至少和我们旧的UNIX旧车一样强大。

我之前使用配置文件YACC语法完成了这项工作。假设您有以下正确形成的段:

item = "bread" {
    quantity = 7
    price = 1.50
    taxrate = 10
}

并且由于某些奇怪的原因,用户误解“数量”,使其不正确。在回调中的那一点,你可能只是提出一个错误标志,这将阻止进一步处理,直到达到检查点。您让解析器继续运行(捕获并忽略更多错误),并确保您的回调不会响应损坏语法中的任何虚假成功。

这可以简单地忽略所有进一步的节到结束括号,或者甚至通过设置价格的默认值并且只忽略到换行符(这样你至少得到一个部分形成的对象)。

但是你这样做,只需在到达检查点时重置错误标志,以便继续处理。

我仍然会确保用户收到通知,有时候我们认为继续使用客户不想要的数据是错误的形式: - )。