Compilation 如何使用%union和fix“在操作内部使用但尚未声明类型的语义值”警告

Compilation 如何使用%union和fix“在操作内部使用但尚未声明类型的语义值”警告,compilation,bison,semantics,lex,Compilation,Bison,Semantics,Lex,我在parser.hpp文件中定义了YYSTYPE,以便scanner.lex使用: 在parser.ypp中,我在RetType上得到一个错误 在操作内部使用的语义值,但尚未声明类型 我想消除错误并使用%union,但无法确定如何: // %union { struct atom_t atom; } %type <atom> RetType; 你真的不应该使用 #define YYSTYPE Atom 如果您这样做,您将无法使用%union或bison提供的任何其他方式

我在parser.hpp文件中定义了YYSTYPE,以便scanner.lex使用:

在parser.ypp中,我在RetType上得到一个错误

在操作内部使用的语义值,但尚未声明类型

我想消除错误并使用%union,但无法确定如何:

// 
%union {
  struct atom_t atom;
}

%type <atom> RetType;

你真的不应该使用

#define YYSTYPE Atom
如果您这样做,您将无法使用%union或bison提供的任何其他方式来声明语义类型,因为将define YYSTYPE放入外部头文件完全绕过了bison设置语义类型本身的尝试

你应该做的是使用

%define api.value.type { Atom } 
在你的野牛开场白中。这将把YYSTYPE的声明复制到bison生成的头文件中,因此您不需要在自己的头文件中担心它

当然,这假设您满足于所有终端和非终端使用相同的语义值类型,因此根本不需要使用%type。但是,bison允许您将%type声明与api.value.type声明结合使用,但有一个限制条件,即如果您在任何地方使用%type声明,则必须将其用于引用其值的所有语法符号,这与使用%union声明的语法的要求相同

如果为特定语法符号声明%type,那么bison会将对该符号语义值$$或$n的任何引用转换为$$.atom,具体取决于该符号是位于:的左侧还是右侧。这是一个简单的文本替换,因为bison对语义类型本身一无所知,也不要求选择器是一个简单的单词;如果愿意,可以使用%type,在这种情况下,对这些符号值的所有引用都将附加.atom.node。在联合之外,这通常不是很有用,因为您不再有任何方法引用基值,但您可能有一个适合的用例。

为什么要使用%union?如果使用%union,则不能使用define YYSTYPE。但是,无论如何,你不应该使用它。
#define YYSTYPE Atom
%define api.value.type { Atom }