Bison 野牛错误处理

Bison 野牛错误处理,bison,yacc,parser-generator,Bison,Yacc,Parser Generator,我对Bison的错误处理有问题。我有以下语法(我只删去了相关部分)。如果字符串“CONFIGPARAM”被解析,Flex将其令牌发送给Bison并返回终端符号“KW_CONFIGPARAM”。IDENT是指向C++字符串对象的指针。 statementlist : statement ';' { $$ = new string("statementlist"); } | statementlist statement ';' { $

我对Bison的错误处理有问题。我有以下语法(我只删去了相关部分)。如果字符串“CONFIGPARAM”被解析,Flex将其令牌发送给Bison并返回终端符号“KW_CONFIGPARAM”。IDENT是指向C++字符串对象的指针。
statementlist   : statement ';'               { $$ = new string("statementlist"); }
                | statementlist statement ';' { $$ = new string("statementlist"); }
;
statement       : KW_CONFIGPARAM IDENT        { $$ = new string("statement"); /* use $2, IDENT is used in main program */ }
;
我为像IDENT这样的字符串指定了以下析构函数

%析构函数{printf(“在第%d行释放:%s\n”,@$.first_行,$$->c_str());delete($);}

现在我有以下输入。第一行有效,第二行无效(缺少标识符):

输出:

In input 2:12 - 2:12 : syntax error
free at line 2: p
free at line 1: statementlist
由于第二行中的错误,Bison会投诉,返回语法错误并调用解析堆栈上所有对象的析构函数。 现在我不明白为什么会调用第一行中标识符“p”的析构函数?它属于第一行,已成功解析。问题是p在主程序中使用,不应该被Bison删除

ConfigParam p;
foo;

In input 2:1 - 2:3 : syntax error
free at line 1: statementlist
free at line 2: foo
如果我选择作为(无效)语句,Bison不会删除任意字符串(“foo”)p

ConfigParam p;
foo;

In input 2:1 - 2:3 : syntax error
free at line 1: statementlist
free at line 2: foo

为什么这样做?

在不查看更多文件的情况下,很难说出确切的问题,但情况肯定不是这样

第一行已成功解析,应弹出堆栈

错误点处的堆栈如下所示:

statementlist KW_CONFIGPARAM
其中,
statementlist
是通过减少第一行创建的,正如bison报告的那样

您似乎没有为语句列表指定值;如果您的摘录是文字的,那么它将被编译,就像它是被编写的一样:

statementlist   : statement ';'                 {$0 = $1;}
我不知道与
语句
对应的值是什么,但可以肯定的是,它包含字符串
“p”
。这取决于您在
{/*执行某些操作时将
$0
设置为什么,请创建一个新的ConfigParam对象*/}

(从一条评论中移走,因为很明显,这有点接近正确答案。)
我的另一个想法是:也许你已经让你所有的终端和非终端都有一个触发析构函数的类型。当你的lexer返回
KW\u CONFIGPARM
时,它可能不会修改
yylval
。在这种情况下,bison解析器无法知道
yylval
是不相关的,因此它将使用剩余的
yylval
(它是指向
“p”
)的指针。

@rici:非常感谢,您为我指明了正确的方向。我写过

%token <str>    STRING    IDENT       NUMBER
                KW_CONFIGPARAM
%令牌字符串标识号
千瓦配置参数
但正确的答案当然是

%token <str>    STRING    IDENT       NUMBER
%token          KW_CONFIGPARAM
%令牌字符串标识号
%令牌KW_CONFIGPARAM


@里希:你让我开心

谢谢你的回答。我重写了这个例子,希望它现在更清楚。你有什么想法吗?@user4811:我的另一个想法是:也许你已经让你所有的终端和非终端都有一个触发析构函数的类型。当你的lexer返回
KW\u CONFIGPARM
时,它可能不会修改
yylval
。在这种情况下,bison解析器无法知道
yylval
是不相关的,因此它将使用剩余的yylval(它是指向
p
的指针)。再说一次,我只是在猜测,因为我看不到你的项目。