GNU Bison生成的解析器在给定非空文件时抛出分段错误11

Parser generated by GNU Bison throws a segmentation fault 11 when given a non-empty file

本文关键字:文件 错误 分段 Bison GNU      更新时间:2023-10-16

每当我用有效文件调用yyparse()时,我都会得到一个seg错误,似乎是由以下代码行(大约1789行)引起的:

if (yyss + yystacksize - 1 <= yyssp){

我通过在这行代码前后打印调试消息得出了这个结论。这一行之前的信息已打印,但这一行之后的信息未打印。

奇怪的是,如果我用一个空文件调用yyparse(),则不会引发错误,但如果文件中至少有一个字符,则会引发错误。

解析器本身已编译,没有任何错误。这个seg故障背后的原因是什么?

解析文件:https://gist.github.com/SamTebbs33/bffb72517f174af679ef

调试消息代码:

cout << "before if" << endl;
if (yyss + yystacksize - 1 <= yyssp){
cout << "after if" << endl;
cout.flush();

在抛出错误之前,第一条调试消息会打印3次。

编辑:当55令牌在yyrreduce标签中匹配时,switch语句中实际上抛出了错误:

case 55:
#line 219 "grammar/grammar.y" /* yacc.c:1661  */
{
cout << "processing token 55" << endl;
(yyval.id) = new TIdentifier(*(yyvsp[0].string));
cout << "processed token 55" << endl;
}
#line 2228 "grammar/parser.cpp" /* yacc.c:1661  */
break;

在到达switch语句之前,我打印被切换变量的整数值,其值为55,因此错误代码应该在上述代码内,因为"已处理的令牌55"没有打印,而是打印了"正在处理的令牌"。以下是TIdentifier构造函数的代码:

TIdentifier(std::string name) : name(name) {
}

这意味着在取消引用(yyvsp[0].string)时必须产生错误

(由OP在问题编辑中回答。转换为社区wiki答案,更适合StackOverflow的问答格式)。

OP写道:

经过进一步的调试,我意识到我的flex语法没有按应有的方式保存文件中的字符串,并且试图访问yylval中不存在的元素,解析器现在可以工作了!

然而,正如@rici:所指出的,最好将核心材料包括在问题中

查看您的bison输入文件(.y)比查看生成的解析器更有用(或者至少更容易)。