我对 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 之类的字符串指定了以下析构函数。
%destructor { printf ("free at line %d: %s\n",@$.first_line, $$->c_str()); 删除($$);}
现在我有以下输入。第一行有效,第二行无效(缺少标识符):
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 删除。
如果我选择作为(无效)语句,任意字符串(“foo”) p 不会被 Bison 删除。
ConfigParam p;
foo;
In input 2:1 - 2:3 : syntax error
free at line 1: statementlist
free at line 2: foo
为什么这行得通?