我想在yacc文件中添加union in union但是我发现了这个错误:
“错误:成员'信息YYSTYPE :: info',联合中不允许使用构造函数”
%{
#include <cstdio>
#include <iostream>
using namespace std;
extern "C" int yylex();
extern "C" int yyparse();
extern "C" FILE *yyin;
struct Info{ int intval; float floatval; string stringval ;int type; }
void yyerror(const char *s);
%}
%union {
int ival;
float fval;
char *sval;
struct Info info;
}
答案 0 :(得分:1)
你不能在C ++中将非POD结构放在一个联合中,因为编译器无法告诉构造或破坏哪个联合成员。
另一种方法是在联合中使用指针:
%union {
...
Info *info;
};
在这种情况下,如果/不再需要它们,则需要注意显式删除指针。如果有错误,Bison的%destructor
在这里可以用来避免泄漏。
或者,根本不要使用%union
- 只需将YYSTYPE
定义为单一类型:
%{
#define YYSTYPE struct Info
%}
在这种情况下,您的所有规则都需要使用相同的类型(没有%type
声明,以使不同的规则产生不同的东西)。如果你真的需要不同的类型,像boost::variant
这样的东西会很有用。
答案 1 :(得分:0)
我没有看到使用具有相同成员的union和struct的意义。你应该使用其中一个。
如果告诉bison发出C ++解析器,您可以选择使用类似变体的语义类型。使用C或C ++解析器,您可以使用union或struct,但在任何情况下都不能包含C ++ std::string
作为union成员,甚至是间接的,正是因为该错误消息中指出的原因。这与野牛没什么关系; C ++不会让你用一个具有构造函数的成员定义一个union,除非union本身有一个构造函数。 (a如果您尝试编写所需的构造函数,您可能会看到为什么该语言无法为您执行此操作。)
如果您不想让内存管理陷入困境,那么野牛的变种选项可能适合您。阅读手册中的文档。否则,您可以使用指向std::string
(使用new
运算符创建)的指针,或者您可以只使用C字符串。在这两种情况下,您都需要分配和释放存储。
答案 2 :(得分:0)
Union只允许你使用原始类型和指针。
如果需要使用结构,那么在联合中,您只能声明指向该结构的指针。