【问题标题】:Boost Spirit semantic actions on non-Fusion adapted structs在非融合适应结构上提升 Spirit 语义动作
【发布时间】:2015-11-23 21:42:50
【问题描述】:

如果我有一个简单的结构,比如:

struct huh { char xxx; };  

在不使用 Boost Fusion 适应结构的情况下,我想找到一个更简单的代理来操作 Spirit 规则的语义操作中的成员变量。现在这当然行不通了:

_val.xxx = _1

但我想比与 phoenix 绑定更更干净

bind(&huh::xxx, _val) =  _1 

这是一个在 clang 和 g++ 上编译的简单图片的工作示例:

#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/phoenix/bind/bind_member_variable.hpp>

struct huh { char xxx; };

int main() {
    namespace qi = boost::spirit::qi;
    namespace ascii = boost::spirit::ascii;
    namespace phx   = boost::phoenix;

    qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;

    start =  qi::char_[
        phx::bind(&huh::xxx, qi::_val) =  qi::_1 
    ];

    return 0;
}

有什么想法吗?

【问题讨论】:

  • This 是我前段时间尝试过的愚蠢的东西。有了它,您可以使用qi::char_[my_val.xxx=qi::_1] 之类的东西。您需要使用自适应宏,所以如果这是您的问题,此解决方案将无济于事。

标签: c++ boost boost-spirit


【解决方案1】:

使用 fusion 绑定正是使其“比使用 phoenix 绑定更更干净”的粘合剂。

所以,这就是你的解决方案。或者,考虑您的表达式模板,也许:

auto _xxx = phx::bind(&huh::xxx, _val);

所以你可以写:

start =  char_[ _xxx = _1 ];

或者,使用函数或自定义点:

自定义点

添加特征

namespace boost { namespace spirit { namespace traits {

    template <> struct assign_to_attribute_from_value<huh, char, void> {
        static void call(char c, huh& attr) { attr.xxx = c; }
    };

} } }

你现在可以简单地写

qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;

start = qi::char_;

Live On Coliru

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>

struct huh { char xxx; };

namespace boost { namespace spirit { namespace traits {

    template <> struct assign_to_attribute_from_value<huh, char, void> {
        static void call(char c, huh& attr) { attr.xxx = c; }
    };

} } }

int main() {
    namespace qi    = boost::spirit::qi;
    namespace ascii = boost::spirit::ascii;

    qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;

    start = qi::char_;
}

【讨论】:

  • 添加自定义点示例Live On Coliru
  • 自定义点方法更好,可能更快,但它太丑了:p。遗憾的是没有宏或其他东西可以使其更易于编写。
  • 有,我声称它叫做BOOST_FUSION_ADAPT_STRUCT。在很多方面
  • 我可以引诱你看一些我认为很酷的东西(如果它是由更好的程序员完成的)?它在comment above 中。如果您决定看它,请跳过(真正混乱的部分)到最后看看它是如何使用的(很酷的部分)。
  • @cv_and_he 是的,这很酷,尽管我个人认为所需的努力不成比例(我会选择答案中显示的auto val_xxx = phx::bind(&amp;huh::xxx, _val);)。如果我们想拥有这个,我们应该基于未来的语言反射支持。 $0.02
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多