【问题标题】:spirit x3 rule cannot synthesize attribute of type boost::iterator_range in a sequence parserSpirit x3 规则无法在序列解析器中合成 boost::iterator_range 类型的属性
【发布时间】:2017-03-22 14:57:47
【问题描述】:

在一个简单的解析器测试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')

应该合成boost::iterator_range&lt;Iterator&gt; 类型的属性。但它无法编译。如果我们删除两个x3::lit('x') 中的任何一个,它就会编译。尽管Live on Coliru,相同的代码也可以用qi 编译。

【问题讨论】:

    标签: c++ boost boost-spirit boost-spirit-qi boost-spirit-x3


    【解决方案1】:

    有趣。实际上它确实编译:

    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 视为融合序列。当然我认为这是一个错误。

    您应该向上游报告。

    遗憾的是,我还没有找到“顺势疗法”的解决方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 2022-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多