views:

39

answers:

1

Hi! How i can set encoding for values in assign_a? I need to set cyrrilic, but i havent any idea how to do it

    #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;

}
A: 

First, you're mixing Spirit.Classic (the older version pof Spirit) with Spirit.Qi (the current version). Please don't do that as it will not work, in the best case it will not interfere, but most likely it will break things.

Second, Spirit.Classic does not support encodings very well. I suggest you switch entirely to the newer version (Spirit.Qi). This gives you the additional benefit of working with an actively supported code base, and with something which is a lot faster than the older version. IMHO, it is easier to use as well, but YMMV.

Third, if you decide to switch to Spirit.Qi, you may want to utilize the pre-existing encodings. This can be done by explicitly using, for instance, iso8859_1::char_ or standard_wide::char_ instead of the default qi::char_ (which is equivalent to ascii::char_). qi::string has similar encoding specific counterparts. Spirit.Qi has some preliminary unicode support as well, but this isn't documented too well. Look at the scheme parser example, if you're interested in that. Another option would be to write your own encoding for Spirit, but this needs more explanation, so you're probably better off discussing this on the Spirit mailing list.

hkaiser