fix #52. Changed to allow Action handler taking non const SemanticValues

parameter
pull/58/head
yhirose 6 years ago
parent 5b3ad705c4
commit 757e81e63d
  1. 84
      peglib.h
  2. 23
      test/test.cc

@ -599,61 +599,111 @@ public:
return bool(fn_); return bool(fn_);
} }
any operator()(const SemanticValues& sv, any& dt) const { any operator()(SemanticValues& sv, any& dt) const {
return fn_(sv, dt); return fn_(sv, dt);
} }
private: private:
template <typename R> template <typename R>
struct TypeAdaptor { struct TypeAdaptor_sv {
TypeAdaptor(std::function<R (const SemanticValues& sv)> fn) TypeAdaptor_sv(std::function<R (SemanticValues& sv)> fn)
: fn_(fn) {} : fn_(fn) {}
any operator()(const SemanticValues& sv, any& /*dt*/) { any operator()(SemanticValues& sv, any& /*dt*/) {
return call<R>(fn_, sv);
}
std::function<R (SemanticValues& sv)> fn_;
};
template <typename R>
struct TypeAdaptor_csv {
TypeAdaptor_csv(std::function<R (const SemanticValues& sv)> fn)
: fn_(fn) {}
any operator()(SemanticValues& sv, any& /*dt*/) {
return call<R>(fn_, sv); return call<R>(fn_, sv);
} }
std::function<R (const SemanticValues& sv)> fn_; std::function<R (const SemanticValues& sv)> fn_;
}; };
template <typename R> template <typename R>
struct TypeAdaptor_c { struct TypeAdaptor_sv_dt {
TypeAdaptor_c(std::function<R (const SemanticValues& sv, any& dt)> fn) TypeAdaptor_sv_dt(std::function<R (SemanticValues& sv, any& dt)> fn)
: fn_(fn) {} : fn_(fn) {}
any operator()(const SemanticValues& sv, any& dt) { any operator()(SemanticValues& sv, any& dt) {
return call<R>(fn_, sv, dt);
}
std::function<R (SemanticValues& sv, any& dt)> fn_;
};
template <typename R>
struct TypeAdaptor_csv_dt {
TypeAdaptor_csv_dt(std::function<R (const SemanticValues& sv, any& dt)> fn)
: fn_(fn) {}
any operator()(SemanticValues& sv, any& dt) {
return call<R>(fn_, sv, dt); return call<R>(fn_, sv, dt);
} }
std::function<R (const SemanticValues& sv, any& dt)> fn_; std::function<R (const SemanticValues& sv, any& dt)> fn_;
}; };
typedef std::function<any (const SemanticValues& sv, any& dt)> Fty; typedef std::function<any (SemanticValues& sv, any& dt)> Fty;
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(SemanticValues& sv) const) {
return TypeAdaptor_sv<R>(fn);
}
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv) const) { Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv) const) {
return TypeAdaptor<R>(fn); return TypeAdaptor_csv<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(SemanticValues& sv)) {
return TypeAdaptor_sv<R>(fn);
} }
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv)) { Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv)) {
return TypeAdaptor<R>(fn); return TypeAdaptor_csv<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R (* /*mf*/)(SemanticValues& sv)) {
return TypeAdaptor_sv<R>(fn);
} }
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R (* /*mf*/)(const SemanticValues& sv)) { Fty make_adaptor(F fn, R (* /*mf*/)(const SemanticValues& sv)) {
return TypeAdaptor<R>(fn); return TypeAdaptor_csv<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(SemanticValues& sv, any& dt) const) {
return TypeAdaptor_sv_dt<R>(fn);
} }
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv, any& dt) const) { Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv, any& dt) const) {
return TypeAdaptor_c<R>(fn); return TypeAdaptor_csv_dt<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(SemanticValues& sv, any& dt)) {
return TypeAdaptor_sv_dt<R>(fn);
} }
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv, any& dt)) { Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv, any& dt)) {
return TypeAdaptor_c<R>(fn); return TypeAdaptor_csv_dt<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R(* /*mf*/)(SemanticValues& sv, any& dt)) {
return TypeAdaptor_sv_dt<R>(fn);
} }
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R(* /*mf*/)(const SemanticValues& sv, any& dt)) { Fty make_adaptor(F fn, R(* /*mf*/)(const SemanticValues& sv, any& dt)) {
return TypeAdaptor_c<R>(fn); return TypeAdaptor_csv_dt<R>(fn);
} }
Fty fn_; Fty fn_;
@ -1387,7 +1437,7 @@ public:
void accept(Visitor& v) override; void accept(Visitor& v) override;
any reduce(const SemanticValues& sv, any& dt) const; any reduce(SemanticValues& sv, any& dt) const;
std::shared_ptr<Ope> ope_; std::shared_ptr<Ope> ope_;
Definition* outer_; Definition* outer_;
@ -2177,13 +2227,13 @@ inline size_t Holder::parse(const char* s, size_t n, SemanticValues& sv, Context
return len; return len;
} }
inline any Holder::reduce(const SemanticValues& sv, any& dt) const { inline any Holder::reduce(SemanticValues& sv, any& dt) const {
if (outer_->action) { if (outer_->action) {
return outer_->action(sv, dt); return outer_->action(sv, dt);
} else if (sv.empty()) { } else if (sv.empty()) {
return any(); return any();
} else { } else {
return sv.front(); return std::move(sv.front());
} }
} }

@ -36,6 +36,29 @@ TEST_CASE("Empty syntax test", "[general]")
REQUIRE(ret == false); REQUIRE(ret == false);
} }
TEST_CASE("Action taking non const Semantic Values parameter", "[general]")
{
peg::parser parser(R"(
ROOT <- TEXT
TEXT <- [a-zA-Z]+
)");
parser["ROOT"] = [&](peg::SemanticValues& sv) {
auto& s = sv[0].get<std::string>();
s[0] = 'H'; // mutate
return std::string(std::move(s)); // move
};
parser["TEXT"] = [&](peg::SemanticValues& sv) {
return sv.token();
};
std::string val;
auto ret = parser.parse("hello", val);
REQUIRE(ret == true);
REQUIRE(val == "Hello");
}
TEST_CASE("String capture test", "[general]") TEST_CASE("String capture test", "[general]")
{ {
peg::parser parser( peg::parser parser(

Loading…
Cancel
Save