From 261f8f463b362bc2f537d890b20c7b8940eefe50 Mon Sep 17 00:00:00 2001 From: yhirose Date: Wed, 18 Feb 2015 22:28:57 -0500 Subject: [PATCH] Added 'const SemanticValues&` action. --- README.md | 16 +++++++++- peglib.h | 96 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 88 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 7c69d3b..eac751c 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,8 @@ Here is a complete list of available actions: [](const std::vector& v, any& c) [](const std::vector& v) []() +[](const SemanticValues& v, any& c) +[](const SemanticValues& v) ``` `const char* s, size_t l` gives a pointer and length of the matched string. @@ -90,7 +92,19 @@ Here is a complete list of available actions: `any& c` is a context data which can be used by the user for whatever purposes. -The following example uses `<` and ` >` operators. They are the *anchor* operators. Each anchor operator creates a semantic value that contains `const char*` of the position. It could be useful to eliminate unnecessary characters. +`const SemanticValues&` is also available. `SemanticValues` structure contains all of above information as well as the vector of definition names of semantic values. + +```c++ +struct SemanticValues +{ + std::vector values; // Semantic value + std::vector names; // Definition name + const char* s; // Token start + size_t l; // Token length +}; +``` + +The following example uses `<` ... ` >` operators. They are the *anchor* operators. Each anchor operator creates a semantic value that contains `const char*` of the position. It could be useful to eliminate unnecessary characters. ```c++ auto syntax = R"( diff --git a/peglib.h b/peglib.h index 8114099..ef66060 100644 --- a/peglib.h +++ b/peglib.h @@ -155,7 +155,7 @@ private: struct SemanticValues { std::vector values; - //std::vector names; + std::vector names; const char* s; size_t l; @@ -217,17 +217,37 @@ public: return (bool)fn_; } - any operator()(const char* s, size_t l, const std::vector& v, any& c) const { + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) const { return fn_(s, l, v, c); } private: template struct TypeAdaptor { - TypeAdaptor(std::function& v, any& c)> fn) + TypeAdaptor(std::function fn) : fn_(fn) {} - any operator()(const char* s, size_t l, const std::vector& v, any& c) { - return call(fn_, s, l, v, c); + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) { + return call(fn_, v); + } + std::function fn_; + }; + + template + struct TypeAdaptor_c { + TypeAdaptor_c(std::function fn) + : fn_(fn) {} + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) { + return call(fn_, v, c); + } + std::function fn_; + }; + + template + struct TypeAdaptor_s_l_v_c { + TypeAdaptor_s_l_v_c(std::function& v, any& c)> fn) + : fn_(fn) {} + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) { + return call(fn_, s, l, v.values, c); } std::function& v, any& c)> fn_; }; @@ -236,8 +256,8 @@ private: struct TypeAdaptor_s_l_v { TypeAdaptor_s_l_v(std::function& v)> fn) : fn_(fn) {} - any operator()(const char* s, size_t l, const std::vector& v, any& c) { - return call(fn_, s, l, v); + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) { + return call(fn_, s, l, v.values); } std::function& v)> fn_; }; @@ -245,7 +265,7 @@ private: template struct TypeAdaptor_s_l { TypeAdaptor_s_l(std::function fn) : fn_(fn) {} - any operator()(const char* s, size_t l, const std::vector& v, any& c) { + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) { return call(fn_, s, l); } std::function fn_; @@ -254,8 +274,8 @@ private: template struct TypeAdaptor_v_n { TypeAdaptor_v_n(std::function& v, any& c)> fn) : fn_(fn) {} - any operator()(const char* s, size_t l, const std::vector& v, any& c) { - return call(fn_, v, c); + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) { + return call(fn_, v.values, c); } std::function& v, any& c)> fn_; }; @@ -263,8 +283,8 @@ private: template struct TypeAdaptor_v { TypeAdaptor_v(std::function& v)> fn) : fn_(fn) {} - any operator()(const char* s, size_t l, const std::vector& v, any& c) { - return call(fn_, v); + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) { + return call(fn_, v.values); } std::function& v)> fn_; }; @@ -272,27 +292,57 @@ private: template struct TypeAdaptor_empty { TypeAdaptor_empty(std::function fn) : fn_(fn) {} - any operator()(const char* s, size_t l, const std::vector& v, any& c) { + any operator()(const char* s, size_t l, const SemanticValues& v, any& c) { return call(fn_); } std::function fn_; }; - typedef std::function& v, any& c)> Fty; + typedef std::function Fty; + + template + Fty make_adaptor(F fn, R (F::*mf)(const SemanticValues& v) const) { + return TypeAdaptor(fn); + } + + template + Fty make_adaptor(F fn, R (F::*mf)(const SemanticValues& v)) { + return TypeAdaptor(fn); + } + + template + Fty make_adaptor(F fn, R(*mf)(const SemanticValues& v)) { + return TypeAdaptor(fn); + } + + template + Fty make_adaptor(F fn, R (F::*mf)(const SemanticValues& v, any& c) const) { + return TypeAdaptor_c(fn); + } + + template + Fty make_adaptor(F fn, R (F::*mf)(const SemanticValues& v, any& c)) { + return TypeAdaptor_c(fn); + } + + template + Fty make_adaptor(F fn, R(*mf)(const SemanticValues& v, any& c)) { + return TypeAdaptor_c(fn); + } template Fty make_adaptor(F fn, R (F::*mf)(const char*, size_t, const std::vector& v, any& c) const) { - return TypeAdaptor(fn); + return TypeAdaptor_s_l_v_c(fn); } template Fty make_adaptor(F fn, R (F::*mf)(const char*, size_t, const std::vector& v, any& c)) { - return TypeAdaptor(fn); + return TypeAdaptor_s_l_v_c(fn); } template Fty make_adaptor(F fn, R(*mf)(const char*, size_t, const std::vector& v, any& c)) { - return TypeAdaptor(fn); + return TypeAdaptor_s_l_v_c(fn); } template @@ -482,10 +532,10 @@ public: SemanticValues chldsv; auto r = rule.parse(s, l, chldsv, c); if (r.ret) { - //assert(chldsv.values.size() == chldsv.names.size()); + assert(chldsv.values.size() == chldsv.names.size()); if (!chldsv.values.empty()) { v.values.insert(v.values.end(), chldsv.values.begin(), chldsv.values.end()); - //v.names.insert(v.names.end(), chldsv.names.begin(), chldsv.names.end()); + v.names.insert(v.names.end(), chldsv.names.begin(), chldsv.names.end()); } v.s = chldsv.s; v.l = chldsv.l; @@ -868,16 +918,16 @@ private: assert(!outer_->actions.empty()); auto id = r.choice + 1; - const auto& ac = (id < outer_->actions.size() && outer_->actions[id]) + const auto& action = (id < outer_->actions.size() && outer_->actions[id]) ? outer_->actions[id] : outer_->actions[0]; auto ts = chldsv.s ? chldsv.s : s; auto tl = chldsv.s ? chldsv.l : r.len; - auto sv = reduce(ts, tl, chldsv, c, ac); + auto sv = reduce(ts, tl, chldsv, c, action); v.values.push_back(sv); - //v.names.push_back(outer_->name); + v.names.push_back(outer_->name); } return r; } @@ -887,7 +937,7 @@ private: any reduce(const char* s, size_t l, const SemanticValues& v, any& c, const Action& action) const { if (action) { - return action(s, l, v.values, c); + return action(s, l, v, c); } else if (v.values.empty()) { return any(); } else {