野牛错误输出

时间:2011-08-04 21:46:58

标签: bison

我正在使用Bison并且我已经生成了一个相当复杂的语法。问题是我的第一个测试案例失败了 - 但Bison只会说“语法错误”。有没有办法让Bison输出无法匹配的规则和有问题的令牌?我用了

%define parse.trace true

但仍然只获得syntax error作为输出。

4 个答案:

答案 0 :(得分:8)

当出现问题时,没有一个基于Yacc的解析器能比“语法错误”做得更好;在很大程度上由你来改进。

你可以很容易地做一些事情。

一种方法是检测词法分析器,使其打印出它找到的标记,因为它将它们返回到正确的解析器。这会告诉您语法失败的标记,以及事先提供的标记。

另一种是在启用Yacc调试的情况下进行编译,然后将其打开。这需要-DYYDEBUG=1并将变量yydebug设置为非零值(通常为1)。第一步是将额外的信息编译成语法;第二步启用输出。

来自Bison 2.4.3手册:

  

§8.2追踪你的解析器

     

如果一个Bison语法正确编译但在运行时没有做你想要的,那么   yydebug解析器跟踪功能可以帮助您找出原因。

     

有几种方法可以启用跟踪工具的编译:

     
      
  • YYDEBUG

         

    编译解析器时,将宏YYDEBUG定义为非零值。   这符合POSIX Yacc。您可以使用-DYYDEBUG=1作为编译器   选项或您可以将#define YYDEBUG 1放在语法的序言中   文件(参见第3.1.1节[序言],第47页)。

  •   
  • 选项-t--debug

         

    运行Bison时使用-t选项(参见第9章[调用Bison],   第117页)。这也符合POSIX。

  •   
  • 指令%debug

         

    添加%debug指令(参见第3.7.12节[Bison声明摘要],   第72页)。这是一个Bison扩展,当Bison将会发挥作用   输出解析器,用于不使用预处理器的语言。除非POSIX和   Yacc可移植性对您很重要,这是首选解决方案。

  •   
     

我们建议您始终启用调试选项,以便始终可以进行调试。

     

跟踪工具使用YYFPRINTF (stderr, format, args)格式的宏调用输出消息,其中formatargs是通常的printf格式和可变参数。   如果您将YYDEBUG定义为非零值但未定义YYFPRINTF<stdio.h>   自动包含,YYFPRINTF定义为fprintf

     

使用跟踪工具编译程序后,请求跟踪的方法是   在变量yydebug中存储非零值。您可以通过使C代码执行此操作   它(可能是主要的),或者您可以使用C调试器更改该值。

     

yydebug非零时,解析器采取的每个步骤都会生成一行或两行跟踪   信息,写在stderr上。跟踪消息告诉您这些事情:

     
      
  • 每次解析器调用yylex时,都会读取哪种令牌。
  •   
  • 每次移动令牌时,状态堆栈的深度和完整内容(参见   第5.5节[分析器状态],第95页。
  •   
  • 每次减少规则,规则是什么,以及状态的完整内容   后来堆叠。
  •   

答案 1 :(得分:5)

使用%error-verbose指令来帮助您。它将为您提供解析器所期望的令牌的提示。请注意,可能存在多个未能匹配的潜在规则。

答案 2 :(得分:2)

如果将全局变量yydebug设置为非零值,bison将在其运行时输出调试信息,其中包含有关解析堆栈的外观,状态,使用规则等信息。我通常会调试这些错误。

答案 3 :(得分:2)

这里有一个混乱。

"%define parse.trace""%debug"完全相同:它为运行时跟踪检测生成的解析器,显示解析器在工作(但您仍需设置yydebug变量,请参阅文件由Jonathan Leffler亲切复制)。

为了使错误信息更加准确(在这方面,Jonathan错了),正如Alek所报告的那样,由于"%define error-verbose",Bison 可以做得更好。