如何从 C 型移动到 C++ 样式的 flex 解析器

How to move from a C to C++ style flex parser

本文关键字:样式 flex C++ 移动      更新时间:2023-10-16

我有典型的可重入C 样式解析器,其中解析的数据包含在如下所示的联合中:

%union {
int number;
const char *string;
Item *item_ptr;
}

我想使用共享指针而不是普通指针。

我不能用std::shared_ptr因为我不能用C++11编译源代码,我也禁止使用boost::shared_ptr。因此,我有自己的类SharedPtr,实现所需的行为。

不幸的是,我无法在工会内插入SharedPtr类,如下所示:

%union {
int number;
const char *string;
SharedPtr<Item> item_ptr;
}

因为我收到以下错误:

bisonparser.yy:92:20: error: member ‘SharedPtr<Item> YYSTYPE::item_ptr’ with constructor not allowed in union
bisonparser.yy:92:20: error: member ‘SharedPtr<Item> YYSTYPE::item_ptr’ with destructor not allowed in union
bisonparser.yy:92:20: error: member ‘SharedPtr<Item> YYSTYPE::item_ptr’ with copy assignment operator not allowed in union
bisonparser.yy:92:20: note: unrestricted unions only available with -std=c++11 or -std=gnu++11

另一种方法是插入间接寻址级别,如下所示:

%union {
int number;
const char *string;
SharedPtr<Item> *item_ptr;
}

但是,我想知道是否有一种更简洁的方式来设计我的项目,以便我可以直接使用我的SharedPtr类而不是作为指针。为了获得替代解决方案,我也在寻找哪些最小的更改?

基本问题是 bison 的 C 接口大量使用联合(来自 %union(,而 C 联合与C++非常不兼容(C++11 之前,您根本无法将它们与非平凡类型一起使用,甚至在 C++11 之后,它们也很难安全使用(。

关于使用Bison的C++模式的可能性,但这是一个相当冗长和广泛的变化。 或者,您可以(小心地(使用原始指针和其他可以安全放入联合中的类型。 但是,您需要非常小心以避免内存泄漏(并使用野牛%destructor以避免语法错误的泄漏(

另一种可能性是根本不使用%union- 而是使用#define YYSTYPE SharedPtr<Item>使堆栈值成为单个共享指针,您将在代码中的任何地方使用。 您需要使Item类型成为基类,所有其他类型都派生自基类,并根据需要使用虚函数。