联合 C++ YACC 中的结构

struct in union c++ yacc

本文关键字:结构 YACC C++ 联合      更新时间:2023-10-16

我想在 yacc 文件中添加联合结构,但我发现此错误:

"错误:成员'信息 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;
}

您不能将非 POD 结构放在 C++ 的联合中,因为编译器无法分辨要构造或销毁哪个联合成员。

一种替代方法是在联合中使用指针:

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

在这种情况下,您需要小心在不再需要指针时显式删除指针。 野牛的%destructor在这里很有用,可以在出现错误时避免泄漏。

或者,根本不要使用%union - 只需将YYSTYPE定义为单个类型:

%{
#define YYSTYPE struct Info
%}

在这种情况下,所有规则都需要使用相同的类型(没有%type声明让不同的规则产生不同的东西(。 如果您真的需要不同的类型,像boost::variant这样的东西会很有用。

我不认为同时使用具有相同成员的联合和结构有什么意义。您应该使用其中之一。

如果你告诉 bison 发出一个C++解析器,你可以选择使用类似变体的语义类型。使用 C 或 C++ 分析器,您可以使用联合或结构,但在这两种情况下,您都不能将C++ std::string作为联合成员包含在内,即使是间接的,正是由于该错误消息中指示的原因。这与野牛关系不大;C++不允许你定义具有构造函数的成员的联合,除非联合本身具有构造函数。(a如果你尝试编写所需的构造函数,你可能会明白为什么语言没有办法为你做到这一点。

如果您不想弄乱内存管理,Bison的变体选项可能适合您。阅读手册中的文档。否则,可以使用指向std::string(使用 new 运算符创建的(的指针,也可以只使用 C 字符串。在这两种情况下,您都需要分配和释放存储。

Union 只允许你使用基元类型和指针。

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