语义动作就是为此而设计的。
灵气
最自然的例子是
qi::int_ [ qi::_pass = is_prime(qi::_1) ]
确保%=
在存在语义动作的情况下使用规则分配,因为没有它,语义动作会禁用自动属性传播。
显然,您也可以更冗长,并写
qi::int_ >> qi::eps(is_prime(qi::_val))
正如你所看到的,引用的文档有点不完整:eps
已经可以接受一个参数,在这种情况下是惰性actor is_prime(qi::_val)
,它决定了它是成功还是失败。
精神X3
在 Spirit X3 中,同样的机制也适用,只是 X3 没有与 Phoenix 集成。这意味着两件事:
- 从好的方面来说,我们可以只使用核心语言特征 (lambdas) 来进行语义操作,从而使学习曲线不那么陡峭
- 不利的一面是,没有一个只有一个参数的版本
x3::eps
需要一个懒惰的演员
这是一个带有 X3 的演示程序:
Live On Coliru
#include <boost/spirit/home/x3.hpp>
namespace parser {
using namespace boost::spirit::x3;
auto is_ltua = [](auto& ctx) {
_pass(ctx) = 0 == (_attr(ctx) % 42);
};
auto start = int_ [ is_ltua ];
}
#include <iostream>
int main() {
for (std::string const txt : { "43", "42", "84", "85" }) {
int data;
if (parse(txt.begin(), txt.end(), parser::start, data))
std::cout << "Parsed " << data << "\n";
else
std::cout << "Parse failed (" << txt << ")\n";
}
}
印刷
Parse failed (43)
Parsed 42
Parsed 84
Parse failed (85)