2009-08-10 108 views
1

野牛我有一個工會如何初始化Bison的%聯合值?

%union 
{ 
    std::string* sval; 
} 

而且我想用它像這樣

在萊克斯:

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

不是

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

爲了防止內存泄漏容易

但是我需要一些方法來分配一個std :: string到sval開始。

我該怎麼做?

回答

0

我不是完全是明確你爲什麼要這樣做,但我可以看到你爲什麼沒有工作。這是因爲"ABCD"const char *,而不是std::string

我知道Yacc的第一"%{ ... %}"部分允許您定義Yacc的控制之外Ç東西(它似乎野牛有類似的功能,基於它的向上兼容性要求和文檔here,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. 
} 

Bison分析器來源:

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

返回固定指針到您的ABCD字符串沒有分配或全部野牛代碼釋放(和珍貴即使在主代碼中也很少)。

+0

因爲現在你有內存泄漏,除非你將輸入釋放給Yacc以滿足每個規則。 – DevDevDev 2009-08-10 23:03:00

+0

好的,但如果你要分配內存,那麼你需要釋放它。如果你不想這樣做,不要分配 - 改變你的聯合是一個char *來代替。我寫的大多數解析器都是一次性的,所以前綴代碼「泄漏」一個std :: string將是無關緊要的。你的架構可能會有所不同。或者在調用解析器之前將其設置,然後再將其拆下。查看更新。 – paxdiablo 2009-08-10 23:13:47

+0

您的代碼將爲每個與返回類型匹配的規則泄漏一個字符串。 – DevDevDev 2009-08-10 23:23:53

2

您不能安全地將類型與構造函數或析構函數(如std :: string)放在聯合中,所以這不起作用。

你可以做的,而不是不使用%工會在所有 - 而不是使用宏來直接映射到YYSTYPE一些其他類型:

%{ 
#define YYSTYPE std::string 
%} 

那麼的yylval將是此類型(如將所有的$ n語法代碼中的選項)

+0

我該在哪裏做?另外我該如何定義我的規則的類型? 像 %型規則 – DevDevDev 2009-08-10 23:15:02

+0

我嘗試過了,現在我得到「無法從字符*轉換爲semantic_type *」 – DevDevDev 2009-08-10 23:24:25

+0

我不認爲你的代碼工作。 – DevDevDev 2009-08-10 23:32:59