c++ - 用提升精神解析继承的结构

标签 c++ inheritance boost-spirit

我有一个摘要struct Base没有字段(只有抽象方法)和struct A , struct B继承自 Base两者都有不同的领域。

是否可以有一个规则来解析 AB并将结果存储在 shared_ptr<Base> 中?

我想这样做是为了解析一些 AB并将其存储在 shared_ptr<Base> 的容器中.

这是结构的定义:

#include <iostream>
using namespace std;

struct Base
{
  virtual void operator() const = 0;
};

struct A : Base
{
  int value;
  void operator() const override { cout << "Hello A: " << x << endl; };
};

struct B : Base
{
  float value;
  void operator() const override { cout << "Hello B: " << x << endl; };
};

struct BaseContainer
{
  multimap<string, shared_ptr<Base>> container;
}

假设一个 BaseContainer由一些格式如下的输入定义:

name: A value
name: B value
name: A value

哪里name是用作 multimap 键的字符串的占位符在BaseContainer , 然后 AB是生成 struct A 的关键字或 struct B , value 是存储在容器中的值。

我将如何编写解析器 BaseContainer

我想应用它的真实例子更复杂,struct Astruct B其中没有相同数量的字段,因此请不要回答该示例过于具体的内容。 谢谢。

最佳答案

所以这里有两个问题,我觉得:

更新

在这个问题的上下文中,方法 2 的小型演示:

Live On Wandbox

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted.hpp>
#include <map>
#include <iomanip> // std::quoted

struct Base {}; // dynamic polymorphism not required for us now, no problem if you want it

struct A : Base {
    int value;
    void operator()() const { std::cout << "Hello A: " << value << std::endl; };
};

struct B : Base {
    float value;
    void operator()() const { std::cout << "Hello B: " << value << std::endl; };
};

using Node = boost::variant<A, B>;
struct BaseContainer {
    using Map = std::multimap<std::string, Node>;
    Map container;
};

BOOST_FUSION_ADAPT_STRUCT(A, value)
BOOST_FUSION_ADAPT_STRUCT(B, value)
BOOST_FUSION_ADAPT_STRUCT(BaseContainer, container)

namespace qi = boost::spirit::qi;

template <typename It> 
struct Parser : qi::grammar<It, BaseContainer()> {
    Parser() : Parser::base_type(start) {
        using namespace qi;
        _key       = lexeme['"' >> *('\\' >> char_ | ~char_('"')) >> '"'];
        _a_node    = "A(" >> int_ >> ")";
        _b_node    = "B(" >> float_ >> ")";
        _node      = _a_node | _b_node;
        _pair      = '{' >> _key >> ',' >> _node >> '}';
        _container = '{' >> -(_pair % ',') >> '}';

        start = skip(space) [ _container ];

        BOOST_SPIRIT_DEBUG_NODES((start)(_container)(_pair)(_key)(_node)(_a_node)(_b_node))
    }
  private:
    qi::rule<It, BaseContainer()> start;

    // lexeme
    qi::rule<It, std::string()> _key;

    using Skipper = qi::space_type;
    using Pair = std::pair<std::string, Node>;

    qi::rule<It, BaseContainer::Map(), Skipper> _container;
    qi::rule<It, Pair(), Skipper> _pair;
    qi::rule<It, Node(), Skipper> _node;
    qi::rule<It, A(), Skipper> _a_node;
    qi::rule<It, B(), Skipper> _b_node;
};

int main() {
    Parser<std::string::const_iterator> const p;
    for (std::string const input : {
            R"({})",
            R"({ { "one", A(42) } })",
            R"({ { "two", B(3.14) } })",
            R"({ { "three", A( -42 ) }, { "four", B( -3.14 ) } })",
            })
    {
        std::cout << "-------\n";
        std::cout << "Parsing " << input << "\n";
        auto f = begin(input), l = end(input);

        BaseContainer result;
        if (qi::parse(f, l, p, result)) {
            for (auto const& [k,v] : result.container) {
                std::cout << " Key " << std::quoted(k) << ": ";
                boost::apply_visitor([](auto const& node) { node(); }, v);
            }
        } else {
            std::cout << "Parse failed\n";
        }

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

打印

-------
Parsing {}
-------
Parsing { { "one", A(42) } }
 Key "one": Hello A: 42
-------
Parsing { { "two", B(3.14) } }
 Key "two": Hello B: 3.14
-------
Parsing { { "three", A( -42 ) }, { "four", B( -3.14 ) } }
 Key "four": Hello B: -3.14
 Key "three": Hello A: -42

关于c++ - 用提升精神解析继承的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56872966/

相关文章:

c++ - 实现 [B,C]=f(A) 语法(函数 f 作用于具有两个或多个输出数组的数组)

c++ - 当元组给出参数时如何检查方法是否存在?

eclipse上的java继承

c++ - 是否可以从 boost::function 继承?

c++ - 嵌套 boost::variant 的段错误

c++ - opencv - 在 cvCvtColor 中断言失败(dst.data == dst0.data)

c++ - 删除谁的责任

java - 线程中的异常 "main"org.hibernate.exception.SQLGrammarException : ORA-00926: missing VALUES keyword

c++ - Boost Spirit 2 - 符号扩展和回溯

c++ - 关于 Boost::Spirit 自动规则行为的困惑