首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >升压精神QI递归

升压精神QI递归
EN

Stack Overflow用户
提问于 2010-10-14 19:01:43
回答 2查看 1.4K关注 0票数 1

我肯定错过了一些关于boost::recursive_wrapper的东西,我总是会有一个错误:

error:不匹配调用‘::tuple::tuple,std::allocator >,client::compare_attr_op_t,std::basic_string,std::allocator >,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>::tuple(client::expression_value&)‘

用于定义语法中的“表达式”的行:expression %= attribute_test | boolean_expression;

有什么想法吗?

代码语言:javascript
复制
namespace client {

    enum compare_attr_op_t {
        cao_eq,
        cao_neq
    };

    enum boolean_op_t {
        bo_and,
        bo_or,
        bo_not
    };

    struct expression_value;

    typedef boost::tuple<std::string, compare_attr_op_t, std::string> attribute_test_value;
    typedef boost::tuple< expression_value, boolean_op_t, expression_value > boolean_expression_value;
    typedef boost::variant< attribute_test_value, boost::recursive_wrapper<boolean_expression_value> > sub_expression_value;

    struct expression_value {
        sub_expression_value value;
    };
}

BOOST_FUSION_ADAPT_STRUCT(
    client::expression_value,
    (client::sub_expression_value, value)
)

namespace client {
    struct compare_attr_ : qi::symbols<char, compare_attr_op_t>
    {
        compare_attr_()
        {
            add
                ("="    , cao_eq)
                ("!="   , cao_neq)
            ;
        }

    } compare_attr;

    struct boolean_op_ : qi::symbols<char, boolean_op_t>
    {
        boolean_op_()
        {
            add
                ("&"    , bo_and)
                ("|"   , bo_or)
            ;
        }

    } boolean_op;


    template <typename Iterator>
    struct attribute_conditions : qi::grammar<Iterator, expression_value(), ascii::space_type>
    {
        attribute_conditions() : attribute_conditions::base_type(expression)
        {
            using qi::eps;
            using qi::lit;
            using qi::_val;
            using qi::lexeme;
            using qi::_1;
            using qi::_2;
            using qi::_3;
            using ascii::char_;
            using ascii::alnum;
            using ascii::alpha;

            expression %= attribute_test | boolean_expression;
            boolean_expression %= expression >> boolean_op >> expression;
            attribute_test %= (attribute_name >> compare_attr >> attribute_value)[std::cout << _1 << ' ' << _2 << ' ' << _3];
            attribute_name %= alpha >> *alnum;
            attribute_value %= lexeme['"' > +(char_ - '"') > '"'];

        }

        qi::rule<Iterator, expression_value(), ascii::space_type> expression;
        qi::rule<Iterator, boolean_expression_value(), ascii::space_type> boolean_expression;
        qi::rule<Iterator, attribute_test_value(), ascii::space_type> attribute_test;
        qi::rule<Iterator, std::string(), ascii::space_type> attribute_name;
        qi::rule<Iterator, std::string(), ascii::space_type> attribute_value;
    };
}
EN

回答 2

Stack Overflow用户

发布于 2010-10-18 09:41:02

我把这一切都抛在脑后,从头开始,给了我这个很好的工作实现:

代码语言:javascript
复制
namespace client {

    enum compare_attr_op_t {
        cao_eq,
        cao_neq
    };

    enum boolean_op_t {
        bo_and,
        bo_or,
        bo_not
    };

    struct expression_value;
    struct or_op_value;
    struct and_expression_value;
    struct and_op_value;
    struct not_op_value;

    typedef boost::tuple<std::string, compare_attr_op_t, std::string> attribute_test_value;
    typedef boost::variant<attribute_test_value, boost::recursive_wrapper<expression_value>, boost::recursive_wrapper<not_op_value> > node_value;

    struct not_op_value {
        boolean_op_t operation;
        node_value rnode;
    };

    struct and_op_value {
        boolean_op_t operation;
        node_value rnode;
    };

    struct and_expression_value {
        node_value lnode;
        std::vector<and_op_value> ops;
    };

    struct or_op_value {
        boolean_op_t operation;
        and_expression_value rnode;
    };

    struct expression_value {
        and_expression_value lnode;
        std::vector<or_op_value> ops;
    };


}

BOOST_FUSION_ADAPT_STRUCT(
        client::not_op_value,
        (client::boolean_op_t, operation)
        (client::node_value, rnode)
)

BOOST_FUSION_ADAPT_STRUCT(
    client::and_expression_value,
    (client::node_value, lnode)
    (std::vector<client::and_op_value>, ops)
)

BOOST_FUSION_ADAPT_STRUCT(
    client::and_op_value,
    (client::boolean_op_t, operation)
    (client::node_value, rnode)
)

BOOST_FUSION_ADAPT_STRUCT(
    client::expression_value,
    (client::and_expression_value, lnode)
    (std::vector<client::or_op_value>, ops)
)

BOOST_FUSION_ADAPT_STRUCT(
    client::or_op_value,
    (client::boolean_op_t, operation)
    (client::and_expression_value, rnode)
)


namespace client {
    struct compare_attr_ : qi::symbols<char, compare_attr_op_t>
    {
        compare_attr_()
        {
            add
                ("="    , cao_eq)
                ("!="   , cao_neq)
            ;
        }

    } compare_attr;

    struct boolean_op_and_t : qi::symbols<char, boolean_op_t>
    {
        boolean_op_and_t()
        {
            add
                ("&"   , bo_and)
                ("and"   , bo_and)
            ;
        }

    } boolean_op_and;

    struct boolean_op_or_t : qi::symbols<char, boolean_op_t>
    {
        boolean_op_or_t()
        {
            add
                ("|"   , bo_or)
                ("or"   , bo_or)
            ;
        }

    } boolean_op_or;

    struct boolean_op_not_t : qi::symbols<char, boolean_op_t>
    {
        boolean_op_not_t()
        {
            add
                ("!"   , bo_not)
                ("not"   , bo_not)
            ;
        }

    } boolean_op_not;

    template <typename Iterator>
    struct attribute_conditions : qi::grammar<Iterator, expression_value(), ascii::space_type>
    {
        attribute_conditions() : attribute_conditions::base_type(expression)
        {
            using qi::eps;
            using qi::lit;
            using qi::_val;
            using qi::lexeme;
            using qi::_1;
            using qi::_2;
            using qi::_3;
            using ascii::char_;
            using ascii::alnum;
            using ascii::alpha;
            using ascii::no_case;

            expression %= and_expression >> *(no_case[boolean_op_or] >> and_expression);
            and_expression %= node >> *(no_case[boolean_op_and] >> node);
            node %= attribute_test | ('(' >> expression >> ')') | not_operation;
            not_operation %= no_case[boolean_op_not] >> node;
            attribute_test %= (attribute_name >> no_case[compare_attr] >> attribute_value);
            attribute_name %= alpha >> *char_("A-Za-z0-9_");
            attribute_value %= lexeme['"' > +(char_ - '"') > '"'];

        }

        qi::rule<Iterator, expression_value(), ascii::space_type> expression;
        qi::rule<Iterator, and_expression_value(), ascii::space_type> and_expression;
        qi::rule<Iterator, not_op_value(), ascii::space_type> not_operation;
        qi::rule<Iterator, node_value(), ascii::space_type> node;
        qi::rule<Iterator, attribute_test_value(), ascii::space_type> attribute_test;
        qi::rule<Iterator, std::string(), ascii::space_type> attribute_name;
        qi::rule<Iterator, std::string(), ascii::space_type> attribute_value;
    };
}
票数 1
EN

Stack Overflow用户

发布于 2010-10-14 19:16:24

这将使用Visual C++ 2010/Boost 1.36.0中的以下内容为我编译OK。您的编译器可能无法在这里处理模板。

代码语言:javascript
复制
#include <boost/tuple/tuple.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted.hpp>
using namespace boost::spirit;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3936605

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档