mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Performance improvements
This commit is contained in:
parent
2180657eea
commit
7d00be396b
119
peglib.h
119
peglib.h
@ -61,7 +61,7 @@ auto any_cast( Args&&... args ) -> decltype(std::any_cast<T>(std::forward<Args>(
|
||||
class any
|
||||
{
|
||||
public:
|
||||
any() : content_(nullptr) {}
|
||||
any() = default;
|
||||
|
||||
any(const any& rhs) : content_(rhs.clone()) {}
|
||||
|
||||
@ -126,7 +126,7 @@ private:
|
||||
return content_ ? content_->clone() : nullptr;
|
||||
}
|
||||
|
||||
placeholder* content_;
|
||||
placeholder* content_ = nullptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -571,18 +571,6 @@ private:
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
path = nullptr;
|
||||
ss = nullptr;
|
||||
source_line_index = nullptr;
|
||||
tokens.clear();
|
||||
|
||||
s_ = nullptr;
|
||||
n_ = 0;
|
||||
choice_count_ = 0;
|
||||
choice_ = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -816,7 +804,8 @@ public:
|
||||
|
||||
std::shared_ptr<Ope> wordOpe;
|
||||
|
||||
std::vector<std::unordered_map<std::string, std::string>> capture_scope_stack;
|
||||
std::vector<std::map<std::string, std::string>> capture_scope_stack;
|
||||
size_t capture_scope_stack_size = 0;
|
||||
|
||||
const size_t def_count;
|
||||
const bool enablePackratParsing;
|
||||
@ -855,7 +844,8 @@ public:
|
||||
source_line_index.push_back(l);
|
||||
|
||||
args_stack.resize(1);
|
||||
capture_scope_stack.resize(1);
|
||||
|
||||
push_capture_scope();
|
||||
}
|
||||
|
||||
~Context() {
|
||||
@ -901,13 +891,20 @@ public:
|
||||
assert(value_stack_size <= value_stack.size());
|
||||
if (value_stack_size == value_stack.size()) {
|
||||
value_stack.emplace_back(std::make_shared<SemanticValues>());
|
||||
} else {
|
||||
auto& sv = *value_stack[value_stack_size];
|
||||
if (!sv.empty()) {
|
||||
sv.clear();
|
||||
sv.tags.clear();
|
||||
}
|
||||
sv.s_ = nullptr;
|
||||
sv.n_ = 0;
|
||||
sv.choice_count_ = 0;
|
||||
sv.choice_ = 0;
|
||||
sv.tokens.clear();
|
||||
}
|
||||
|
||||
auto& sv = *value_stack[value_stack_size++];
|
||||
if (!sv.empty()) {
|
||||
sv.clear();
|
||||
sv.tags.clear();
|
||||
}
|
||||
sv.reset();
|
||||
sv.path = path;
|
||||
sv.ss = s;
|
||||
sv.source_line_index = &source_line_index;
|
||||
@ -918,8 +915,8 @@ public:
|
||||
value_stack_size--;
|
||||
}
|
||||
|
||||
void push_args(const std::vector<std::shared_ptr<Ope>>& args) {
|
||||
args_stack.push_back(args);
|
||||
void push_args(std::vector<std::shared_ptr<Ope>>&& args) {
|
||||
args_stack.emplace_back(args);
|
||||
}
|
||||
|
||||
void pop_args() {
|
||||
@ -931,19 +928,26 @@ public:
|
||||
}
|
||||
|
||||
void push_capture_scope() {
|
||||
capture_scope_stack.resize(capture_scope_stack.size() + 1);
|
||||
assert(capture_scope_stack_size <= capture_scope_stack.size());
|
||||
if (capture_scope_stack_size == capture_scope_stack.size()) {
|
||||
capture_scope_stack.emplace_back(std::map<std::string, std::string>());
|
||||
} else {
|
||||
auto& cs = capture_scope_stack[capture_scope_stack_size];
|
||||
cs.clear();
|
||||
}
|
||||
capture_scope_stack_size++;
|
||||
}
|
||||
|
||||
void pop_capture_scope() {
|
||||
capture_scope_stack.pop_back();
|
||||
capture_scope_stack_size--;
|
||||
}
|
||||
|
||||
void shift_capture_values() {
|
||||
assert(capture_scope_stack.size() >= 2);
|
||||
auto it = capture_scope_stack.rbegin();
|
||||
auto it_prev = it + 1;
|
||||
for (const auto& kv: *it) {
|
||||
(*it_prev)[kv.first] = kv.second;
|
||||
auto curr = &capture_scope_stack[capture_scope_stack_size - 1];
|
||||
auto prev = curr - 1;
|
||||
for (const auto& kv: *curr) {
|
||||
(*prev)[kv.first] = kv.second;
|
||||
}
|
||||
}
|
||||
|
||||
@ -992,11 +996,23 @@ public:
|
||||
}
|
||||
i += len;
|
||||
}
|
||||
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
||||
sv.tags.insert(sv.tags.end(), chldsv.tags.begin(), chldsv.tags.end());
|
||||
if (!chldsv.empty()) {
|
||||
for (size_t i = 0; i < chldsv.size(); i++) {
|
||||
sv.emplace_back(std::move(chldsv[i]));
|
||||
}
|
||||
}
|
||||
if (!chldsv.tags.empty()) {
|
||||
for (size_t i = 0; i < chldsv.tags.size(); i++) {
|
||||
sv.tags.emplace_back(std::move(chldsv.tags[i]));
|
||||
}
|
||||
}
|
||||
sv.s_ = chldsv.c_str();
|
||||
sv.n_ = chldsv.length();
|
||||
sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end());
|
||||
if (!chldsv.tokens.empty()) {
|
||||
for (size_t i = 0; i < chldsv.tokens.size(); i++) {
|
||||
sv.tokens.emplace_back(std::move(chldsv.tokens[i]));
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -1028,13 +1044,25 @@ public:
|
||||
const auto& rule = *ope;
|
||||
auto len = rule.parse(s, n, chldsv, c, dt);
|
||||
if (success(len)) {
|
||||
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
||||
sv.tags.insert(sv.tags.end(), chldsv.tags.begin(), chldsv.tags.end());
|
||||
if (!chldsv.empty()) {
|
||||
for (size_t i = 0; i < chldsv.size(); i++) {
|
||||
sv.emplace_back(std::move(chldsv[i]));
|
||||
}
|
||||
}
|
||||
if (!chldsv.tags.empty()) {
|
||||
for (size_t i = 0; i < chldsv.tags.size(); i++) {
|
||||
sv.tags.emplace_back(std::move(chldsv.tags[i]));
|
||||
}
|
||||
}
|
||||
sv.s_ = chldsv.c_str();
|
||||
sv.n_ = chldsv.length();
|
||||
sv.choice_count_ = opes_.size();
|
||||
sv.choice_ = id;
|
||||
sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end());
|
||||
if (!chldsv.tokens.empty()) {
|
||||
for (size_t i = 0; i < chldsv.tokens.size(); i++) {
|
||||
sv.tokens.emplace_back(std::move(chldsv.tokens[i]));
|
||||
}
|
||||
}
|
||||
|
||||
c.shift_capture_values();
|
||||
return len;
|
||||
@ -2447,7 +2475,7 @@ inline size_t Reference::parse(
|
||||
args.push_back(vis.found_ope);
|
||||
}
|
||||
|
||||
c.push_args(args);
|
||||
c.push_args(std::move(args));
|
||||
auto se = make_scope_exit([&]() { c.pop_args(); });
|
||||
auto ope = get_core_operator();
|
||||
return ope->parse(s, n, sv, c, dt);
|
||||
@ -2469,16 +2497,14 @@ inline std::shared_ptr<Ope> Reference::get_core_operator() const {
|
||||
|
||||
inline size_t BackReference::parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const {
|
||||
c.trace("BackReference", s, n, sv, dt);
|
||||
auto it = c.capture_scope_stack.rbegin();
|
||||
while (it != c.capture_scope_stack.rend()) {
|
||||
const auto& captures = *it;
|
||||
if (captures.find(name_) != captures.end()) {
|
||||
const auto& lit = captures.at(name_);
|
||||
for (int i = c.capture_scope_stack_size - 1; i >= 0; i--) {
|
||||
const auto& cs = c.capture_scope_stack[i];
|
||||
if (cs.find(name_) != cs.end()) {
|
||||
const auto& lit = cs.at(name_);
|
||||
auto init_is_word = false;
|
||||
auto is_word = false;
|
||||
return parse_literal(s, n, sv, c, dt, lit, init_is_word, is_word, false);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
throw std::runtime_error("Invalid back reference...");
|
||||
}
|
||||
@ -2912,7 +2938,8 @@ private:
|
||||
const auto& name = any_cast<std::string>(sv[0]);
|
||||
auto ope = any_cast<std::shared_ptr<Ope>>(sv[1]);
|
||||
return cap(ope, [name](const char* a_s, size_t a_n, Context& c) {
|
||||
c.capture_scope_stack.back()[name] = std::string(a_s, a_n);
|
||||
auto& cs = c.capture_scope_stack[c.capture_scope_stack_size - 1];
|
||||
cs[name] = std::string(a_s, a_n);
|
||||
});
|
||||
}
|
||||
default: {
|
||||
@ -2924,12 +2951,6 @@ private:
|
||||
g["IdentCont"] = [](const SemanticValues& sv) {
|
||||
return std::string(sv.c_str(), sv.length());
|
||||
};
|
||||
g["IdentStart"] = [](const SemanticValues& /*sv*/) {
|
||||
return std::string();
|
||||
};
|
||||
g["IdentRest"] = [](const SemanticValues& /*sv*/) {
|
||||
return std::string();
|
||||
};
|
||||
|
||||
g["LiteralI"] = [](const SemanticValues& sv) {
|
||||
const auto& tok = sv.tokens.front();
|
||||
|
Loading…
Reference in New Issue
Block a user