提升非融合结构的精神语义动作

时间:2015-08-29 09:05:30

标签: c++ boost boost-spirit

说我是否有一个简单的结构:

struct huh { char xxx; };  

在没有使用Boost Fusion改编的结构的情况下,我想在Spirit规则的语义动作中找到一个更简单的代理来操作成员变量。当然,这当然不起作用:

_val.xxx = _1

但是我希望得到一些清洁而不是与凤凰绑定:

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;
}

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

与融合绑定正是使它“与凤凰绑定”的“一点点更清洁”的粘合剂。

所以,有你的解决方案。或者,考虑您的表达模板,可能:

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_;
}