кодирование в boost.spirit - PullRequest
       4

кодирование в boost.spirit

0 голосов
/ 09 сентября 2010

Как я могу установить кодировку для значений в assign_a? Мне нужно установить кириллицу, но я понятия не имею, как это сделать

    #include "filter_data.h"
    #include <boost/bind.hpp>
    #include <boost/spirit.hpp>
    #include <boost/spirit/actor.hpp>
    #include <boost/spirit/attribute.hpp>
    #include <boost/config/warning_disable.hpp>
    #include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
    #include <boost/spirit/home/support/char_class.hpp>
    #include <string>

    using namespace boost::spirit;
    using char_encoding::standard_wide;
    class filter_grammar : public grammar<filter_grammar>
    {
    public:

        static filter_data _filter_data;

    protected:

        static std::pair<std::wstring,std::wstring> _replace_arg;
        static std::wstring _remove_arg;
        static std::wstring _duplicate_arg;
        static std::wstring _errorstr;

        static void add_replace_arg();
        static void add_remove_arg();
        static void add_duplicate_arg();
        static void err();

    public:
        template<typename ScannerT>
        class definition {
        public:
            definition( const filter_grammar & self );

            rule<ScannerT> const & start() const ;

        private:
            rule<ScannerT> filters, filter_replace, filter_remove, filter_duplicate,errstr,arg;

            typedef definition _self;
        };
    };


    template<typename ScannerT>
    filter_grammar::definition<ScannerT>::definition( const filter_grammar & self )
    {
            filters = *(filter_replace|filter_remove|filter_duplicate|errstr);
            filter_replace = str_p("replace_word")>>blank_p>>arg[assign_a(_replace_arg.first)]>>blank_p>>arg[assign_a(_replace_arg.second)][boost::bind(&filter_grammar::add_replace_arg)]>>!(ch_p('\r'))>>ch_p('\n');
            filter_remove  = str_p("remove_word")>>blank_p>>arg[assign_a(_remove_arg)][boost::bind(&filter_grammar::add_remove_arg)]>>!(ch_p('\r'))>>ch_p('\n');
            filter_duplicate =  str_p("duplicate_word")>>blank_p>>arg[assign_a(_duplicate_arg)][boost::bind(&filter_grammar::add_duplicate_arg)]>>!(ch_p('\r'))>>ch_p('\n');
            errstr = *(arg[assign_a(_errorstr)][boost::bind(&filter_grammar::err)]>>!ch_p('_')>>!arg[assign_a(_errorstr)][boost::bind(&filter_grammar::err)]>>!blank_p)>>!(ch_p('\r'))>>ch_p('\n');

            arg = lexeme_d[+anychar_p];
    }

    template<typename ScannerT>
    rule<ScannerT> const & filter_grammar::definition<ScannerT>::start() const
    {
            return filters;
    }
filter_data filter_grammar::_filter_data;

std::pair<std::wstring,std::wstring> filter_grammar::_replace_arg;
std::wstring filter_grammar::_remove_arg;
std::wstring filter_grammar::_duplicate_arg;
std::wstring filter_grammar::_errorstr;

void filter_grammar::add_replace_arg ()
{
    try
    {
        _filter_data._replace.insert(std::make_pair(_filter_data._total_count,_replace_arg));
        _filter_data._queue.insert(std::make_pair(_filter_data._total_count,std::make_pair(1,_filter_data._total_count)));
        _filter_data._total_count++;
    }
    catch(std::exception& e)
    {
        std::wcerr << "Exception:" << e.what () << std::endl;
    }
}

void filter_grammar::add_remove_arg ()
{
    try
    {
        _filter_data._remove.insert(std::make_pair(_filter_data._total_count,_remove_arg));
        _filter_data._queue.insert(std::make_pair(_filter_data._total_count,std::make_pair(2,_filter_data._total_count)));
        _filter_data._total_count++;
    }
    catch(std::exception& e)
    {
        std::wcerr << "Exception:" << e.what () << std::endl;
    }
}

void filter_grammar::add_duplicate_arg ()
{
    try
    {
        _filter_data._duplicate.insert(std::make_pair(_filter_data._total_count,_duplicate_arg));
        _filter_data._queue.insert(std::make_pair(_filter_data._total_count,std::make_pair(3,_filter_data._total_count)));
        _filter_data._total_count++;
    }
    catch(std::exception& e)
    {
        std::wcerr << "Exception:" << e.what () << std::endl;
    }
}

void filter_grammar::err ()
{
    std::wcerr<<"Error - unknown symbol: "<<_errorstr<<" in filter file"<<std::endl;

}

1 Ответ

1 голос
/ 09 сентября 2010

Во-первых, вы смешиваете Spirit.Classic (более старая версия Spirit) с Spirit.Qi (текущая версия).Пожалуйста, не делайте этого, так как это не будет работать, в лучшем случае это не будет мешать, но, скорее всего, это сломает вещи.

Во-вторых, Spirit.Classic не очень хорошо поддерживает кодировки.Я предлагаю вам полностью перейти на более новую версию (Spirit.Qi).Это дает вам дополнительное преимущество работы с активно поддерживаемой кодовой базой и с чем-то, что намного быстрее, чем в старой версии.ИМХО, его проще использовать, но YMMV.

В-третьих, если вы решите переключиться на Spirit.Qi, вы можете использовать уже существующие кодировки.Это можно сделать, явно используя, например, iso8859_1 :: char_ или standard_wide :: char_ вместо стандартного qi :: char_ (что эквивалентно ascii :: char_).qi :: string имеет аналогичные кодировки конкретных аналогов.Spirit.Qi также имеет некоторую предварительную поддержку юникода, но это не слишком хорошо задокументировано.Посмотрите на пример синтаксического анализатора схемы, если вы заинтересованы в этом.Другой вариант - написать свою собственную кодировку для Spirit, но это требует большего объяснения, поэтому вам, вероятно, лучше обсудить это в списке рассылки Spirit.

...