From c2e19cfd01d1cb4e4c509dbb8ff197b059c38b3d Mon Sep 17 00:00:00 2001 From: yhirose Date: Sat, 13 Jun 2015 00:57:45 -0400 Subject: [PATCH] Added definition duplicates check. --- peglib.h | 42 +++++++++++++++++++++++++++++------------- test/test.cc | 10 ++++++++++ 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/peglib.h b/peglib.h index 7f9ab1b..7faea7f 100644 --- a/peglib.h +++ b/peglib.h @@ -1514,11 +1514,12 @@ private: } struct Data { - std::shared_ptr grammar; - std::string start; - MatchAction match_action; - std::unordered_map references; - size_t capture_count; + std::shared_ptr grammar; + std::string start; + MatchAction match_action; + std::vector> duplicates; + std::unordered_map references; + size_t capture_count; Data() : grammar(std::make_shared()) @@ -1693,13 +1694,18 @@ private: const auto& name = sv[baseId].val.get(); auto ope = sv[baseId + 2].val.get>(); - auto& rule = (*data.grammar)[name]; - rule <= ope; - rule.name = name; - rule.ignoreSemanticValue = ignore; + auto& grammar = *data.grammar; + if (grammar.find(name) == grammar.end()) { + auto& rule = grammar[name]; + rule <= ope; + rule.name = name; + rule.ignoreSemanticValue = ignore; - if (data.start.empty()) { - data.start = name; + if (data.start.empty()) { + data.start = name; + } + } else { + data.duplicates.push_back(std::make_pair(name, sv.s)); } }; @@ -1868,9 +1874,19 @@ private: } } - // Check missing definitions - bool ret = true; + // Check duplicated definitions + bool ret = data.duplicates.empty();; + for (const auto& x: data.duplicates) { + if (log) { + const auto& name = x.first; + auto ptr = x.second; + auto line = line_info(s, ptr); + log(line.first, line.second, "'" + name + "' is already defined."); + } + } + + // Check missing definitions for (const auto& x : data.references) { const auto& name = x.first; auto ptr = x.second; diff --git a/test/test.cc b/test/test.cc index 834162a..111a7b4 100644 --- a/test/test.cc +++ b/test/test.cc @@ -565,6 +565,16 @@ TEST_CASE("Ignore semantic value of 'and' predicate test", "[general]") REQUIRE(ast->nodes[0]->name == "HELLO_WORLD"); } +TEST_CASE("Definition duplicates test", "[general]") +{ + peg parser( + " A <- ''" + " A <- ''" + ); + + REQUIRE(parser == false); +} + TEST_CASE("Left recursive test", "[left recursive]") { peg parser(