2015-01-26 2 views
2

Если у меня есть mpl :: map, как я могу сгенерировать соответствующий boost :: spirit :: symbol parser?Возможно ли использовать mpl :: map для инициализации парсера символов?

Пример:

using blocks = mpl::map< 
        mpl::pair<mpl::string<'p'>, do_para>, 
        mpl::pair<mpl::string<'ul'>, do_ul>, 
        mpl::pair<mpl::string<'ol'>, do_ol> 
       >; 

qi::symbols<const char *, T> block_parser(?????); 

Спасибо за помощь с минимальным кодом вопрос!

+0

В основном вы спрашиваете: «Может ли mpl-карта использоваться, чтобы иметь эффект выполнения»? Ну, очевидно. Мой вопрос будет следующим: почему (поскольку он не кажется более выразительным, более удобным для обслуживания ...?) – sehe

+0

Я получаю карту mpl после нескольких других преобразований mpl. Может быть, все еще не так, но не думал, что это должен быть тупик. – KentH

ответ

2

Не зная, почему вы могли бы сделать такую ​​вещь, вот воображаемое применение его с помощью boost::fusion::for_each:

Live On Coliru

#include <boost/mpl/map.hpp> 
#include <boost/mpl/for_each.hpp> 
#include <boost/mpl/string.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/fusion/algorithm.hpp> 
#include <boost/fusion/mpl.hpp> 

namespace mpl = boost::mpl; 
namespace qi = boost::spirit::qi; 

struct do_ol : qi::grammar<const char*> { 
    do_ol() : do_ol::base_type(start) {} 
    qi::rule<const char*> start; 
}; 
struct do_ul : qi::grammar<const char*> { 
    do_ul() : do_ul::base_type(start) {} 
    qi::rule<const char*> start; 
}; 
struct do_para : qi::grammar<const char*> { 
    do_para() : do_para::base_type(start) {} 
    qi::rule<const char*> start; 
}; 

template <typename T> 
struct block_parser_t : qi::symbols<char, T> { 

    template <typename Map> 
    void add_map() { 
     boost::fusion::for_each(Map(), map_adder(*this)); 
    } 

    private: 
    struct map_adder { 
     map_adder(block_parser_t& r) : _r(r) {} 
     block_parser_t& _r; 

     template <typename...> struct result { typedef void type; }; 

     template <typename Pair> void operator()(Pair const&) const { 
      std::cout << "Adding: " << mpl::c_str<typename Pair::first>::value << "\n"; 
      _r.add(
       mpl::c_str<typename Pair::first>::value, 
       typename Pair::second() 
      ); 
     } 
    }; 
}; 

int main() { 
    using blocks = mpl::map< 
     mpl::pair<mpl::string<'p'>, do_para>, 
     mpl::pair<mpl::string<'ul'>, do_ul>, 
     mpl::pair<mpl::string<'ol'>, do_ol> 
    >; 

    typedef qi::rule<char const*> R; 

    block_parser_t<R> block_parser; 
    block_parser.add_map<blocks>(); 
} 

Печать

Adding: p 
Adding: ul 
Adding: ol 

Это будет по умолчанию постройте do_ul, do_ol и do_para grammars (при условии, что они являются грамматиками)

+0

Спасибо за рабочий пример! Я застрял с функтором «map_adder» - я пытался получить данные из аргумента, а не из типа. Наверное, я слишком скоро пересек границу времени ... Еще раз спасибо за вашу помощь! – KentH

Смежные вопросы