对结构使用 %union

using %union for structs

本文关键字:%union 结构      更新时间:2023-10-16

我搜索了很多,但似乎找不到有关如何使用 %union 是我的解析器文件的清晰示例。 例如,我想将以下令牌保存在名为classID的结构中:

[a-zA-Z][a-zA-Z0-9]*            { yylval=new IDClass(yytext); return ID; }

这是我包含的.hpp文件夹中的结构:

class Node {
public:
Node(){}
};

class IDClass : public Node {
public:
string name;
IDClass(string name):
Node(),name(name)
{}
};

然后在我的.ypp文件中,我想使用它进行某些检查:

Define: Type ID { if(doesIDexists(***$2->name***)){errorDef(yylineno, ID_ptr->name);exit(1);}}

但显然,$2-> name不会返回它。%union 在结构中的正确用法是什么?如何正确获取名称的值?

提前谢谢你。

没有"在结构中正确使用%union",因为%union用于声明union。(当然,你可以只用一个成员声明一个union,但这几乎毫无意义。

声明不是union语义类型的正确方法是:

%define api.value.type { Node* }

但这不会得到你想要的,因为你想要的既不是union也不是固定类型,而是隐式动态强制转换或类似的东西。这不在野牛的选项菜单上。(很容易理解为什么不这样做。动态演员阵容不会是一个左值,所以野牛必须知道什么时候应用它,什么时候不应用它。

所以你可以使用上面的%define api.value.type,然后写出语法操作:

Define: Type ID { if (doesIDexist(dynamic_cast<IDClass>($2)->name)) {
errorDef(@2.first_line,
dynamic_cast<IDClass>($2)->name);
exit(1);
}
}

如果您生成一个 C++ 解析器而不是恰好在 C++ 中工作的 C 解析器,那么您还有其他一些选择,这些选项可能是也可能不是对您的应用程序的更好修复。C解析器的选项在Bison手册的语言语义章节中进行了解释,C++选项有自己的章节,尽管如果您要使用C++界面,则需要阅读整个C++部分。

注意:我yylineno更改为@2.first_lineyylineno因为通常不准确;yylineno通常是与前瞻标记关联的行号,该行号通常与错误不在同一行上。但你不能只是做出改变;您还必须确保您的词法分析器正确填写yylloc。请参阅野牛手册中的跟踪位置章节。