gpt4 book ai didi

c++ - 可能会失败的 "post-initialization"的 eps 解析器

转载 作者:行者123 更新时间:2023-11-30 01:43:08 25 4
gpt4 key购买 nike

我正在阅读 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 是否有助于对解析输入的一部分进行某种语义/后分析,这可能会失败,以获得某种语法中检查的位置。

是否存在可能失败的 eps,使用此构造进行额外的输入验证是否是个好主意?

我想表达的是一个糟糕的例子:

int_ >> eps_might_fail[is_prime]

这将只解析质数,如果我没记错的话,并允许完整的解析器在它需要质数的地方失败。

最佳答案

语义 Action 就是为此而设计的。

灵气

最自然的例子是

 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 没有采用懒惰 actor 的单参数版本

这是一个 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)

关于c++ - 可能会失败的 "post-initialization"的 eps 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38302271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com