#ifndef CUSTOMFOLDDIRECTIVE_HH_ #define CUSTOMFOLDDIRECTIVE_HH_ namespace AMDA { namespace parser { namespace tag { struct fold { BOOST_SPIRIT_IS_TAG() }; } template boost::spirit::stateful_tag_type fold(Expr const& expr) { return boost::spirit::stateful_tag_type(expr); } } /*namespace parser */ } /*namespace AMDA */ namespace boost { namespace spirit { template struct use_directive > : mpl::true_ {}; } /*namespace spirit */ } /*namespace boost */ namespace AMDA { namespace parser { template struct fold_directive { fold_directive(InitialParser const& initial, RepeatingParser const& repeating):initial(initial),repeating(repeating){} template struct attribute { typedef typename boost::spirit::traits::attribute_of::type type;//This works in this case but is not generic }; template bool parse(Iterator& first, Iterator const& last, Context& context, Skipper const& skipper, Attribute& attr_) const { Iterator start = first; typename boost::spirit::traits::attribute_of::type initial_attr; if (!initial.parse(first, last, context, skipper, initial_attr)) { first=start; return false; } typename boost::spirit::traits::attribute_of::type repeating_attr; if(!repeating.parse(first, last, context, skipper, repeating_attr)) { boost::spirit::traits::assign_to(initial_attr, attr_); return true; } Exposed current_attr(initial_attr,repeating_attr); while(repeating.parse(first, last, context, skipper, repeating_attr)) { boost::spirit::traits::assign_to(Exposed(current_attr,repeating_attr),current_attr); } boost::spirit::traits::assign_to(current_attr,attr_); return true; } template boost::spirit::info what(Context& context) const { return boost::spirit::info("fold"); } InitialParser initial; RepeatingParser repeating; }; } /*namespace parser */ } /*namespace AMDA */ namespace boost { namespace spirit { namespace qi { template struct make_directive, Subject, Modifiers> { typedef AMDA::parser::fold_directive result_type; template result_type operator()(Terminal const& term, Subject const& subject, Modifiers const&) const { typedef tag::stateful_tag tag_type; using spirit::detail::get_stateful_data; return result_type(get_stateful_data::call(term),subject); } }; } /* namespace qi */ } /* namespace parser */ } /* namespace AMDA */ #endif