Boost Spirit: Какие имена типов следует использовать для встроенных терминалов? - PullRequest
4 голосов
/ 17 мая 2011

Я занимаюсь рефакторингом системы ввода (модель типа), которую я использую, которая использует дух для сериализации строк. Я использую конструкцию моделирования во время компиляции type-traits.

template<>
type_traits<int4_type>
{
    typedef boost::spirit::qi::int_parser<boost::int32_t> string_parser;
}  

template<>
type_traits<string_type>
{
    typedef boost::spirit::ascii::string string_parser;
}

В этом примере я показываю примитивные парсеры, но я ожидаю также ввести и правила.

Тип int4 работает, но это из-за (home / qi / numeric / int.hpp +27):

namespace tag
    {
        template <typename T, unsigned Radix, unsigned MinDigits
                , int MaxDigits> 
        struct int_parser {};
    }

    namespace qi
    {
        ///////////////////////////////////////////////////////////////////////
        // This one is the class that the user can instantiate directly in 
        // order to create a customized int parser
        template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
                , int MaxDigits = -1>
        struct int_parser
          : spirit::terminal<tag::int_parser<T, Radix, MinDigits, MaxDigits> > 
        {};
    }

строка typedef не работает, как и eps. Я не мог понять причину обращения к парсеру строк. Тем не менее, в случае с EPS это сводится к:

#define BOOST_SPIRIT_TERMINAL(name)                                             \
    namespace tag { struct name {};  }                                          \
    typedef boost::proto::terminal<tag::name>::type name##_type;                \
    name##_type const name = {{}};                                              \
    inline void silence_unused_warnings__##name() { (void) name; }              \
    /***/

Что означает, что я не могу его определить, это прототерминальная конструкция, или, говоря непрозрачно, глобальное определение const.

Мой вопрос: как мне определить правило, грамматику, примитивный парсер?

Примечание: я уже начал работать над тем, чтобы дать всем моим "типам" функтор, инкапсулирующий правило, и затем сделать это признаком типа.

1 Ответ

1 голос
/ 11 июля 2011

Я не уверен, что это будет работать во всех случаях, но то, что я сделал, чтобы набрать определение моего Шкипера, было использовать BOOST_TYPEOF:

typedef BOOST_TYPEOF(boost::spirit::ascii::space - (boost::spirit::qi::eol | boost::spirit::qi::eoi)) SkipperT;

так что ваш пример будет

typedef BOOST_TYPEOF(boost::spirit::ascii::string) string_parser;

Возможно, есть лучший / более элегантный способ, но в настоящее время он работает для того, что мне было нужно.

...