Bison:错误消息中包含的行号

Bison : Line number included in the error messages

本文关键字:包含 错误 消息 Bison      更新时间:2023-10-16

好的,我想我的问题已经很清楚了。

我目前正在Bison中构建一个解析器,我想让错误报告变得更好。

目前,我已经设置了%define parse.error verbose(它实际上给出了像syntax error, unexpected ***********************, expecting ********************这样的消息。

所有我想要的是在错误消息中添加一些更多的信息,例如行号(在输入/文件/等)

我现在的yyerror(好吧,没什么…不寻常的……lol):

void yyerror(const char *str)
{
    fprintf(stderr,"x1B[35mInterpreter : x1B[37m%sn",str);
}

注:

  • 我已经浏览了最新的Bison文档,但我似乎很迷路…
  • 我也看了看%locations指令,最有可能是非常接近我需要的-然而,我仍然没有发现完整的工作示例,我不确定这是如何使用的。

所以,这里我是一个与一步一步的解决方案:

    我们在语法文件中添加了%locations指令(在%}和第一个%%之间)
  • 我们确保我们的词法分析器文件包含我们的解析器(例如#include "mygrammar.tab.h"),在顶部
  • 我们在词法分析器文件中添加了%option yylineno选项(在%}和第一个%%之间)

现在,在我们的yyerror函数中(应该在lexer文件中),我们可以自由地使用这个…yylineno (=当前正在处理的文件行):

void yyerror(const char *str)
{
    fprintf(stderr,"Error | Line: %dn%sn",yylineno,str);
}

是的。就是这么简单!: -)

对我有用的是在.ypp文件中添加extern int yylineno:

/* parser.ypp */
%{
    extern int yylineno;
%}
/* scanner.lex */
...
%option yylineno

Bison附带了许多示例来演示其功能,请参阅您机器上的/usr/local/share/doc/bison/examples(其中前缀/usr/local取决于您的配置)。

这些例子你可能会特别感兴趣:

  • lexcalc使用优先级指令和位置跟踪。它使用Flex生成扫描仪。
  • bistromatic演示了使用Bison时的最佳实践。
    • 其手写扫描器跟踪位置。
    • 接口为纯接口。
    • 使用%params传递用户信息给解析器和扫描器。
    • 它的扫描器使用error令牌表示词法错误并输入错误恢复。
    • 它的界面是"增量式"的,非常适合交互:它使用push-parser API,为解析器提供传入令牌。
    • 它的特点是一个交互式命令行,基于解析器状态,基于yyexpected_tokens .
    • 它使用Bison的标准目录来实现生成的国际化消息。
    • 它使用自定义语法错误,包括位置、向前看更正和令牌国际化。
    • 错误消息用在错误下划线下划线引用来源:
    > 123 456
    1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
        1 | 123 456
          |     ^~~
    
    • 支持带有语义值的调试跟踪。
    • 它使用命名引用而不是传统的$1,$2等。