'(' >> double_ >> -(',' >> double_) >> ')' | double_
double_[ref(n) = _1] >> *(',' >> double_[ref(n) += _1])
累加。
template
bool parse_numbers(Iterator first, Iterator last, std::vector& 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
bool parse_numbers(Iterator first, Iterator last, std::vector& 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 r;
rule r;
rule r;
rule r;
没有带Skipper的规则只能用于parse,不能用于phrase_parse。Iterator后面的类型顺序没有要求。Signature指定规划的属性(或者叫类型更合适),比如:double。还有种属性称作继承:
result(argN, argN,..., argN)
暂时先不管。
template
struct roman : qi::grammar
{
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 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