boost::spirit, извлечение отпарсенного стринга

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by rudvil, 5 Feb 2010.

  1. rudvil

    rudvil Elder - Старейшина

    Joined:
    25 Aug 2008
    Messages:
    200
    Likes Received:
    29
    Reputations:
    0
    boost::spirit, извлечение отпарсенного стринга из переменной

    Вот часть кода
    Code:
    void print_num (double num) {
        std::cout << "(" << num << ")";
    }
    
    template <typename Iterator>
    struct grammar : qi::grammar<Iterator, ascii::space_type> {
        grammar() : grammar::base_type(expression) {
            using qi::double_;
            using qi::alpha;
            using qi::alnum;
            identifier = -('_' >> +alnum) >> alpha >> *alnum;
            expression = term >> *(('+' >> term) | ('-' >> term));
            term = factor >> *(('*' >> factor) | ('/' >> factor) | ('%' >> factor));
            factor = identifier | double_[&print_num] | '(' >> expression >> ')' | ('-' >> factor) | ('+' >> factor);
        }
        qi::rule<Iterator, ascii::space_type>
            identifier,
            expression,
            term,
            factor,
            program;
    };
    с получением значения из "double_" проблем нет - там все понятно, т.к. в spirit все уже сделано за тебя...
    Собственно вопрос, как можно получить содержимое переменной "identifier"?
    Т.е. чтобы было примерно так
    Code:
    void print_str (std::string str) {
        std::cout << "(" << str << ")";
    }
    
    void print_num (double num) {
        std::cout << "(" << num << ")";
    }
    
    template <typename Iterator>
    struct grammar : qi::grammar<Iterator, ascii::space_type> {
        grammar() : grammar::base_type(expression) {
            using qi::double_;
            using qi::alpha;
            using qi::alnum;
            identifier = -('_' >> +alnum) >> alpha >> *alnum;
            expression = term >> *(('+' >> term) | ('-' >> term));
            term = factor >> *(('*' >> factor) | ('/' >> factor) | ('%' >> factor));
            factor = identifier[&print_str] | double_[&print_num] | '(' >> expression >> ')' | ('-' >> factor) | ('+' >> factor);
        }
        qi::rule<Iterator, ascii::space_type>
            identifier,
            expression,
            term,
            factor,
            program;
    };
    и соотвественно будет выведено содержимое identifier'a.
    В доках про мой случай много чего написано о Phoenix и Bind, но я в эти вещи ещё не "въехал" =/
     
    #1 rudvil, 5 Feb 2010
    Last edited: 5 Feb 2010
  2. rudvil

    rudvil Elder - Старейшина

    Joined:
    25 Aug 2008
    Messages:
    200
    Likes Received:
    29
    Reputations:
    0
    Смог разобраться, может кому-нибуть тоже понадобится.
    В моём случае необходимо создать доп. правило с типом std::string, тогда при вызове функции он в качестве параметра передаст отпарсенный std::string.
    Code:
    void print_str (std::string str) {
        std::cout << "(" << str << ")";
    }
    void print_num (double num) {
        std::cout << "(" << num << ")";
    }
    template <typename Iterator>
    struct grammar : qi::grammar<Iterator, ascii::space_type> {
        grammar() : grammar::base_type(expression) {
            using qi::double_;
            using qi::alpha;
            using qi::alnum;
            identifier = -('_' >> +alnum) >> alpha >> *alnum;
            expression = term >> *(('+' >> term) | ('-' >> term));
            term = factor >> *(('*' >> factor) | ('/' >> factor) | ('%' >> factor));
            factor = identifier[&print_str] | double_[&print_num] | '(' >> expression >> ')' | ('-' >> factor) | ('+' >> factor);
        }
        qi::rule<Iterator, ascii::space_type>
            expression,
            term,
            factor,
            program;
        qi::rule<Iterator, std::string> identifier;
    };
    Т.е.
    Code:
    qi::rule<Iterator, std::string> identifier;
    И теперь можно использовать его так
    Code:
    identifier[&print_str]