Parsing with Boost :: Spirit (V2.4) into a container

I just started digging into Boost :: Spirit, the latest version so far is V2.4. The essence of my problem is as follows:

I would like to parse strings like "1a2" or "3b4". Therefore, I use the rule:

  (double_ >> lit('b') >> double_)
| (double_ >> lit('a') >> double_);

The rule attribute must be "vector <double>". And I read it in a container.

Full code:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>

int main(int argc, char * argv[])
{
    using namespace std;
    using namespace boost::spirit;
    using namespace boost::spirit::qi;
    using boost::phoenix::arg_names::arg1;

    char const * first = "1a2";
    char const * last  = first + std::strlen(first);
    vector<double> h;

    rule<char const *, vector<double>()> or_test;
    or_test %=    (double_ >> lit('b') >> double_) 
            | (double_ >> lit('a') >> double_);

    if (parse(first, last, or_test,h)) {
           cout << "parse success: "; 
           for_each(h.begin(), h.end(), (cout << arg1 << " "));
           cout << "end\n";
    } else cout << "parse error\n" << endl;
    return 0;
 }

I am compiling it with g ++ 4.4.3. And it returns "1 1 2". Although I expect "1 2".

As far as I understand, this is because the parser:

  • goes to the first alternative
  • reads double_ and saves it in the container
  • then stops at "a", waiting for burning ("b")
  • goes to the second alternative
  • reads two more duplicates

: , - ?

+2
1

. "" . hold[], ( ):

or_test =    
        hold[double_ >> lit('b') >> double_)]
    |   (double_ >> lit('a') >> double_)
    ; 

, , .

+4

Source: https://habr.com/ru/post/1659571/


All Articles