gpt4 book ai didi

c++ - 将 Boost Spirit 递归匹配结果保存到 C++ 结构

转载 作者:太空狗 更新时间:2023-10-29 22:58:13 24 4
gpt4 key购买 nike

我成功地解析了像 "A, (B, C), (D, E, (F, G)), H"这样的字符串

但是,我未能将匹配结果保存到 C++ 结构中。

我无法找出规则的正确属性类型。

以下是解析的最小测试用例。

TEST_CASE("recursive match", "[qi]")
{
namespace qi = boost::spirit::qi;
using qi::char_;

struct recursive_match
: qi::grammar<std::string::iterator, qi::ascii::space_type>
{
recursive_match() : recursive_match::base_type(div_)
{
subdiv_ = '(' >> div_ >> ')';
div_ = (char_("A-Z") | subdiv_) % ',';
}

qi::rule<std::string::iterator, qi::ascii::space_type> subdiv_;
qi::rule<std::string::iterator, qi::ascii::space_type> div_;
};

std::string s = "A, (B, C), (D, E, (F, G)), H";
auto begin = s.begin();
auto end = s.end();
recursive_match rule_;
bool r = qi::phrase_parse(begin, end, rule_, qi::ascii::space);
REQUIRE(r);
REQUIRE(begin == end);
}

任何对我有用的东西。谢谢。

最佳答案

我建议使用递归变体:

using node = boost::make_recursive_variant<
char,
std::vector<boost::recursive_variant_>
>::type;

using nodes = std::vector<node>;

现在,您可以更简单地声明规则:

qi::rule<It, Ast::node(),  qi::ascii::space_type> node_;
qi::rule<It, Ast::nodes(), qi::ascii::space_type> list_;

定义是这样的

node_ = char_("A-Z") | '(' >> list_ >> ')';
list_ = node_ % ',';

完整演示

为调试输出添加一些代码:

Live On Coliru

//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/io.hpp>
namespace qi = boost::spirit::qi;

namespace std {
// for debug output
template <typename T>
inline static std::ostream& operator<<(std::ostream& os, std::vector<T> const& v) {
os << "(";
bool first = true;
for (auto& el : v) {
(first?os:os << ", ") << el;
first = false;
}
return os << ")";
}
}

namespace Ast {
using node = boost::make_recursive_variant<
char,
std::vector<boost::recursive_variant_>
>::type;

using nodes = std::vector<node>;
}

template <typename It = std::string::const_iterator>
struct recursive_match : qi::grammar<It, Ast::nodes(), qi::ascii::space_type> {
recursive_match() : recursive_match::base_type(list_) {
using namespace qi;

node_ = char_("A-Z") | '(' >> list_ >> ')';
list_ = node_ % ',';

BOOST_SPIRIT_DEBUG_NODES((node_)(list_))
}

private:
qi::rule<It, Ast::node(), qi::ascii::space_type> node_;
qi::rule<It, Ast::nodes(), qi::ascii::space_type> list_;
};

int main() {
using qi::char_;

std::string const s = "A, (B, C), (D, E, (F, G)), H";
auto begin = s.begin();
auto end = s.end();
recursive_match<> rule_;
Ast::nodes parsed;
bool ok = qi::phrase_parse(begin, end, rule_, qi::ascii::space, parsed);

if (ok)
std::cout << "Parsed: " << parsed << "\n";
else
std::cout << "Parse failed\n";

if (begin != end)
std::cout << "Remaining unparsed input: '" << std::string(begin, end) << "'\n";
}

打印:

Parsed: (A, (B, C), (D, E, (F, G)), H)

关于c++ - 将 Boost Spirit 递归匹配结果保存到 C++ 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41330814/

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