C++ 对结构使用%union

C++ 对结构使用%union,c++,struct,bison,C++,Struct,Bison,我搜索了很多,但似乎找不到关于如何使用我的解析器文件%union的清晰示例。 例如,我想将以下令牌保存在名为classID的结构中: [a-zA-Z][a-zA-Z0-9]* { yylval=new IDClass(yytext); return ID; } 这是我的.hpp文件夹中的结构,其中包括: class Node { public: Node(){} }; class IDClass : public Node {

我搜索了很多,但似乎找不到关于如何使用我的解析器文件%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在结构中的正确用法是什么?如何正确地获取name的值

提前谢谢。

结构中没有“正确使用
%union
”,因为
%union
用于声明
union
。(当然,您可以声明一个只有一个成员的
联合,但这几乎毫无意义。)

声明非联合的语义类型的正确方法是:

%define api.value.type { Node* }
但这不会得到你想要的,因为你想要的既不是一个
联合,也不是一个固定类型,而是一个隐式动态转换,或者类似的东西。这不是野牛的菜单上的选项。(不难看出原因。动态演员阵容不会是左值,因此野牛必须知道何时应用和何时不应用。)

因此,您可以使用上面的
%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);
                      }
                }
Define:Type ID{if(doesIDexist(dynamic_cast($2)->name)){
errorDef(@2.first_行,
动态_cast($2)->名称);
出口(1);
}
}
<>如果生成C++解析器而不是C++分析器,它在C++中工作,那么你还有其他选项,这可能对你的应用程序可能不是更好的修复。C解析器的选项在BISON手册的章节中解释,C++选项有,虽然如果你要使用C++接口,你需要阅读整个C++部分。 注:我将
yylineno
改为
@2。第一行
,因为
yylineno
通常不准确
yylineno
通常是与先行令牌关联的行号,该行号通常与错误不在同一行。但你不能只是做出改变;您还必须确保lexer正确填写
yylloc
。参见野牛手册中的章节