Bison 语义谓词语法错误,杂散的“#”

Bison semantic predicate syntax error, stray '#'

所以我正在尝试使用 bison 的 semantic predicate 功能,但我 运行 遇到了一些问题,试图让它发挥作用。

当我尝试用 gcc 编译生成的 .tab.c 文件时出现问题。我正在使用 gcc 7.1.0 和 bison 3.0.4。这是编译错误的片段:

test2.tab.c: In function ‘yyuserAction’:
test2.tab.c:811:12: error: stray ‘#’ in program
     if (! (#line 19 "test2.y" /* glr.c:816  */
            ^
test2.tab.c:811:13: error: ‘line’ undeclared (first use in this function); did you mean ‘uint’?
     if (! (#line 19 "test2.y" /* glr.c:816  */
             ^~~~
             uint

所以我将 bison 的示例作为语义谓词,并将其作为一个工作示例:

%{

int new_syntax = 0;
int yyerror(const char* msg) { /* some error handling */ }

%}

%token id

%glr-parser

%%

prog: %empty
    | prog widget
    | prog flip
    ;

widget: %?{  new_syntax } "widget" id old_arg
      | %?{ !new_syntax } "widget" id new_arg
      ;

flip: "flip" { new_syntax = !new_syntax; }
    ;

old_arg: /* something here */
       ;
new_arg: /* something else here */
       ;

%%

在研究了 tab 文件之后,我意识到在 #line 指令之前添加一个换行符可以解决语法错误,(但直接修改生成的文件感觉有点 hacky。另外,你必须与一些空格对齐,以便 gcc 计算代码的右列位置)。

我想知道这是否是 bison 本身的错误,还是我使用的语义谓词有误,或者此语法在早期版本的 gcc 中是否正确,或者其他原因。

我也曾尝试在网上搜索这个问题,或者搜索已经提交给 bison 的错误,但我找到了 none。 (最新的野牛版本似乎已有 3 年历史。如果这个问题根本没有得到解决,我会感到惊讶)。有人可以启发我这个问题吗?谢谢。

如有必要,我可以尝试提交 bison 的错误(需要弄清楚如何做),但我不确定这是我自己的问题还是其他问题。

据我所知,这个错误已经存在了一段时间(可能是自引入语义谓词功能以来,尽管似乎有人应该在某些时候用某些版本的 bison 测试过它。)

最简单的解决方法是关闭 #line 指令的生成,只需将 -l(或 --no-lines)添加到 bison 命令行即可。但是,这将使解释错误消息变得更加困难,否则这些错误消息会引用 bison 语法文件中的行号。

作为第二个解决方法,您可以找到文件 c.m4,它可能位于 /usr/share/bison/c.m4 中(当然,这取决于您的发行版)。该文件的第 462 行(在 bison 3.0.4 中)显示为:

    if (! ()) YYERROR;

如果您在 </code> 之前添加一个换行符,那么它将显示为 </p> <pre><code> if (! ( )) YYERROR;

那么一切都应该顺利进行。 (至少,我测试的时候是这样的。)