我对Bison的错误处理有一个问题。我有以下语法(我只删掉了相关的部分)。Flex将其令牌发送给Bison,如果解析了字符串"ConfigParam“,则返回终端符号"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_line,$$->c_str());delete($$);}
现在我有以下输入。第一行有效,第二行无效(缺少标识符):
ConfigParam p;
ConfigParam;输出:
In input 2:12 - 2:12 : syntax error
free at line 2: p
free at line 1: statementlist由于第二行中的错误,Bison发出抱怨,返回语法错误,并调用解析堆栈上所有对象的析构函数。现在我不明白为什么第一行的标识符"p“的析构函数被调用了?它属于第一行,并且已成功解析。问题是p是在主程序中使用的,不应该被Bison删除。
如果我选择作为(无效)语句,Bison不会删除任意字符串("foo") p。
ConfigParam p;
foo;
In input 2:1 - 2:3 : syntax error
free at line 1: statementlist
free at line 2: foo为什么这是可行的?
发布于 2013-01-27 01:47:44
在没有看到更多文件的情况下,很难判断出确切的问题,但情况肯定不是这样的
第一行已成功解析,应从堆栈中弹出
错误点处的堆栈如下所示:
statementlist KW_CONFIGPARAM其中statementlist是通过减少第一行而创建的,正如bison所报道的那样。
您似乎没有为statement_list指定一个值;如果您的摘录是文字,那么它将被编译,就像它已经被编写一样:
statementlist : statement ';' {$0 = $1;}我不知道对应于statement的值是什么,但可以肯定的是,它包含字符串"p"。这取决于您在{ /* do some stuff, create a new ConfigParam object */ }期间将$0设置为什么。
(当它明显地接近正确答案时,从评论中移走。)我的另一个想法是:也许你已经让所有的终端和非终端都有一个触发析构函数的类型。也许您的词法分析器在返回KW_CONFIGPARM时不会修改yylval。在这种情况下,bison解析器无法知道yylval是不相关的,因此它将使用yylval上的左键(这是指向"p"的指针)。
发布于 2013-01-27 08:46:14
@rici:非常感谢,你给我指明了正确的方向。我已经写了
%token <str> STRING IDENT NUMBER
KW_CONFIGPARAM但正确当然是..。
%token <str> STRING IDENT NUMBER
%token KW_CONFIGPARAM啊!
@rici:你让我开心了!
https://stackoverflow.com/questions/14537906
复制相似问题