3

我正在编写一个 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等于某个常数的值。我想做这样的事情:ab

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

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

4

1 回答 1

6

首先,pairSequence需要的签名是:

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

因为列表运算符公开 astd::vector<Pair>作为其属性。

从语义动作内部调用的所有函数都必须是“惰性”的,因此您需要使用 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 内置的属性传播规则。

顺便说一句,要使其中任何一个起作用,您都不需要适应PairFusion 序列。

于 2010-06-27T17:37:11.450 回答