Spirit x3 rule cannot synthesize type attribute boost :: iterator_range in sequence parser

In a simple test of the Live On Coliru parser ,

std::string str("x123x");
boost::iterator_range<boost::range_iterator<decltype(str)>::type> attr;
if( x3::parse( boost::begin(str), boost::end(str), x3::lit('x') >> x3::raw[+x3::digit] >> x3::lit('x'), attr ) ) {
    std::cout<<"Match! attr = "<<attr<<std::endl;
} else {
    std::cout<<"Not match!"<<std::endl;
}

      

Analyzer

x3::lit('x') >> x3::raw[+x3::digit] >> x3::lit('x')

      

the type attribute is supposed to be synthesized boost::iterator_range<Iterator>

. But it cannot compile. If we remove one of the two x3::lit('x')

, it will compile. The same code compiles with qi, although Live on Coliru .

+3


source to share


1 answer


Interesting. It actually compiles:

Live On Coliru

#include <iostream>
#include <boost/spirit/home/x3.hpp>

namespace x3 = boost::spirit::x3;

int main() {
    std::string const str("x123x");
    boost::iterator_range<std::string::const_iterator> attr;
    if(x3::parse(boost::begin(str), boost::end(str), x3::raw[+x3::digit], attr)) {
        std::cout<<"Match! attr = "<<attr<<std::endl;
    } else {
        std::cout<<"Not match!"<<std::endl;
    }
}

      

The thing that makes it break is the surrounding context:



// simple (ok):
x3::parse(boost::begin(str), boost::end(str), x3::raw[+x3::digit], attr);
// ok:
parse(boost::begin(str), boost::end(str), x3::eps >> x3::raw[+x3::digit], attr);
parse(boost::begin(str), boost::end(str), x3::raw[+x3::digit] >> x3::eps, attr);
// breaks:
parse(boost::begin(str), boost::end(str), x3::eps >> x3::raw[+x3::digit] >> x3::eps, attr);

      

My guess is somehow metaprogramming in this case somehow as a Fusion sequence iterator_range

. Of course I think it's a mistake.

You must report this above.

Unfortunately, I have not found a "homeopathic" solution.

+2


source