3

簡単なパーサー テストLive On Coliruでは、

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;
}

パーサー

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

type の属性を合成することになっていますboost::iterator_range<Iterator>。しかし、それはコンパイルできません。2 つの のいずれかを削除すると、x3::lit('x')コンパイルされます。Live on Coliru でも、同じコードが qi でコンパイルされます。

4

1 に答える 1

2

面白い。実際にはコンパイルされます:

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;
    }
}

それを壊すのは、周囲のコンテキストです:

// 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);

私の推測では、そのような場合、メタプログラミングはどういうわけかiterator_range、Fusion シーケンスとして誤って扱います。もちろんバグだと思います。

これを上流に報告する必要があります。

悲しいことに、私は「ホメオパシー」の回避策を見つけていません.

于 2017-03-23T00:21:43.733 に答える