如何初始化Bison的%union值?

时间:2009-08-10 22:46:27

标签: c bison yacc lex flex-lexer

在野牛我有一个工会

%union
{
   std::string* sval;
}

我想像这样使用它

在Lex:

*(yylval->sval) = "ABCD";

而不是

yylval->sval = new std::string("ABCD");

为了防止内存泄漏

但是我需要一些方法将std :: string分配给sval开始。

我该怎么做?

2 个答案:

答案 0 :(得分:2)

你不能安全地将带有构造函数或析构函数的类型(例如std :: string)放在union中,所以这不起作用。

你可以做的不是使用%union - 而是使用宏将YYSTYPE直接映射到其他类型:

%{
#define YYSTYPE std::string
%}

然后yylval将是该类型(语法代码中的所有$ n选项)

答案 1 :(得分:0)

我不是完全清楚你为什么要这样做,但我可以看到你为什么没有工作。这是因为"ABCD"const char *,而不是std::string

我知道Yacc的第一"%{ ... %}"部分允许定义Yacc的控制之外Ç东西(和它出现野牛具有类似的特征的基础上,它的向上兼容性要求和文档{{3} },2.1.1)。你为什么不放:

std::string *strABCD = new std::string("ABCD");

在该部分中然后使用:

yylval->sval = strABCD;

以后什么时候需要指向该字符串的指针?

在我看来,这是实现你想要的最简单方法。

如果你担心Bison解析器中的分配没有被释放(它们应该是),我的建议是不要在那里进行。您可以在调用yyparse()之前设置字符串,然后在返回后将其释放。

更新

以下是我如何避免在Bison解析器中分配/释放该固定值。将其设置为在程序持续期间存在的全局。

主要代码:

std::string *strABCD = new std::string ("ABCD");

int main(...) {
    // Do some stuff.
    : : :
    yyparse();
    : : :
    // Do some other stuff.
}

野牛解析器来源:

%{
    extern std::string *strABCD;
%}
: : :
yylval->sval = strABCD;

返回固定指针到你的ABCD字符串 no 分配或在Bison代码中释放(甚至在主代码中也很少)。