Reputation: 1
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
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
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
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