From 6584bfa5c6f49470bd516afba3a5df08a6d4e2be Mon Sep 17 00:00:00 2001 From: yhirose Date: Sat, 28 Jul 2018 21:51:11 -0400 Subject: [PATCH] Changed to setup is_token at a better place --- peglib.h | 37 +++++++++++++++++++------------------ test/test.cc | 26 +++++++++++++------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/peglib.h b/peglib.h index 6f31fa5..4560f1e 100644 --- a/peglib.h +++ b/peglib.h @@ -1605,17 +1605,17 @@ public: Definition() : ignoreSemanticValue(false) , enablePackratParsing(false) - , is_token(false) , is_macro(false) - , holder_(std::make_shared(this)) {} + , holder_(std::make_shared(this)) + , is_token_(false) {} Definition(const Definition& rhs) : name(rhs.name) , ignoreSemanticValue(false) , enablePackratParsing(false) - , is_token(false) , is_macro(false) , holder_(rhs.holder_) + , is_token_(false) { holder_->outer_ = this; } @@ -1626,9 +1626,9 @@ public: , whitespaceOpe(rhs.whitespaceOpe) , wordOpe(rhs.wordOpe) , enablePackratParsing(rhs.enablePackratParsing) - , is_token(rhs.is_token) , is_macro(rhs.is_macro) , holder_(std::move(rhs.holder_)) + , is_token_(rhs.is_token_) { holder_->outer_ = this; } @@ -1636,9 +1636,9 @@ public: Definition(const std::shared_ptr& ope) : ignoreSemanticValue(false) , enablePackratParsing(false) - , is_token(false) , is_macro(false) , holder_(std::make_shared(this)) + , is_token_(false) { *this <= ope; } @@ -1726,10 +1726,19 @@ public: holder_->accept(v); } - std::shared_ptr get_core_operator() { + std::shared_ptr get_core_operator() const { return holder_->ope_; } + bool is_token() const { + std::call_once(is_token_init_, [this]() { + TokenChecker vis; + get_core_operator()->accept(vis); + is_token_ = vis.is_token(); + }); + return is_token_; + } + std::string name; size_t id; Action action; @@ -1740,7 +1749,6 @@ public: std::shared_ptr whitespaceOpe; std::shared_ptr wordOpe; bool enablePackratParsing; - bool is_token; bool is_macro; std::vector params; Tracer tracer; @@ -1766,6 +1774,8 @@ private: } std::shared_ptr holder_; + mutable std::once_flag is_token_init_; + mutable bool is_token_; }; /* @@ -2476,14 +2486,6 @@ private: return nullptr; } - // Token check - for (auto& x: grammar) { - auto& rule = x.second; - TokenChecker vis; - rule.get_core_operator()->accept(vis); - rule.is_token = vis.is_token(); - } - // Set root definition start = data.start; @@ -2879,11 +2881,10 @@ public: auto& rule = x.second; if (!rule.action) { - auto is_token = rule.is_token; - rule.action = [=](const SemanticValues& sv) { + rule.action = [&](const SemanticValues& sv) { auto line = line_info(sv.ss, sv.c_str()); - if (is_token) { + if (rule.is_token()) { return std::make_shared(sv.path, line.first, line.second, name.c_str(), sv.token()); } diff --git a/test/test.cc b/test/test.cc index 76236b7..86a853f 100644 --- a/test/test.cc +++ b/test/test.cc @@ -142,11 +142,11 @@ TEST_CASE("Token check test", "[general]") " _ <- [ \t\r\n]* " ); - REQUIRE(parser["EXPRESSION"].is_token == false); - REQUIRE(parser["FACTOR"].is_token == false); - REQUIRE(parser["FACTOR_OPERATOR"].is_token == true); - REQUIRE(parser["NUMBER"].is_token == true); - REQUIRE(parser["_"].is_token == true); + REQUIRE(parser["EXPRESSION"].is_token() == false); + REQUIRE(parser["FACTOR"].is_token() == false); + REQUIRE(parser["FACTOR_OPERATOR"].is_token() == true); + REQUIRE(parser["NUMBER"].is_token() == true); + REQUIRE(parser["_"].is_token() == true); } TEST_CASE("Lambda action test", "[general]") @@ -1144,14 +1144,14 @@ TEST_CASE("Macro token check test", "[macro]") T(S) <- < S > _ )"); - REQUIRE(parser["EXPRESSION"].is_token == false); - REQUIRE(parser["TERM"].is_token == false); - REQUIRE(parser["FACTOR"].is_token == false); - REQUIRE(parser["FACTOR_OPERATOR"].is_token == true); - REQUIRE(parser["NUMBER"].is_token == true); - REQUIRE(parser["_"].is_token == true); - REQUIRE(parser["LIST"].is_token == false); - REQUIRE(parser["T"].is_token == true); + REQUIRE(parser["EXPRESSION"].is_token() == false); + REQUIRE(parser["TERM"].is_token() == false); + REQUIRE(parser["FACTOR"].is_token() == false); + REQUIRE(parser["FACTOR_OPERATOR"].is_token() == true); + REQUIRE(parser["NUMBER"].is_token() == true); + REQUIRE(parser["_"].is_token() == true); + REQUIRE(parser["LIST"].is_token() == false); + REQUIRE(parser["T"].is_token() == true); } TEST_CASE("Line information test", "[line information]")