为什么使用 yyclearin 不会在 bison 中触发 %destructor
Why does the use of yyclearin not trigger %destructor in bison
尽管有 %destructor 处理程序,但我在 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(); }
| KEYWORD ERROR { yyclearin; yyerrok; someResync(); }
;
对于以下输入:
KEYWORD KEYWORD "string1"
KEYWORD "string2"
第一个输入行与第一个规则匹配,字符串被所属操作释放 'manually'。
第二个输入行被错误规则选中。作为前瞻读取的字符串
令牌触发错误并被 yyclearin 遗忘。但是
分配的内存仍然泄漏。需要做什么才能调用 %destructor?
这是一个很好的问题。
我本以为丢弃lookahead token会落入"when user actions cannot manage memory"的范畴。但是 yyclearin
所做的只是重置 yych
,强制在下次需要前瞻时读取新令牌。
实际上,这意味着您的使用操作(调用 yyclearin
)需要管理内存。通过稍微深入 bison 的内部结构,我们可以相当简单地做到这一点:
#define my_yyclearin \
yydestruct ("Clearin: discarding", yytoken, &yylval); \
yychar = YYEMPTY;
(如果您使用位置,则必须将 yylloc
添加到 yydestruct
调用中。)
yydestruct
是一个未记录的 bison 内部,如果启用了跟踪,它会调用正确的析构函数并打印出 teace 消息。 yytoken
是保存在 yychar
中的令牌值的内部版本(使用索引值的压缩范围来减少 table 大小)。 yychar
和 yylval
变量已记录在案,因此使用它们应该是安全的。
这充其量只是一种粗略的解决方法。我已将此问题作为错误报告给野牛维护人员。
尽管有 %destructor 处理程序,但我在 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(); }
| KEYWORD ERROR { yyclearin; yyerrok; someResync(); }
;
对于以下输入:
KEYWORD KEYWORD "string1"
KEYWORD "string2"
第一个输入行与第一个规则匹配,字符串被所属操作释放 'manually'。 第二个输入行被错误规则选中。作为前瞻读取的字符串 令牌触发错误并被 yyclearin 遗忘。但是 分配的内存仍然泄漏。需要做什么才能调用 %destructor?
这是一个很好的问题。
我本以为丢弃lookahead token会落入"when user actions cannot manage memory"的范畴。但是 yyclearin
所做的只是重置 yych
,强制在下次需要前瞻时读取新令牌。
实际上,这意味着您的使用操作(调用 yyclearin
)需要管理内存。通过稍微深入 bison 的内部结构,我们可以相当简单地做到这一点:
#define my_yyclearin \
yydestruct ("Clearin: discarding", yytoken, &yylval); \
yychar = YYEMPTY;
(如果您使用位置,则必须将 yylloc
添加到 yydestruct
调用中。)
yydestruct
是一个未记录的 bison 内部,如果启用了跟踪,它会调用正确的析构函数并打印出 teace 消息。 yytoken
是保存在 yychar
中的令牌值的内部版本(使用索引值的压缩范围来减少 table 大小)。 yychar
和 yylval
变量已记录在案,因此使用它们应该是安全的。
这充其量只是一种粗略的解决方法。我已将此问题作为错误报告给野牛维护人员。