我正在使用 Bison 2.7 编写 GLR 解析器并打开 %error-verbose 选项。当我运行解析器时,它给了我“语法不明确”的错误。有没有办法让 Bison 给我更多关于语法在哪里/如何模棱两可的细节?
2 回答
如果您希望生成有意义的错误消息,您可能需要制作自己的函数来报告歧义。bison
确实为您提供了一个基本工具:自定义%merge
函数。
如手册中所述(请参阅上面链接末尾的段落),您可以使用%merge
可能导致歧义的产生式子句指定自定义合并功能。合并函数可以很好地完成任何事情,包括信号错误,但有一些限制:
合并函数的参数是语义值 (
YYSTYPE
),它将是歧义产生式的子类型。模糊右侧的语义动作将在调用合并函数之前执行,因此如果语义动作改变全局解析器状态,则该状态可能不一致,合并函数将不得不清理。(因此,建议这种语法中的语义动作不要修改全局状态。)合并函数必须返回适当类型的语义值。YYSTYPE
如果可能有歧义的产生式具有不同的类型,您可能需要为每种类型创建不同的合并函数,因为除非您将其编码到自身中,否则无法知道语义联合的哪个元素适合特定的联合值。一种简单的方法是通过将枚举标记作为每个联合成员的第一个元素来创建“有区别的联合”。(C/C++
允许您使用任何联合成员访问这样的标签,但它必须在开始时才能工作。)使用两个语义值调用合并函数。因此,如果有两个以上的可能解析,它将被多次调用。
合并功能无权访问位置信息,除非该信息包含在语义类型中(这反而违背了拥有单独位置堆栈恕我直言的观点,但当然您只需要将位置信息包含在可能参与的类型中含糊不清。)
添加以下定义:
#define YYDEBUG 1
, Bison 将显示所有可能导致语法不明确的解析选项。