对结构使用 %union
using %union for structs
我搜索了很多但似乎找不到关于如何使用 %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(***->name***)){errorDef(yylineno, ID_ptr->name);exit(1);}}
但显然,$2->name 不会 return 它。 %union 在结构中的正确用法是什么?如何正确获取 name 的值?
提前致谢。
没有"correct use of %union
in structs",因为%union
用于声明union
。 (当然,您可以声明一个只有一个成员的 union
,但这几乎毫无意义。)
声明不是 union
的语义类型的正确方法是:
%define api.value.type { Node* }
但这不会得到你想要的,因为你想要的既不是 union
也不是固定类型,而是隐式动态转换或类似的东西。这不在 Bison 的选项菜单上。 (很容易看出为什么不这样做。动态转换不是左值,因此 Bison 必须知道何时应用它,何时不应用它。)
所以你可以使用上面的%define api.value.type
然后写出语法动作:
Define: Type ID { if (doesIDexist(dynamic_cast<IDClass>()->name)) {
errorDef(@2.first_line,
dynamic_cast<IDClass>()->name);
exit(1);
}
}
如果您生成 C++ 解析器而不是恰好在 C++ 中工作的 C 解析器,那么您还有一些其他选项,这可能是也可能不是对您的应用程序更好的修复。 Language Semantics chapter of the Bison manual, and the C++ options have their own chapter 中解释了 C 解析器的选项,但如果您要使用 C++ 接口,则需要阅读整个 C++ 部分。
注意:我将yylineno
改为@2.first_line
,因为yylineno
通常是不准确的; yylineno
通常是与先行标记关联的行号,它通常与错误不在同一行。但是您不能只是进行更改;您还必须确保您的词法分析器正确填写 yylloc
。请参阅 Bison 手册中的 Tracking Locations 章节。
我搜索了很多但似乎找不到关于如何使用 %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(***->name***)){errorDef(yylineno, ID_ptr->name);exit(1);}}
但显然,$2->name 不会 return 它。 %union 在结构中的正确用法是什么?如何正确获取 name 的值?
提前致谢。
没有"correct use of %union
in structs",因为%union
用于声明union
。 (当然,您可以声明一个只有一个成员的 union
,但这几乎毫无意义。)
声明不是 union
的语义类型的正确方法是:
%define api.value.type { Node* }
但这不会得到你想要的,因为你想要的既不是 union
也不是固定类型,而是隐式动态转换或类似的东西。这不在 Bison 的选项菜单上。 (很容易看出为什么不这样做。动态转换不是左值,因此 Bison 必须知道何时应用它,何时不应用它。)
所以你可以使用上面的%define api.value.type
然后写出语法动作:
Define: Type ID { if (doesIDexist(dynamic_cast<IDClass>()->name)) {
errorDef(@2.first_line,
dynamic_cast<IDClass>()->name);
exit(1);
}
}
如果您生成 C++ 解析器而不是恰好在 C++ 中工作的 C 解析器,那么您还有一些其他选项,这可能是也可能不是对您的应用程序更好的修复。 Language Semantics chapter of the Bison manual, and the C++ options have their own chapter 中解释了 C 解析器的选项,但如果您要使用 C++ 接口,则需要阅读整个 C++ 部分。
注意:我将yylineno
改为@2.first_line
,因为yylineno
通常是不准确的; yylineno
通常是与先行标记关联的行号,它通常与错误不在同一行。但是您不能只是进行更改;您还必须确保您的词法分析器正确填写 yylloc
。请参阅 Bison 手册中的 Tracking Locations 章节。