Added 'const SemanticValues&` action.

This commit is contained in:
yhirose 2015-02-18 22:28:57 -05:00
parent f87ae01d3b
commit 261f8f463b
2 changed files with 88 additions and 24 deletions

View File

@ -82,6 +82,8 @@ Here is a complete list of available actions:
[](const std::vector<peglib::any>& v, any& c) [](const std::vector<peglib::any>& v, any& c)
[](const std::vector<peglib::any>& v) [](const std::vector<peglib::any>& v)
[]() []()
[](const SemanticValues& v, any& c)
[](const SemanticValues& v)
``` ```
`const char* s, size_t l` gives a pointer and length of the matched string. `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. `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<any> values; // Semantic value
std::vector<std::string> 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++ ```c++
auto syntax = R"( auto syntax = R"(

View File

@ -155,7 +155,7 @@ private:
struct SemanticValues struct SemanticValues
{ {
std::vector<any> values; std::vector<any> values;
//std::vector<std::string> names; std::vector<std::string> names;
const char* s; const char* s;
size_t l; size_t l;
@ -217,17 +217,37 @@ public:
return (bool)fn_; return (bool)fn_;
} }
any operator()(const char* s, size_t l, const std::vector<any>& v, any& c) const { any operator()(const char* s, size_t l, const SemanticValues& v, any& c) const {
return fn_(s, l, v, c); return fn_(s, l, v, c);
} }
private: private:
template <typename R> template <typename R>
struct TypeAdaptor { struct TypeAdaptor {
TypeAdaptor(std::function<R (const char* s, size_t l, const std::vector<any>& v, any& c)> fn) TypeAdaptor(std::function<R (const SemanticValues& v)> fn)
: fn_(fn) {} : fn_(fn) {}
any operator()(const char* s, size_t l, const std::vector<any>& v, any& c) { any operator()(const char* s, size_t l, const SemanticValues& v, any& c) {
return call<R>(fn_, s, l, v, c); return call<R>(fn_, v);
}
std::function<R (const SemanticValues& v)> fn_;
};
template <typename R>
struct TypeAdaptor_c {
TypeAdaptor_c(std::function<R (const SemanticValues& v, any& c)> fn)
: fn_(fn) {}
any operator()(const char* s, size_t l, const SemanticValues& v, any& c) {
return call<R>(fn_, v, c);
}
std::function<R (const SemanticValues& v, any& c)> fn_;
};
template <typename R>
struct TypeAdaptor_s_l_v_c {
TypeAdaptor_s_l_v_c(std::function<R (const char* s, size_t l, const std::vector<any>& v, any& c)> fn)
: fn_(fn) {}
any operator()(const char* s, size_t l, const SemanticValues& v, any& c) {
return call<R>(fn_, s, l, v.values, c);
} }
std::function<R (const char* s, size_t l, const std::vector<any>& v, any& c)> fn_; std::function<R (const char* s, size_t l, const std::vector<any>& v, any& c)> fn_;
}; };
@ -236,8 +256,8 @@ private:
struct TypeAdaptor_s_l_v { struct TypeAdaptor_s_l_v {
TypeAdaptor_s_l_v(std::function<R (const char* s, size_t l, const std::vector<any>& v)> fn) TypeAdaptor_s_l_v(std::function<R (const char* s, size_t l, const std::vector<any>& v)> fn)
: fn_(fn) {} : fn_(fn) {}
any operator()(const char* s, size_t l, const std::vector<any>& v, any& c) { any operator()(const char* s, size_t l, const SemanticValues& v, any& c) {
return call<R>(fn_, s, l, v); return call<R>(fn_, s, l, v.values);
} }
std::function<R (const char* s, size_t l, const std::vector<any>& v)> fn_; std::function<R (const char* s, size_t l, const std::vector<any>& v)> fn_;
}; };
@ -245,7 +265,7 @@ private:
template <typename R> template <typename R>
struct TypeAdaptor_s_l { struct TypeAdaptor_s_l {
TypeAdaptor_s_l(std::function<R (const char* s, size_t l)> fn) : fn_(fn) {} TypeAdaptor_s_l(std::function<R (const char* s, size_t l)> fn) : fn_(fn) {}
any operator()(const char* s, size_t l, const std::vector<any>& v, any& c) { any operator()(const char* s, size_t l, const SemanticValues& v, any& c) {
return call<R>(fn_, s, l); return call<R>(fn_, s, l);
} }
std::function<R (const char* s, size_t l)> fn_; std::function<R (const char* s, size_t l)> fn_;
@ -254,8 +274,8 @@ private:
template <typename R> template <typename R>
struct TypeAdaptor_v_n { struct TypeAdaptor_v_n {
TypeAdaptor_v_n(std::function<R (const std::vector<any>& v, any& c)> fn) : fn_(fn) {} TypeAdaptor_v_n(std::function<R (const std::vector<any>& v, any& c)> fn) : fn_(fn) {}
any operator()(const char* s, size_t l, const std::vector<any>& v, any& c) { any operator()(const char* s, size_t l, const SemanticValues& v, any& c) {
return call<R>(fn_, v, c); return call<R>(fn_, v.values, c);
} }
std::function<R (const std::vector<any>& v, any& c)> fn_; std::function<R (const std::vector<any>& v, any& c)> fn_;
}; };
@ -263,8 +283,8 @@ private:
template <typename R> template <typename R>
struct TypeAdaptor_v { struct TypeAdaptor_v {
TypeAdaptor_v(std::function<R (const std::vector<any>& v)> fn) : fn_(fn) {} TypeAdaptor_v(std::function<R (const std::vector<any>& v)> fn) : fn_(fn) {}
any operator()(const char* s, size_t l, const std::vector<any>& v, any& c) { any operator()(const char* s, size_t l, const SemanticValues& v, any& c) {
return call<R>(fn_, v); return call<R>(fn_, v.values);
} }
std::function<R (const std::vector<any>& v)> fn_; std::function<R (const std::vector<any>& v)> fn_;
}; };
@ -272,27 +292,57 @@ private:
template <typename R> template <typename R>
struct TypeAdaptor_empty { struct TypeAdaptor_empty {
TypeAdaptor_empty(std::function<R ()> fn) : fn_(fn) {} TypeAdaptor_empty(std::function<R ()> fn) : fn_(fn) {}
any operator()(const char* s, size_t l, const std::vector<any>& v, any& c) { any operator()(const char* s, size_t l, const SemanticValues& v, any& c) {
return call<R>(fn_); return call<R>(fn_);
} }
std::function<R ()> fn_; std::function<R ()> fn_;
}; };
typedef std::function<any (const char* s, size_t l, const std::vector<any>& v, any& c)> Fty; typedef std::function<any (const char* s, size_t l, const SemanticValues& v, any& c)> Fty;
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::*mf)(const SemanticValues& v) const) {
return TypeAdaptor<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::*mf)(const SemanticValues& v)) {
return TypeAdaptor<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R(*mf)(const SemanticValues& v)) {
return TypeAdaptor<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::*mf)(const SemanticValues& v, any& c) const) {
return TypeAdaptor_c<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R (F::*mf)(const SemanticValues& v, any& c)) {
return TypeAdaptor_c<R>(fn);
}
template<typename F, typename R>
Fty make_adaptor(F fn, R(*mf)(const SemanticValues& v, any& c)) {
return TypeAdaptor_c<R>(fn);
}
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R (F::*mf)(const char*, size_t, const std::vector<any>& v, any& c) const) { Fty make_adaptor(F fn, R (F::*mf)(const char*, size_t, const std::vector<any>& v, any& c) const) {
return TypeAdaptor<R>(fn); return TypeAdaptor_s_l_v_c<R>(fn);
} }
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R (F::*mf)(const char*, size_t, const std::vector<any>& v, any& c)) { Fty make_adaptor(F fn, R (F::*mf)(const char*, size_t, const std::vector<any>& v, any& c)) {
return TypeAdaptor<R>(fn); return TypeAdaptor_s_l_v_c<R>(fn);
} }
template<typename F, typename R> template<typename F, typename R>
Fty make_adaptor(F fn, R(*mf)(const char*, size_t, const std::vector<any>& v, any& c)) { Fty make_adaptor(F fn, R(*mf)(const char*, size_t, const std::vector<any>& v, any& c)) {
return TypeAdaptor<R>(fn); return TypeAdaptor_s_l_v_c<R>(fn);
} }
template<typename F, typename R> template<typename F, typename R>
@ -482,10 +532,10 @@ public:
SemanticValues chldsv; SemanticValues chldsv;
auto r = rule.parse(s, l, chldsv, c); auto r = rule.parse(s, l, chldsv, c);
if (r.ret) { if (r.ret) {
//assert(chldsv.values.size() == chldsv.names.size()); assert(chldsv.values.size() == chldsv.names.size());
if (!chldsv.values.empty()) { if (!chldsv.values.empty()) {
v.values.insert(v.values.end(), chldsv.values.begin(), chldsv.values.end()); 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.s = chldsv.s;
v.l = chldsv.l; v.l = chldsv.l;
@ -868,16 +918,16 @@ private:
assert(!outer_->actions.empty()); assert(!outer_->actions.empty());
auto id = r.choice + 1; 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[id]
: outer_->actions[0]; : outer_->actions[0];
auto ts = chldsv.s ? chldsv.s : s; auto ts = chldsv.s ? chldsv.s : s;
auto tl = chldsv.s ? chldsv.l : r.len; 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.values.push_back(sv);
//v.names.push_back(outer_->name); v.names.push_back(outer_->name);
} }
return r; return r;
} }
@ -887,7 +937,7 @@ private:
any reduce(const char* s, size_t l, const SemanticValues& v, any& c, const Action& action) const { any reduce(const char* s, size_t l, const SemanticValues& v, any& c, const Action& action) const {
if (action) { if (action) {
return action(s, l, v.values, c); return action(s, l, v, c);
} else if (v.values.empty()) { } else if (v.values.empty()) {
return any(); return any();
} else { } else {