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;
那么一切都应该顺利进行。 (至少,我测试的时候是这样的。)
所以我正在尝试使用 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;
那么一切都应该顺利进行。 (至少,我测试的时候是这样的。)