假设我有这样的符号表:
struct jass_types : qi::symbols<char, jass_type> {
现在我想用其父类型填充一个自定义声明的类型:
identifier %=
char_("a-zA-Z") >> -(*char_("a-zA-Z_0-9") >> char_("a-zA-Z0-9"))
;
type %=
lit("type") >> identifier >>
lit("extends") >> identifier[type_symbols.find(_1)]
结构如下:
BOOST_FUSION_ADAPT_STRUCT(
wc3lib::jass::jass_type,
(std::string, identifier)
(wc3lib::jass::jass_type*, parent)
)
我如何编写将其存储0的代码写入属性&#34; parent&#34;如果&#34;之后的标识符延伸&#34;在符号表中找不到,我如何正确地对缺失的符号作出反应?
我的想法是做出类似的事情:
boost::variant<wc3lib::jass::jass_type*,std::string> parent
并根据事实填写指针或标识符,如果在符号表中找到类型,但我必须在之后检测父类型信息。 另一个选择是将父级存储为0作为连字符,并创建一个带有标识符信息等的错误对象。如果找不到符号,Boost可能已经完全相同了???
修改
首先犯了使用_2而不是_1的错误,但它仍然无法工作,因为它显然需要一个char *值而不是std :: string,所以我添加了一个自定义函数:
inline jass_type* get_type_symbol(jass_types &types, const std::string &value) {
return types.find(value.c_str());
}
和语义行为:
type =
lit("type") >> identifier >>
lit("extends") >> identifier[phoenix::bind(&get_type_symbol, ref(type_symbols), _1)]
;
但它似乎仍然过于复杂,如果找不到符号,我无法解决标识符的正确错误检测/存储问题!
答案 0 :(得分:0)
你可以这样做:
// simplified identifier rule exposes a `std::strirng`:
qi::rule<It, std::string()> identifier = char_("a-zA-Z") >> *char_("a-zA-Z_0-9");
struct jass_types : qi::symbols<char, jass_type*> {
// ...
};
typedef boost::variant<jass_type*, std::string> jass_typeref;
jass_types type_symbols;
请注意,我使symbols<>
解析器直接返回指向jass_type的指针。现在规则可以简单如下:
qi::rule<It, jass_typeref()> typeref_ = type_symbols | identifier;
使用它,例如如
type %= "type" >> identifier >> "extends" >> typeref_;
要提供默认值,您可以执行
type %= "type" >> identifier >>
("extends" >> typeref_ | qi::attr(std::string("::object")));
(假设所有类型都延伸::object
)