我有 YYSTYPE
定义于 parser.hpp
归档 scanner.lex
使用:
// parser.hpp
#define YYSTYPE Atom
typedef struct Atom
{
int i_value;
TypeEnum e_type;
string *str_value;
Node *node;
} atom_t;
在 parser.ypp
我收到一个错误的 RetType
"在行动中使用的语义值,但没有声明类型"
RetType:
Type {}
| VOID {
debugPrint("Here");
$$.e_type = TYPE_VOID;
}
;
我想摆脱这个错误,并使用 %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
完全没有。然而,野牛允许你使用 %type
声明与 api.value.type
声明,但如果你使用了 %type
声明的任何地方,你必须对其值被引用的所有语法符号使用它(这与对使用了 %union
声明)。)
如果您声明 %type <atom>
为一个特定的语法符号,然后野牛翻译任何对该符号的语义值的引用($$
或 $n
符号是在左手边还是右手边,取决于符号是在 :
)变成实际上是 $$.atom
. 这是一个简单的文本替换,因为 bison 对语义类型本身并不了解,而且它也不要求选择器是一个简单的词;如果你想的话,你可以使用 %type <atom.node>
在这种情况下,所有对这些符号值的引用都将是 .atom.node
附加到它们上面。在联盟之外,这通常不是很有用,因为你不再有任何方法来引用基值,但你可能有一个适合的用例。