boost::spirit::lex получить типизированнаое значение токена
От: sanok  
Дата: 03.07.10 07:39
Оценка:
Почему-то не удаётся получить из токенов соответствующее им типизированное значение.

Пример, иллюстрируюший проблему: лексический анализатор понимает 3 типа токенов: Символы 'K', ';' и цеалые числа без знака. Из последнего типа токенов хотелось бы извлекать значения типа unsigned int. Для этого я использую get<unsigned int>, но вызов get заканчивается неудачей, даже если содержимое токена — число.

Использую VC2010 Express.

#include <boost/spirit/include/lex_lexertl.hpp>
#include <string>

using namespace boost::spirit;

template <typename Lexer>
struct optionalK_tokens : lex::lexer<Lexer>
{
    optionalK_tokens()
    {
        k = 'K';
        ival = "[0-9]+";
        delim = ';';
        this->self = k | ival | delim;
    }

    lex::token_def<> k, delim;
    lex::token_def<unsigned int> ival;
};

struct token_handler
{
    template<typename Token>
    bool operator() (const Token& t) 
    {
        std::cout << "Value: " << t.value() << ' ' << ' ';
        typename Token::token_value_type const& value (t.value());
/*        
        const unsigned int* pi = boost::get<unsigned int>( &t.value() );
        if ( pi )        //тоже не работает, на выходе NULL даже если парсим число
            std::cout << "[unsigned int]"; 
*/
        try {
            unsigned int pi = boost::get<unsigned int>( value );   //Всегда кидает bad_get, даже если в токене '11' или '12'
            std::cout << "[unsigned int]";
        }
        catch (boost::bad_get &) {
            std::cout << "except:";    
        }
        std::cout << std::endl;
        return true;
    }
};

int main(int argc, char* argv[])
{
    typedef std::string::iterator base_iterator_type;

    typedef lex::lexertl::token<
        base_iterator_type, boost::mpl::vector<unsigned int> 
    > token_type;

    std::string str = "K12;K;K11"; //string to tokenize

    // create the token definition instance needed to invoke the lexical analyzer
    optionalK_tokens<lex::lexertl::lexer<token_type> > lexer_obj;
    bool r = boost::spirit::lex::tokenize(str.begin(), str.end(), lexer_obj, token_handler() );

    return 0;
}


Нужна помощь в понимании, что же я делаю не так?

12.07.10 12:59: Перенесено модератором из 'C/C++' — Кодт
Re: boost::spirit::lex получить типизированнаое значение ток
От: sanok  
Дата: 03.07.10 19:51
Оценка:
Добавлю в догонку, что boost версии 1.43
Re[2]: boost::spirit::lex получить типизированнаое значение
От: sanok  
Дата: 04.07.10 05:50
Оценка:
Здравствуйте, sanok, Вы писали:

S>Добавлю в догонку, что boost версии 1.43


Сам с собою я веду беседу

Кажется, понял. Вроде, как нужно ещё специальный код написать, который, получив на вход пару итераторов строки, преобразует текстовое значение между ними в значение соответствующего типа. Почему-то я подумал, что для типов double, int, и.т.п. лексер и всякая шаблонная магия сделает такое преобразование автоматически.
Re[3]: boost::spirit::lex получить типизированнаое значение
От: hkaiser  
Дата: 04.07.10 17:37
Оценка: 18 (3)
Здравствуйте, sanok, Вы писали:

S>Здравствуйте, sanok, Вы писали:


S>>Добавлю в догонку, что boost версии 1.43


S>Сам с собою я веду беседу


S>Кажется, понял. Вроде, как нужно ещё специальный код написать, который, получив на вход пару итераторов строки, преобразует текстовое значение между ними в значение соответствующего типа. Почему-то я подумал, что для типов double, int, и.т.п. лексер и всякая шаблонная магия сделает такое преобразование автоматически.


It actually does, but only if used in conjunction with a Qi parser. There the token exposes the matched input as an (parser-) attribute of the type specified while defining the corresponding token_def.

Regards Hartmut
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.