gpt4 book ai didi

c++ - Boost Spirit Qi Symbols默认值和NULL值

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:00:24 27 4
gpt4 key购买 nike

Boost Spirit qi::symbols 实现了一个键值对映射:给一个字符串的键,它可以返回某个值。我的问题是:

1) 对于一个空字符串,是否可以返回一个默认值? (代码中的Q1)

2) 对于非空字符串或键值对映射中列出的键,是否可以返回一个值表示该键无效? (代码中的Q2)

** 以下代码基于 BOOST SPIRIT 文档。** 在此先感谢您的任何建议。

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true)
{
using boost::spirit::qi::parse;

char const* f(input);
char const* l(f + strlen(f));
if (parse(f, l, p, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}

int main()
{
using boost::spirit::qi::symbols;

symbols<char, int> sym;
sym.add
("Apple", 1)
("Banana", 2)
("Orange", 3)
;

int i;
test_parser_attr("Banana", sym, i);
std::cout << i << std::endl; // 2


test_parser_attr("", sym, i); // Q1: key is "",
std::cout << i << std::endl; // would like it to be 1 as default

test_parser_attr("XXXX", sym, i); // Q2: key is other than "Apple"/"Banana"/"Orange",
std::cout << i << std::endl; // would like it to be 4

return 0;
}

最佳答案

您无法仅使用 qi::symbols 来完成您想要的。应该可以创建一个达到预期结果的 Spirit 终端/指令,但这样做会非常复杂,并且需要了解 qi::symbols 和相关类的内部工作原理,所以我不不认为这是一个值得的方法。幸运的是,有一个非常简单的替代方法,使用 qi::attr(val) ,一个不消耗任何输入的解析器,将 val 作为其属性公开并始终成功。

让我们看看所有三种情况:

  • 如果字符串在符号表中,则返回其关联值->只需使用sym
  • 如果字符串为空返回 1 -> 只需使用 attr(1)
  • 如果字符串不在符号表中 return 4 -> 这里你需要使用 attr(4) 但这还不够,因为你还需要消耗字符串。如果我们假设字符串仅由字母组成,omit[+alpha] 可以工作(omit 丢弃文本,而 + 确保有至少是一个字母)。

你需要把这三个解析器放在一个 alternative parser 中请记住,每种情况下实际使用的解析器将是第一个成功的解析器:

sym | omit[+alpha] >> attr(4) | attr(1)

可能出现的问题:

  • 如果您的不在符号表中的字符串可能更复杂,您需要适本地更改 +alpha
  • 如果您使用船长,您可能需要使用omit[lexeme[+alpha]] 停止贪婪的+

完整样本 (Running on WandBox)

#include <iostream>
#include <string>

#include <boost/spirit/include/qi.hpp>


template <typename P, typename T>
void test_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true)
{
using boost::spirit::qi::parse;

char const* f(input);
char const* l(f + strlen(f));
if (parse(f, l, p, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}

int main()
{
using boost::spirit::qi::symbols;

symbols<char, int> sym;
sym.add
("Apple", 1)
("Banana", 2)
("Orange", 3)
;

using boost::spirit::qi::attr;
using boost::spirit::qi::alpha;
using boost::spirit::qi::omit;
using boost::spirit::qi::lexeme;

//if the text is in the symbol table return the associated value
//else if the text is formed by letters (you could change this using for example `alnum`) and contains at least one, discard the text and return 4
//else return 1
boost::spirit::qi::rule<char const*,int()> symbols_with_defaults = sym | omit[+alpha] >> attr (4) | attr(1);


int i;
test_parser_attr("Banana", symbols_with_defaults, i);
std::cout << i << std::endl; // 2

test_parser_attr("", symbols_with_defaults, i); // Q1: key is "",
std::cout << i << std::endl; // would like it to be 1 as default

test_parser_attr("XXXX", symbols_with_defaults, i); // Q2: key is other than "Apple"/"Banana"/"Orange",
std::cout << i << std::endl; // would like it to be 4

std::vector<int> values;
test_parser_attr("<Banana>,<>,<xxxx>", ('<' >> symbols_with_defaults >> '>')%',', values);
for(int val : values)
std::cout << val << " "; // should be '2 1 4'
std::cout << std::endl;

return 0;
}

关于c++ - Boost Spirit Qi Symbols默认值和NULL值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39177729/

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