所以我试图使用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/