union in union c ++ yacc

时间:2016-05-13 19:10:15

标签: c++ struct yacc

我想在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;

}

3 个答案:

答案 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只允许你使用原始类型和指针。

如果需要使用结构,那么在联合中,您只能声明指向该结构的指针。