【问题标题】:Boost Spirit rule with custom attribute parsing使用自定义属性解析提升 Spirit 规则
【发布时间】:2010-06-27 16:06:39
【问题描述】:

我正在编写一个 Boost Spirit 语法来将文本解析为这些结构的向量:

struct Pair
{
    double a;
    double b;
};

BOOST_FUSION_ADAPT_STRUCT(
    Pair,
    (double, a)
    (double, a)
)

这个语法有这样的规则:

qi::rule<Iterator, Pair()> pairSequence;

然而pairSequence的实际语法是这样的:

double_ % separator

我希望这个语法产生一个Pair,其中a 等于双精度,b 等于某个常数。我想做这样的事情:

pairSequence = double_[_val = Pair(_1, DEFAULT_B)] % separator;

当然,以上内容无法编译。我尝试将构造函数添加到 Pair,但仍然出现编译错误(没有匹配函数调用 'Pair::Pair(const boost::phoenix::actor >&, double)' )。

【问题讨论】:

    标签: boost attributes boost-spirit boost-spirit-qi boost-phoenix


    【解决方案1】:

    首先pairSequence的签名需要是:

    qi::rule<Iterator, std::vector<Pair>()> pairSequence; 
    

    因为列表运算符公开了 std::vector&lt;Pair&gt; 作为其属性。

    从语义动作内部调用的所有函数都必须是“惰性”的,因此您需要使用 phoenix:

    namespace phx = boost::phoenix;
    
    pairSequence = 
        double_[
            phx::push_back(_val, 
                phx::construct<Pair>(_1, phx::val(DEFAULT_B))
            )
        ] % separator
    ; 
    

    另一种可能性是向Pair 添加一个(非显式)构造函数:

    struct Pair         
    {         
        Pair(double a) : a(a), b(DEFAULT_B) {}
    
        double a;         
        double b;         
    };         
    

    这可以简化语法:

    pairSequence = double_ % separator; 
    

    并且完全依赖 Spirit 内置的属性传播规则。

    顺便说一句,要使其中任何一个起作用,您无需将 Pair 改编为 Fusion 序列。

    【讨论】:

    • 啊,是的,我错过了 vector 构造。
    猜你喜欢
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多