所以我试图使用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指令之前添加一个换行符可以解决语法错误(但是直接修改生成的文件有点麻烦)。另外,为了让gcc计算代码的右列位置,您必须与一些空格对齐)。
我想知道这是bison本身的一个bug,还是我使用的语义谓词错误,或者这个语法在早期版本的gcc中是正确的,或者其他什么东西。
我也试过在网上搜索这个问题,或者搜索一个已经提交给bison的bug,但是没有找到。(最新的野牛版本似乎只有3岁。如果这个问题没有得到任何解决,我会感到惊讶。有人能告诉我这个问题吗?谢谢。
如果有必要,我可以试着向野牛提交一个bug(需要弄清楚怎么做),但我不确定这是我自己的问题还是什么。

最佳答案

据我所见,这个bug已经出现了一段时间(可能是因为引入了语义谓词特性,尽管似乎有人应该在某个时候用bison的某个版本来测试它)
最简单的解决方法是关闭#line指令的生成,只需将-l(或--no-lines)添加到bison命令行即可。但是,这将使解释错误消息变得更加困难,否则错误消息将引用bison语法文件中的行号。
作为第二种解决方法,您可以找到文件c.m4,该文件可能位于/usr/share/bison/c.m4(当然,这取决于您的发行版)。该文件的第462行(在bison 3.0.4中)读取:

    if (! ($2)) YYERROR;

如果在$2之前添加一个换行符,那么它将显示
    if (! (
           $2)) YYERROR;

那一切都会好起来的。(至少,我测试的时候是这样的。)

关于c - 野牛语义谓词语法错误,流浪“#”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50550637/

10-12 20:47