如何从 C 型移动到 C++ 样式的 flex 解析器
How to move from a C to C++ style flex parser
我有典型的可重入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
类型成为基类,所有其他类型都派生自基类,并根据需要使用虚函数。