ppc-lang/include/treeifier/parsers/inspoint.hh

52 lines
1.4 KiB
C++
Raw Normal View History

2023-02-10 14:10:34 +00:00
#pragma once
2023-01-26 08:06:39 +00:00
#include "treeifier/constr.hh"
2023-02-10 14:10:34 +00:00
#include "treeifier/parsers/helper.hh"
#ifdef PROFILE_debug
#include <iostream>
#endif
namespace ppc::tree::parse {
2023-01-26 08:06:39 +00:00
struct named_t {
virtual std::string name() = 0;
virtual ~named_t() = default;
#ifdef PROFILE_debug
virtual void print() { std::cout << "(" << name() << ")"; }
#endif
};
template <class ParserT, class ResT>
class inspoint_t {
private:
std::map<std::string, std::unique_ptr<ParserT>> parsers;
public:
inspoint_t<ParserT, ResT> &add(const ParserT &parser, bool replace = false) {
const std::string &name = parser.name();
auto it = parsers.find(name);
if (it != parsers.end()) {
if (!replace) throw "The parser '" + name + "' is already in the group.";
it->second = std::make_unique(parser);
}
else {
parsers.emplace(name, std::make_unique(parser));
}
return *this;
}
2023-02-10 14:10:34 +00:00
bool operator()(ppc::tree::parse_ctx_t &ctx, size_t &i, std::unique_ptr<ResT> &out) const override {
2023-01-26 08:06:39 +00:00
helper_t h(ctx, i);
if (h.ended()) return false;
for (std::pair<std::string, std::unique_ptr<ParserT>> &pair : parsers) {
2023-02-10 14:10:34 +00:00
if (pair.second(ctx, i, out)) return true;
2023-01-26 08:06:39 +00:00
}
return false;
}
};
}