当前位置:  开发笔记 > 编程语言 > 正文

使用语义操作解析以逗号分隔的范围和数字列表

如何解决《使用语义操作解析以逗号分隔的范围和数字列表》经验,为你挑选了0个好方法。

使用Boost.Spirit X3,我想将逗号分隔的范围列表和单个数字(例如1-4,6,7,9-12)解析为单个std::vector.这是我想出的:

namespace ast {
    struct range 
    {
        int first_, last_;    
    };    

    using expr = std::vector;    
}

namespace parser {        
    template
    auto as_rule = [](auto p) { return x3::rule{} = x3::as_parser(p); };

    auto const push = [](auto& ctx) { 
        x3::_val(ctx).push_back(x3::_attr(ctx)); 
    };  

    auto const expand = [](auto& ctx) { 
        for (auto i = x3::_attr(ctx).first_; i <= x3::_attr(ctx).last_; ++i) 
            x3::_val(ctx).push_back(i);  
    }; 

    auto const number = x3::uint_;
    auto const range  = as_rule (number >> '-' >> number                   ); 
    auto const expr   = as_rule  ( -(range [expand] | number [push] ) % ',' );
} 

鉴于输入

    "1,2,3,4,6,7,9,10,11,12",   // individually enumerated
    "1-4,6-7,9-12",             // short-hand: using three ranges

这被成功解析为(Live On Coliru):

OK! Parsed: 1, 2, 3, 4, 6, 7, 9, 10, 11, 12, 
OK! Parsed: 1, 2, 3, 4, 6, 7, 9, 10, 11, 12, 

问题:我认为我理解将语义动作expand应用于该range部分是必要的,但为什么我还必须将语义动作push应用于该number部分?没有它(即使用简单的( -(range [expand] | number) % ',')规则expr,单个数字不会传播到AST(Live On Coliru):

OK! Parsed: 
OK! Parsed: 1, 2, 3, 4, 6, 7, 9, 10, 11, 12, 

奖金问题:我是否甚至需要语义行为才能做到这一点?Spirit X3文档似乎不鼓励他们.

推荐阅读
臭小子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有