我正在使用Bison并且我已经生成了一个相当复杂的语法。问题是我的第一个测试案例失败了 - 但Bison只会说“语法错误”。有没有办法让Bison输出无法匹配的规则和有问题的令牌?我用了
%define parse.trace true
但仍然只获得syntax error
作为输出。
答案 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)
格式的宏调用输出消息,其中format
和args
是通常的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 可以做得更好。