如何从 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
。因此,我有自己的 class SharedPtr
,实现了所需的行为。
不幸的是,我无法在 union 中插入 SharedPtr
class,如下所示:
%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
class 而不是作为指针。为了获得替代解决方案,我也希望进行哪些最小的更改?
基本问题是 bison 的 C 接口大量使用联合(来自 %union)并且 C 联合与 C++ 非常不兼容(在 C++11 之前你根本不能将它们用于非平凡类型和即使 post C++11 也很难安全使用。
可能会使用 Bison's C++ mode,但这是一个相当冗长且范围广泛的更改。或者,您可以(小心地)使用原始指针和其他可以安全放入联合的类型。但是,您需要非常小心以避免内存泄漏(并使用 bison 的 %destructor
来避免语法错误造成的泄漏)
另一种可能性是根本不使用 %union
——而是使用 #define YYSTYPE SharedPtr<Item>
使堆栈值成为您将在代码中随处使用的单个共享指针。您需要让您的 Item
类型成为基础 class,所有其他类型都派生自它,并酌情使用虚函数。
我有典型的可重入 C 风格解析器,其中解析的数据包含在一个联合中,如下所示:
%union {
int number;
const char *string;
Item *item_ptr;
}
我想使用 共享指针 而不是普通指针。
我不能用std::shared_ptr
因为我不能用C++11
编译源代码,我也被禁止使用boost::shared_ptr
。因此,我有自己的 class SharedPtr
,实现了所需的行为。
不幸的是,我无法在 union 中插入 SharedPtr
class,如下所示:
%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
class 而不是作为指针。为了获得替代解决方案,我也希望进行哪些最小的更改?
基本问题是 bison 的 C 接口大量使用联合(来自 %union)并且 C 联合与 C++ 非常不兼容(在 C++11 之前你根本不能将它们用于非平凡类型和即使 post C++11 也很难安全使用。
可能会使用 Bison's C++ mode,但这是一个相当冗长且范围广泛的更改。或者,您可以(小心地)使用原始指针和其他可以安全放入联合的类型。但是,您需要非常小心以避免内存泄漏(并使用 bison 的 %destructor
来避免语法错误造成的泄漏)
另一种可能性是根本不使用 %union
——而是使用 #define YYSTYPE SharedPtr<Item>
使堆栈值成为您将在代码中随处使用的单个共享指针。您需要让您的 Item
类型成为基础 class,所有其他类型都派生自它,并酌情使用虚函数。