代码之家  ›  专栏  ›  技术社区  ›  anon

使用诸如bison之类的解析器生成器,同时仍然优雅地处理错误的输入

  •  3
  • anon  · 技术社区  · 15 年前

    我需要一个不那么复杂的语言的解析器。唯一的问题是,我从不希望解析器在接收到格式错误的输入时引发错误。相反,我希望它继续,尽可能地理解输入,类似于web浏览器中的html解析器所做的事情。

    我很自然地想到了使用解析器生成器,但是我对它们没有太多的经验,我所看到的bison和antlr的所有例子都是脆弱的解析器,一旦遇到语法错误就会放弃。这对他们来说是可行的,还是我应该考虑手动操作呢?考虑到语言,这可能(我认为)没那么难。

    2 回复  |  直到 15 年前
        1
  •  1
  •   SingleNegationElimination    15 年前

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

    a - b + c ) * d
    

    解析器应该对此做些什么呢?当它遇到第一个非法的标记(右括号)时,它可能以某种方式猜测用户希望在某个地方有一个左括号,但是在哪里呢?它可以放在任何地方都会产生不同的值。

    相反,它可以假装以前发生的一切从来没有发生过。结果会是

    * d
    

    仍然是畸形的。

        2
  •  1
  •   paxdiablo    15 年前

    你需要在设计语法时考虑检查点。我所说的检查点是指c的分号、python的换行符或cobol的句点(例如)。此检查点是编译器恢复的数量,以便它们可以报告的不仅仅是发现的第一个错误。

    我没有使用bison,但是yacc允许覆盖错误处理,我希望等效的gnu工具是 至少 像我们以前的unix旧车一样强大。

    我以前用过配置文件yacc语法。假设您有以下格式正确的段:

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

    由于一些奇怪的原因,用户错拼了“数量”,使其不正确。在回调的那一点上,您可以只抛出一个错误标志,在到达检查点之前阻止进一步的处理。您让解析器继续运行(捕捉并忽略进一步的错误),并确保回调不会对损坏语法中的任何虚假成功做出任何响应。

    这可以简单地忽略到右大括号为止的所有其他节,甚至设置price的默认值,只忽略到换行符为止(这样至少可以得到一个部分格式的对象)。

    但是,只要在到达检查点时重置错误标志,就可以继续处理。

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