Changed to setup is_token at a better place

pull/48/head
yhirose 6 years ago
parent 6f9d19463d
commit 6584bfa5c6
  1. 37
      peglib.h
  2. 26
      test/test.cc

@ -1605,17 +1605,17 @@ public:
Definition() Definition()
: ignoreSemanticValue(false) : ignoreSemanticValue(false)
, enablePackratParsing(false) , enablePackratParsing(false)
, is_token(false)
, is_macro(false) , is_macro(false)
, holder_(std::make_shared<Holder>(this)) {} , holder_(std::make_shared<Holder>(this))
, is_token_(false) {}
Definition(const Definition& rhs) Definition(const Definition& rhs)
: name(rhs.name) : name(rhs.name)
, ignoreSemanticValue(false) , ignoreSemanticValue(false)
, enablePackratParsing(false) , enablePackratParsing(false)
, is_token(false)
, is_macro(false) , is_macro(false)
, holder_(rhs.holder_) , holder_(rhs.holder_)
, is_token_(false)
{ {
holder_->outer_ = this; holder_->outer_ = this;
} }
@ -1626,9 +1626,9 @@ public:
, whitespaceOpe(rhs.whitespaceOpe) , whitespaceOpe(rhs.whitespaceOpe)
, wordOpe(rhs.wordOpe) , wordOpe(rhs.wordOpe)
, enablePackratParsing(rhs.enablePackratParsing) , enablePackratParsing(rhs.enablePackratParsing)
, is_token(rhs.is_token)
, is_macro(rhs.is_macro) , is_macro(rhs.is_macro)
, holder_(std::move(rhs.holder_)) , holder_(std::move(rhs.holder_))
, is_token_(rhs.is_token_)
{ {
holder_->outer_ = this; holder_->outer_ = this;
} }
@ -1636,9 +1636,9 @@ public:
Definition(const std::shared_ptr<Ope>& ope) Definition(const std::shared_ptr<Ope>& ope)
: ignoreSemanticValue(false) : ignoreSemanticValue(false)
, enablePackratParsing(false) , enablePackratParsing(false)
, is_token(false)
, is_macro(false) , is_macro(false)
, holder_(std::make_shared<Holder>(this)) , holder_(std::make_shared<Holder>(this))
, is_token_(false)
{ {
*this <= ope; *this <= ope;
} }
@ -1726,10 +1726,19 @@ public:
holder_->accept(v); holder_->accept(v);
} }
std::shared_ptr<Ope> get_core_operator() { std::shared_ptr<Ope> get_core_operator() const {
return holder_->ope_; 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; std::string name;
size_t id; size_t id;
Action action; Action action;
@ -1740,7 +1749,6 @@ public:
std::shared_ptr<Ope> whitespaceOpe; std::shared_ptr<Ope> whitespaceOpe;
std::shared_ptr<Ope> wordOpe; std::shared_ptr<Ope> wordOpe;
bool enablePackratParsing; bool enablePackratParsing;
bool is_token;
bool is_macro; bool is_macro;
std::vector<std::string> params; std::vector<std::string> params;
Tracer tracer; Tracer tracer;
@ -1766,6 +1774,8 @@ private:
} }
std::shared_ptr<Holder> holder_; std::shared_ptr<Holder> holder_;
mutable std::once_flag is_token_init_;
mutable bool is_token_;
}; };
/* /*
@ -2476,14 +2486,6 @@ private:
return nullptr; 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 // Set root definition
start = data.start; start = data.start;
@ -2879,11 +2881,10 @@ public:
auto& rule = x.second; auto& rule = x.second;
if (!rule.action) { 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()); auto line = line_info(sv.ss, sv.c_str());
if (is_token) { if (rule.is_token()) {
return std::make_shared<T>(sv.path, line.first, line.second, name.c_str(), sv.token()); return std::make_shared<T>(sv.path, line.first, line.second, name.c_str(), sv.token());
} }

@ -142,11 +142,11 @@ TEST_CASE("Token check test", "[general]")
" _ <- [ \t\r\n]* " " _ <- [ \t\r\n]* "
); );
REQUIRE(parser["EXPRESSION"].is_token == false); REQUIRE(parser["EXPRESSION"].is_token() == false);
REQUIRE(parser["FACTOR"].is_token == false); REQUIRE(parser["FACTOR"].is_token() == false);
REQUIRE(parser["FACTOR_OPERATOR"].is_token == true); REQUIRE(parser["FACTOR_OPERATOR"].is_token() == true);
REQUIRE(parser["NUMBER"].is_token == true); REQUIRE(parser["NUMBER"].is_token() == true);
REQUIRE(parser["_"].is_token == true); REQUIRE(parser["_"].is_token() == true);
} }
TEST_CASE("Lambda action test", "[general]") TEST_CASE("Lambda action test", "[general]")
@ -1144,14 +1144,14 @@ TEST_CASE("Macro token check test", "[macro]")
T(S) <- < S > _ T(S) <- < S > _
)"); )");
REQUIRE(parser["EXPRESSION"].is_token == false); REQUIRE(parser["EXPRESSION"].is_token() == false);
REQUIRE(parser["TERM"].is_token == false); REQUIRE(parser["TERM"].is_token() == false);
REQUIRE(parser["FACTOR"].is_token == false); REQUIRE(parser["FACTOR"].is_token() == false);
REQUIRE(parser["FACTOR_OPERATOR"].is_token == true); REQUIRE(parser["FACTOR_OPERATOR"].is_token() == true);
REQUIRE(parser["NUMBER"].is_token == true); REQUIRE(parser["NUMBER"].is_token() == true);
REQUIRE(parser["_"].is_token == true); REQUIRE(parser["_"].is_token() == true);
REQUIRE(parser["LIST"].is_token == false); REQUIRE(parser["LIST"].is_token() == false);
REQUIRE(parser["T"].is_token == true); REQUIRE(parser["T"].is_token() == true);
} }
TEST_CASE("Line information test", "[line information]") TEST_CASE("Line information test", "[line information]")

Loading…
Cancel
Save