可能因 "post-initialization" 失败而失败的 eps 解析器
eps parser that can fail for a "post-initialization" that could fail
我正在阅读 the Boost X3 Quick Start tutorial 并注意到行
eps
is a special spirit parser that consumes no input but is always successful. We use it to initialize the rule's synthesized attribute, to zero before anything else. [...] Using eps
this way is good for doing pre and post initializations.
现在我不禁想知道 eps_that_might_fail
是否有助于对已解析输入的一部分进行某种 semantic/post 分析,这可能会失败,以进行某种排序语法内部检查的位置。
是否存在可能失败的问题eps
,使用此构造进行额外的输入验证是否是个好主意?
我要传达的一个糟糕例子:
int_ >> eps_might_fail[is_prime]
如果我没记错的话,这将只解析质数,并允许完整的解析器在需要质数的地方失败。
语义动作就是为此而设计的。
灵气
最自然的例子是
qi::int_ [ qi::_pass = is_prime(qi::_1) ]
一定要在存在语义操作的情况下使用 %=
规则分配,因为没有它,语义操作会禁用自动属性传播。
显然,您也可以更详细地编写
qi::int_ >> qi::eps(is_prime(qi::_val))
如您所见,引用的文档略微不完整:eps
已经可以接受一个参数,在本例中是懒惰的参与者 is_prime(qi::_val)
,它确定它是成功还是失败。
灵X3
在 Spirit X3 中应用相同的机制,只是 X3 没有与 Phoenix 集成。这意味着两件事:
- 从好的方面来说,我们可以只使用核心语言特征 (lambdas) 进行语义操作,使学习曲线不那么陡峭
- 不利的一面是,
x3::eps
没有采用懒惰 actor 的单参数版本
这是一个 X3 的演示程序:
#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)
我正在阅读 the Boost X3 Quick Start tutorial 并注意到行
eps
is a special spirit parser that consumes no input but is always successful. We use it to initialize the rule's synthesized attribute, to zero before anything else. [...] Usingeps
this way is good for doing pre and post initializations.
现在我不禁想知道 eps_that_might_fail
是否有助于对已解析输入的一部分进行某种 semantic/post 分析,这可能会失败,以进行某种排序语法内部检查的位置。
是否存在可能失败的问题eps
,使用此构造进行额外的输入验证是否是个好主意?
我要传达的一个糟糕例子:
int_ >> eps_might_fail[is_prime]
如果我没记错的话,这将只解析质数,并允许完整的解析器在需要质数的地方失败。
语义动作就是为此而设计的。
灵气
最自然的例子是
qi::int_ [ qi::_pass = is_prime(qi::_1) ]
一定要在存在语义操作的情况下使用 %=
规则分配,因为没有它,语义操作会禁用自动属性传播。
显然,您也可以更详细地编写
qi::int_ >> qi::eps(is_prime(qi::_val))
如您所见,引用的文档略微不完整:eps
已经可以接受一个参数,在本例中是懒惰的参与者 is_prime(qi::_val)
,它确定它是成功还是失败。
灵X3
在 Spirit X3 中应用相同的机制,只是 X3 没有与 Phoenix 集成。这意味着两件事:
- 从好的方面来说,我们可以只使用核心语言特征 (lambdas) 进行语义操作,使学习曲线不那么陡峭
- 不利的一面是,
x3::eps
没有采用懒惰 actor 的单参数版本
这是一个 X3 的演示程序:
#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)