From cd1da19062c8436f716ca1e18c1e4865ad1bb5c9 Mon Sep 17 00:00:00 2001 From: yhirose Date: Fri, 6 May 2022 16:31:33 -0400 Subject: [PATCH] Fix #197 --- peglib.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/peglib.h b/peglib.h index b5811f7..e6712cc 100644 --- a/peglib.h +++ b/peglib.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -964,7 +963,7 @@ public: bool is_traceable(const Ope &ope) const; mutable size_t next_trace_id = 0; - mutable std::list trace_ids; + mutable std::vector trace_ids; }; /* @@ -1955,7 +1954,7 @@ private: }; struct HasEmptyElement : public Ope::Visitor { - HasEmptyElement(std::list> &refs) + HasEmptyElement(std::vector> &refs) : refs_(refs) {} void visit(Sequence &ope) override { @@ -2013,7 +2012,7 @@ private: is_empty = true; tie(error_s, error_name) = refs_.back(); } - std::list> &refs_; + std::vector> &refs_; }; struct DetectInfiniteLoop : public Ope::Visitor { @@ -2064,7 +2063,8 @@ struct DetectInfiniteLoop : public Ope::Visitor { std::string error_name; private: - std::list> refs_; + std::vector> refs_; + std::unordered_map has_error_cache_; }; struct ReferenceChecker : public Ope::Visitor { @@ -2956,9 +2956,15 @@ inline void DetectInfiniteLoop::visit(Reference &ope) { if (it != refs_.end()) { return; } if (ope.rule_) { - refs_.emplace_back(ope.s_, ope.name_); - ope.rule_->accept(*this); - refs_.pop_back(); + auto it = has_error_cache_.find(ope.name_); + if (it != has_error_cache_.end()) { + has_error = it->second; + } else { + refs_.emplace_back(ope.s_, ope.name_); + ope.rule_->accept(*this); + refs_.pop_back(); + has_error_cache_[ope.name_] = has_error; + } } if (ope.is_macro_) {