Skip to content

Commit

Permalink
Fix #213
Browse files Browse the repository at this point in the history
  • Loading branch information
yhirose committed Jun 17, 2022
1 parent af43f1f commit f6b1a73
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions peglib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1950,8 +1950,9 @@ struct DetectLeftRecursion : public Ope::Visitor {
};

struct HasEmptyElement : public Ope::Visitor {
HasEmptyElement(std::vector<std::pair<const char *, std::string>> &refs)
: refs_(refs) {}
HasEmptyElement(std::vector<std::pair<const char *, std::string>> &refs,
std::unordered_map<std::string, bool> &has_error_cache)
: refs_(refs), has_error_cache_(has_error_cache) {}

void visit(Sequence &ope) override;
void visit(PrioritizedChoice &ope) override {
Expand Down Expand Up @@ -1993,17 +1994,20 @@ struct HasEmptyElement : public Ope::Visitor {
tie(error_s, error_name) = refs_.back();
}
std::vector<std::pair<const char *, std::string>> &refs_;
std::unordered_map<std::string, bool> &has_error_cache_;
};

struct DetectInfiniteLoop : public Ope::Visitor {
DetectInfiniteLoop(const char *s, const std::string &name,
std::vector<std::pair<const char *, std::string>> &refs)
: refs_(refs) {
std::vector<std::pair<const char *, std::string>> &refs,
std::unordered_map<std::string, bool> &has_error_cache)
: refs_(refs), has_error_cache_(has_error_cache) {
refs_.emplace_back(s, name);
}

DetectInfiniteLoop(std::vector<std::pair<const char *, std::string>> &refs)
: refs_(refs) {}
DetectInfiniteLoop(std::vector<std::pair<const char *, std::string>> &refs,
std::unordered_map<std::string, bool> &has_error_cache)
: refs_(refs), has_error_cache_(has_error_cache) {}

void visit(Sequence &ope) override {
for (auto op : ope.opes_) {
Expand All @@ -2019,7 +2023,7 @@ struct DetectInfiniteLoop : public Ope::Visitor {
}
void visit(Repetition &ope) override {
if (ope.max_ == std::numeric_limits<size_t>::max()) {
HasEmptyElement vis(refs_);
HasEmptyElement vis(refs_, has_error_cache_);
ope.ope_->accept(vis);
if (vis.is_empty) {
has_error = true;
Expand Down Expand Up @@ -2049,7 +2053,7 @@ struct DetectInfiniteLoop : public Ope::Visitor {

private:
std::vector<std::pair<const char *, std::string>> &refs_;
std::unordered_map<std::string, bool> has_error_cache_;
std::unordered_map<std::string, bool> &has_error_cache_;
};

struct ReferenceChecker : public Ope::Visitor {
Expand Down Expand Up @@ -3041,7 +3045,7 @@ inline void HasEmptyElement::visit(Sequence &ope) {
if (!is_empty) {
++it;
while (it != ope.opes_.end()) {
DetectInfiniteLoop vis(refs_);
DetectInfiniteLoop vis(refs_, has_error_cache_);
(*it)->accept(vis);
if (vis.has_error) {
is_empty = true;
Expand Down Expand Up @@ -4048,7 +4052,8 @@ class ParserGenerator {
bool detect_infiniteLoop(const Data &data, Definition &rule, const Log &log,
const char *s) const {
std::vector<std::pair<const char *, std::string>> refs;
DetectInfiniteLoop vis(data.start_pos, rule.name, refs);
std::unordered_map<std::string, bool> has_error_cache;
DetectInfiniteLoop vis(data.start_pos, rule.name, refs, has_error_cache);
rule.accept(vis);
if (vis.has_error) {
if (log) {
Expand Down

0 comments on commit f6b1a73

Please sign in to comment.