Sara Raslan
Sara Raslan

Reputation: 1

struct in union c++ yacc

I want to add struct in union in a yacc file but I found this error:

"error : member 'Info YYSTYPE ::info' with constructor not allowed in union "

%{
#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;

}

Upvotes: 0

Views: 1057

Answers (3)

Aleksandar Makragić
Aleksandar Makragić

Reputation: 1997

Union only allows you to use primitive types and pointers.

If you need to use structure, then in union you can only declare pointer to that structure.

Upvotes: 0

rici
rici

Reputation: 241861

I don't see the point of using both a union and a struct with the same members. You should use one or the other.

If you tell bison to emit a C++ parser, you can choose to use a variant-like semantic type. With either the C or the C++ parser, you can use a union or a struct, but in neither case can you have include a C++ std::string as a union member, even indirectly, precisely for the reason indicated in that error message. This has very little to do with bison; C++ won't let you define a union with a member which has a constructor unless the union itself has a constructor. (aIf you try to write the required constructor, you might see why the language has no way of doing it for you.)

If you don't want to have to mess around with memory management, bison's variant option may be for you. Read the documentation in the manual. Otherwise, you could use a pointer to a std::string (created with the new operator), or you could just use a C-string. In both cases, you will need to allocate and release storage.

Upvotes: 0

Chris Dodd
Chris Dodd

Reputation: 126408

You can't put non-POD structs in a union in C++, because there's no way for the compiler to tell which union member to construct or destruct.

One alternative is to use pointers in the union:

%union {
    ...
    Info *info;
};

in which case you need to be careful about explicitly deleting the pointers if/when they are no longer needed. Bison's %destructor can be useful here to avoid leaks if there are errors.

Alternately, don't use %union at all -- just define YYSTYPE as a single type:

%{
#define YYSTYPE struct Info
%}

in which case all your rules need to use the same type (no %type declarations to have different rules produce different things). Something like boost::variant can be useful if you really need to have different types..

Upvotes: 1

Related Questions