2013-09-09 4 views
2

Итак, у меня это, довольно уродливое правило в моем парсе boost::spirit;Получение количества времени, когда правило сопоставляется как unsigned int

qi::rule<Iterator, bool()> empty_brackets; 
... 
empty_brackets = (qi::token(LEFT_BRACKET) >> qi::token(RIGHT_BRACKET)) 
        [ qi::_val = true ] 
       ; 

Правило используется как;

array_typeexp = (primitive_typeexp >> +(empty_brackets)) 

Так что я действительно хочу, для второго аргумента (qi::_2), не std::vector<bool>, а скорее unsigned int, описывающее количество раз 'empty_brackets' были подобраны.

Как бы я мог добиться этого?

ответ

2

Я действительно не уверен, что вам может понадобиться это для, но, эй:/

Я предлагаю

empty_brackets = lit('(') >> lit(')'); 
n_empty_brackets = eps [ _val = 0 ] >> +empty_brackets [ ++_val ]; 

array_typeexp  = primitive_typeexp >> n_empty_brackets; 

Для простоты я не сделал primitive_typeexp «нет-оп», и поэтому крайние правила возврата только значения unsigned в этой простой установке:

qi::rule<It, unsigned(), Skipper> array_typeexp, n_empty_brackets; 
qi::rule<It, Skipper> empty_brackets, primitive_typeexp; 

Смотреть полный образец Live on Coliru

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 

namespace qi = boost::spirit::qi; 

template <typename It, typename Skipper = qi::space_type> 
    struct parser : qi::grammar<It, unsigned(), Skipper> 
{ 
    parser() : parser::base_type(array_typeexp) 
    { 
     using namespace qi; 

     empty_brackets = lit('(') >> lit(')'); 
     n_empty_brackets = eps [ _val = 0 ] >> +empty_brackets [ ++_val ]; 

     array_typeexp  = primitive_typeexp >> n_empty_brackets; 

     // TODO 
     primitive_typeexp = eps; 

     BOOST_SPIRIT_DEBUG_NODES((array_typeexp)(n_empty_brackets)(empty_brackets)(primitive_typeexp)); 
    } 

    private: 
    qi::rule<It, unsigned(), Skipper> array_typeexp, n_empty_brackets; 
    qi::rule<It, Skipper> empty_brackets, primitive_typeexp; 
}; 

bool doParse(const std::string& input) 
{ 
    typedef std::string::const_iterator It; 
    auto f(begin(input)), l(end(input)); 

    parser<It, qi::space_type> p; 
    unsigned data; 

    try 
    { 
     bool ok = qi::phrase_parse(f,l,p,qi::space,data); 
     if (ok) 
     { 
      std::cout << "parse success\n"; 
      std::cout << "data: " << data << "\n"; 
     } 
     else  std::cerr << "parse failed: '" << std::string(f,l) << "'\n"; 

     if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n"; 
     return ok; 
    } catch(const qi::expectation_failure<It>& e) 
    { 
     std::string frag(e.first, e.last); 
     std::cerr << e.what() << "'" << frag << "'\n"; 
    } 

    return false; 
} 

int main() 
{ 
    doParse("()() ( )()"); 
    doParse("()"); 
} 
+0

Я нуждаясь его, чтобы соответствовать; 'int [] [] []', то есть многомерные массивы. – Skeen

+0

А, я тоже догадывался о неправильном типе парнеров :) – sehe

+0

Но я попробую это, это выглядит довольно многообещающе. – Skeen