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