如何从 Spirit::Qi 规则访问 boost::variant 成员?
我无法找到如何在我的 Spirit-Qi 语法中使用 boost::phoenix 访问 boost::variant 的成员的正确方法。这是我想要实现的简单示例。 (我的整个语法要复杂得多,这是我正在测试提到的问题的简单片段)。
namespace ph = boost::phoenix;
typedef boost::variant<std::string,int> VariantType;
typedef std::list<VariantType> TlstVariants;
rule<Iterator, void(TlstVariants&), Skipper> rule1;
rule1 =
qi::eps [ ph::push_back(qi::_r1, ph::construct<int>(2)) ]
>> qi::eps [ ph::get<int>(ph::back(qi::_r1)) = ph::val(3) ] //THIS IS EXAMPLE OF WHAT I NEED
;
TlstVariants lstVals;
ExecuteParser("5",rule1( ph::ref(lstVals) ));
BOOST_FOREACH( VariantType &val, lstVals )
{
std::cout << val.which() << " - " << val;
}
但我找不到任何 Phoenix::get<>或使用 Phoenix 访问 boost::variant 的任何类似方法。我需要 Phoenix::get<> 的原因是因为我需要插入变体以列出特定类型,然后将此特定类型作为对子规则的引用作为继承属性传递:
qi::rule<Iterator, void(structTest&), Skipper> rule_child;
rule =
qi::lit("test") [ph::push_back(sp::_r1, ph::construct<structTest>())]
> qi::lit('(')
> rule_child( ph::get<structTest>(ph::back(sp::_r1)) )
> qi::lit(')')
...
有什么方法可以实现这样的行为吗?
感谢您的回复
瑞克
I can't find a proper way how to access members of boost::variant using boost::phoenix in my Spirit-Qi grammar. Here is simple an example what I’m trying to achieve. (my whole grammar is much more complex, this is simple fragment where I'm testing mentioned problem).
namespace ph = boost::phoenix;
typedef boost::variant<std::string,int> VariantType;
typedef std::list<VariantType> TlstVariants;
rule<Iterator, void(TlstVariants&), Skipper> rule1;
rule1 =
qi::eps [ ph::push_back(qi::_r1, ph::construct<int>(2)) ]
>> qi::eps [ ph::get<int>(ph::back(qi::_r1)) = ph::val(3) ] //THIS IS EXAMPLE OF WHAT I NEED
;
TlstVariants lstVals;
ExecuteParser("5",rule1( ph::ref(lstVals) ));
BOOST_FOREACH( VariantType &val, lstVals )
{
std::cout << val.which() << " - " << val;
}
But I can't find any phoenix::get<> or any similar method to access boost::variant using Phoenix. Reason why I need phoenix::get<> is because I need to insert variant to list with specific type and then pass this specific type as reference to the child rule as inherited attribute:
qi::rule<Iterator, void(structTest&), Skipper> rule_child;
rule =
qi::lit("test") [ph::push_back(sp::_r1, ph::construct<structTest>())]
> qi::lit('(')
> rule_child( ph::get<structTest>(ph::back(sp::_r1)) )
> qi::lit(')')
...
Is there any way how to achieve behavior like this?
Thank for any reply
Rick
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编写自己的“惰性”Phoenix 函数相当容易。这是
boost::variant
的一个。现在,这可以用在语义操作中:
It's fairly easy to write your own 'lazy' Phoenix function. Here is one for
boost::variant
.Now, this can be used in a semantic action:
我想我找到了一种方法。 (不知道这是否是最好的方法,但它有效;-))。
问题出在 int& 上。类型,因为 boost::variant 保存的是 int 而不是 int&。因此,我更新您的模板以接受两种类型,一种用于变体 getter,一种用于返回类型。
我以这种方式更新了 get_impl 模板:
我的语法现在看起来像这样:
一切似乎都正常。再次感谢hkaiser的最初回复,这对我帮助很大。
I think I found a way how to do it. (Don't know if this is best way, but it works ;-) ).
The problem was in int& type, because boost::variant holds int and not int&. So I update your template to accept two types, one for variant getter and one for return type.
I updated get_impl template in this way:
And my grammar now looks like this:
And everything seems to works Ok. Thank you again hkaiser for your initial reply which helps me a lot.