2010-10-14 96 views
1

我一定是錯過了一些與升壓:: recursive_wrapper的事情,我總是得到一個錯誤:升壓精神QI遞歸

error: no matching function for call to 'boost::tuples::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, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>::tuple(client::expression_value&)'

在語法定義的「表達」的路線:expression %= attribute_test | boolean_expression;

任何想法?

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

回答

0

這個編譯好使用以下包含在Visual Studio C++ 2010/Boost 1.36.0中。可能你的編譯器不能在這裏處理模板。

#include <boost/tuple/tuple.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/fusion/adapted.hpp> 
using namespace boost::spirit; 
+0

我使用Boost 1.42和gcc-4.2.1,我會嘗試其他組合 – Scapal 2010-10-15 06:31:37

+0

相同gcc(Debian 4.3.2-1.1)和Boost 1.43 – Scapal 2010-10-15 06:40:10

+0

@Scapal - 今天晚些時候我會用Boost 1.44試試這個,如果我有機會的話,只是爲了排除Spirit以來的變化,因爲我的Boost版本有點老了。 – 2010-10-15 10:18:28

1

我扔了這一切,從頭開始,給我這個好和工作實現:

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