gpt4 book ai didi

c++ - 如何在语义操作中访问元组的元素

转载 作者:太空狗 更新时间:2023-10-29 21:35:42 24 4
gpt4 key购买 nike

我的语法有各种以通用名称开头的条目。确定类型后,我想使用期望运算符来创建解析错误。

rule1=name >> (type1 > something);
rule2=name >> (type2 > something);

我已经想到我不能混合使用 > 和 >> 这两个运算符——这就是括号的原因。我的猜测是括号导致创建一个元组。如何在语义操作中访问元组的元素?以下肯定是错误的,但应该阐明我想要完成的事情。

rule1=(name >> (type1 > something))[qi::_val = boost::phoenix::bind(
create,
qi::_1,
std::get<0>(qi::_2),
std::get<1>(qi::_2))];

谢谢

最佳答案

直接解决问题:

using px::at_c;
rule1 = (name >> (type1 > something)) [_val = px::bind(create, _1, at_c<0>(_2), at_c<1>(_2))];

但是,我会在 qi::eps 中使用这个小技巧为了避免复杂性:

rule2 = (name >> type1 >> (eps > something)) [_val = px::bind(create, _1, _2, _3)];

最后看boost::phoenix::function<> :

px::function<decltype(&create)> create_(create); // or just decltype(create) if it's a function object
rule3 = (name >> type1 >> (eps > something)) [_val = create_(_1, _2, _3)];

这样你甚至可以获得可读的代码!

演示

只是为了证明所有三个都具有相同的行为¹

Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/at_c.hpp>

namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;

static int create(char n, char t, char s) {
assert(n=='n' && t=='t' && s=='s');
return 42;
}

int main() {
using It = std::string::const_iterator;

// fake rules just for demo
qi::rule<It, char()>
name = qi::char_("n"),
type1 = qi::char_("t"),
something = qi::char_("s");

//using boost::fusion::at_c;
qi::rule<It, int(), qi::space_type> rule1, rule2, rule3;

{
using namespace qi;
using px::at_c;

rule1 = (name >> (type1 > something)) [_val = px::bind(create, _1, at_c<0>(_2), at_c<1>(_2))];
rule2 = (name >> type1 >> (eps > something)) [_val = px::bind(create, _1, _2, _3)];

px::function<decltype(&create)> create_(create); // or just decltype(create) if it's a function object
rule3 = (name >> type1 >> (eps > something)) [_val = create_(_1, _2, _3)];
}

for(auto& parser : { rule1, rule2, rule3 }) {
for(std::string const input : { "n t s", "n t !" }) {
std::cout << "Input: '" << input << "'\n";
auto f = input.begin(), l = input.end();
int data;

try {
bool ok = qi::phrase_parse(f, l, parser, qi::space, data);
if (ok) {
std::cout << "Parsing result: " << data << '\n';
} else {
std::cout << "Parsing failed\n";
}
} catch(qi::expectation_failure<It> const& e) {
std::cout << "Expectation failure: " << e.what() << " at '" << std::string(e.first, e.last) << "'\n";
}

if (f!=l) {
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}

std::cout << "-------------------------------------------\n";
}
}
}

打印 3 倍相同的输出:

Input: 'n t s'
Parsing result: 42
-------------------------------------------
Input: 'n t !'
Expectation failure: boost::spirit::qi::expectation_failure at '!'
Remaining unparsed: 'n t !'
-------------------------------------------
Input: 'n t s'
Parsing result: 42
-------------------------------------------
Input: 'n t !'
Expectation failure: boost::spirit::qi::expectation_failure at '!'
Remaining unparsed: 'n t !'
-------------------------------------------
Input: 'n t s'
Parsing result: 42
-------------------------------------------
Input: 'n t !'
Expectation failure: boost::spirit::qi::expectation_failure at '!'
Remaining unparsed: 'n t !'
-------------------------------------------

¹ PS 让这作为如何在您的问题中创建 SSCCE 代码示例的示例

关于c++ - 如何在语义操作中访问元组的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41667945/

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