代码之家  ›  专栏  ›  技术社区  ›  Daniel Walker

用Bison识别特定的语法错误

  •  0
  • Daniel Walker  · 技术社区  · 6 年前

    我正试图使用Bison来开发我自己的编程语言。我已经为我的语法编写了.y文件。但是,我想知道,如果用户试图解析语法无效的源代码,是否有办法让Bison给出有用的错误消息。例如,假设我的语法中有以下规则:

    if_statement: IF expr '{' statement_list '}' {$$=createNode(IF,$2,$4);}
        ;
    

    假设源代码省略了右括号。据我所知,Bison会报告说,它无法找到减少代码的规则。可以让野牛意识到还有一个未完成的 if 哪个从某某开始,然后向用户报告?

    0 回复  |  直到 6 年前
        1
  •  1
  •   rici    6 年前

    缺少大括号的地方很少被检测到,因为通常情况下,缺少大括号之后的任何内容都可能出现在它之前。如果缺少的闭合大括号后面紧接着另一个闭合大括号,这一点尤其明显,但在这种情况下,它可能只是后面跟着另一个语句:

    function some_function() {
        ....
        while (some_condition) {
            ...
            if (some_other_condition) {
                ...
                break;
    //      }          /* Commented out by mistake */
            a = 3;
            ...
        }
        return a;
    }
    
    function another_function() {
        ...
    }
    

    如果你的语言不允许嵌套函数定义,那么 another_function 将触发错误;如果它确实允许嵌套函数定义,那么 另一个功能 将仅在意外范围内定义,解析将继续,可能直到文件结束。

    检测此类错误的一种方法是检查每行的压痕是否与预期压痕一致。但是,除非你的语言有一些正确缩进的概念(例如Python),否则你不能将误导性缩进标记为错误。因此,你能做的最好的事情就是记录意外的缩进,以便在最终遇到语法错误时将其用作线索(如果有语法错误,因为程序员可能不想让他们的程序可读)。这种错误检测方法的复杂性可能是它在主流语言中如此罕见的原因,尽管我个人认为这是一种具有很大潜力的方法。

    我通常主张对错误的程序进行两次解析。第一个解析针对正确的程序进行了优化,这意味着它不需要任何良好错误消息所需的开销,例如跟踪每个令牌的位置。如果程序在语法上是正确的,那么您可以继续将AST转换为编译代码。如果程序出现语法错误,您可以在开始时重新启动解析,然后您当然可以自由地使用缩进检查等启发式方法来尝试更好地定位错误。

    说了这么多,你最好继续实现你的语言,稍后再回到产生更好诊断的问题上。

    在某些情况下,Bison确实提供了一种机制来产生更有用的错误消息。

    首先,您至少应该从Flex中启用行号跟踪,这几乎不需要任何努力。您可能还想跟踪精确的令牌位置,这需要更多的工作,但不会太多。(参见 Character Position from starting of a line , https://stackoverflow.com/a/48879103/1566221 和 yyllocp->first_line returns uninitialized value in second iteration of a reEntrant Bison parser (除其他外)示例代码。)

    其次,让野牛产生详细的错误消息。这只需要在你的野牛序言中多写两行:

    %define parse.error verbose
    %define parse.lac full
    

    请务必阅读野牛手册,了解一些重要的注意事项。特别是,LAC可能涉及大量开销。但产生的错误消息通常是有帮助的。

    最后,在检测到第一个语法错误后,使用bison的错误恢复机制继续解析,从而允许您在一次运行中报告多个语法错误。这通常不会让用户感到沮丧,尽管您应该在某个阈值错误计数时终止解析,因为错误恢复后的错误计数非常高通常意味着错误恢复本身失败,并且许多后续错误消息都是虚假的。

    同样,野牛手册对如何使用 error 设施。

    Bison manual table of contents