Boost.Spirit备忘

'(' >> double_ >> -(',' >> double_) >> ')' | double_
  1. 候补者:例如,a | b。先尝试匹配第一个,如果不成功,再尝试b。
  2. 可选:例如,-p。匹配解析器p零或一次
double_[ref(n) = _1] >> *(',' >> double_[ref(n) += _1])

累加。

template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last, std::vector<double>& v)
{
    using qi::double_;
    using qi::phrase_parse;
    using qi::_1;
    using ascii::space;
    using phoenix::push_back;

    bool r = phrase_parse(first, last,

        //  Begin grammar
        (
            double_[push_back(phoenix::ref(v), _1)]
                >> *(',' >> double_[push_back(phoenix::ref(v), _1)])
        )
        ,
        //  End grammar

        space);

    if (first != last) // fail if we did not get a full match
        return false;
    return r;
}

存入容器,double_ >> *(',' >> double_)可以简化为double_ % ',',加上容器操作:

double_[push_back(phoenix::ref(v), _1)] % ','

容器操作还可以再简化:

template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last, std::vector<double>& v)
{
    using qi::double_;
    using qi::phrase_parse;
    using qi::_1;
    using ascii::space;

    bool r = phrase_parse(first, last,

        //  Begin grammar
        (
            double_ % ','
        )
        ,
        //  End grammar

        space, v);

    if (first != last) // fail if we did not get a full match
        return false;
    return r;
}

 前面直接将表达式传递给phrase_parse,这对于小解析器没问题,如果解析器很复杂,需要拆分为一条条规则:

rule<Iterator> r;
rule<Iterator, Skipper> r;
rule<Iterator, Signature> r;
rule<Iterator, Signature, Skipper> r;

没有带Skipper的规则只能用于parse,不能用于phrase_parse。Iterator后面的类型顺序没有要求。Signature指定规划的属性(或者叫类型更合适),比如:double。还有种属性称作继承:

result(argN, argN,..., argN)

暂时先不管。

语法

template <typename Iterator>
struct roman : qi::grammar<Iterator, unsigned()>
{
    roman() : roman::base_type(start)
    {
        using qi::eps;
        using qi::lit;
        using qi::_val;
        using qi::_1;
        using ascii::char_;

        start = eps             [_val = 0] >>
            (
                +lit('M')       [_val += 1000]
                ||  hundreds    [_val += _1]
                ||  tens        [_val += _1]
                ||  ones        [_val += _1]
            )
        ;
    }

    qi::rule<Iterator, unsigned()> start;
};

eps是特殊的解析器,它一直成功,但不消耗字符,用于初始化_val。_val是另一个Boost.Phoenix占位符代表规则的综合属性。

表达式a || b:匹配a或b,并且连续。即,如果同时匹配a和b,需要依次匹配;与a >> -b相等,但更高效。

lexeme['"' >> +(char_ - '"') >> '"'];

lexeme用于抑制方括号内的Skipper,-在这里是除了的意思。

等有空了继续。

Employee - Parsing into structs - 1.82.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值