mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +00:00
Added 'const SemanticValues&` action.
This commit is contained in:
parent
f87ae01d3b
commit
261f8f463b
16
README.md
16
README.md
@ -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"(
|
||||||
|
96
peglib.h
96
peglib.h
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user