I must have missed something with the boost::recursive_wrapper thing, I always get an error:
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&)'
for the line defining the "expression" in the grammar: expression %= attribute_test | boolean_expression;
Any idea?
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;
    };
}