虽然有一个%析构函数处理程序,但在bison语法的错误恢复中出现内存泄漏。这似乎取决于yyclearin的使用。
以下是语法摘录:
%union {
int val;
const char* str; /* allocated in the lexer with strdup() */
}
%token <int> KEYWORD
%token <str> STR
%destructor { free($$); } <str>
...
%%
...
problem
: KEYWORD KEYWORD STR {doSomething(); free($3); }
| KEYWORD ERROR { yyclearin; yyerrok; someResync(); }
;
对于以下输入:
KEYWORD KEYWORD "string1"
KEYWORD "string2"
第一个输入行与第一个规则匹配,字符串被手动释放&#39;通过归属行动。 第二个输入行被错误规则选中。该字符串作为前瞻读取 令牌触发错误并被yyclearin遗忘。但是 分配的内存仍然泄漏。需要做些什么来调用%析构函数?
答案 0 :(得分:1)
这是一个很好的问题。
我原本以为丢弃前瞻标记会属于&#34;当用户操作无法管理内存时#34;。但所有yyclearin
都会重置yych
,强制在下次需要预测时读取新令牌。
实际上,这意味着您的使用操作(调用yyclearin
)需要管理内存。通过稍微闯入野牛的内部,我们可以相当简单地做到这一点:
#define my_yyclearin \
yydestruct ("Clearin: discarding", yytoken, &yylval); \
yychar = YYEMPTY;
(如果您使用地理位置,则必须在yylloc
电话中添加yydestruct
。)
yydestruct
是一个未记录的bison内部函数,它调用正确的析构函数并在启用跟踪时打印出teace消息。 yytoken
是yychar
中保留的令牌值的内部版本(使用压缩范围的索引值来减小表大小)。 yychar
和yylval
变量已记录在案,因此它们应该可以安全使用。
这充其量只是一个原始的解决方法。我已将此问题报告为野牛维护者的错误。