mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +00:00
Changed to allow simpler notation in actions.
This commit is contained in:
parent
8acb0e2822
commit
4202e6d111
@ -97,7 +97,7 @@ assert(val == -3);
|
|||||||
|
|
||||||
It may be helpful to keep in mind that the action behavior is similar to the YACC semantic action model ($$, $1, $2, ...).
|
It may be helpful to keep in mind that the action behavior is similar to the YACC semantic action model ($$, $1, $2, ...).
|
||||||
|
|
||||||
In this example, the actions return values. These samentic values will be pushed up to the parent definition which can be referred to in the parent action `[](const vector<Any>& v)`. In other words, when a certain definition has been accepted, we can find all semantic values which are associated with the child definitions in `const vector<Any>& v`. The values are wrapped by peblib::Any class which is like `boost::any`. We can retrieve the value by using `get<T>` method where `T` is the actual type of the value. If no value is returned in an action, an undefined `Any` will be pushed up to the parent. Finally, the resulting value of the root definition is received in the out parameter of `parse` method in the parser. `long val` is the resulting value in this case.
|
In this example, the actions return values. These samentic values will be pushed up to the parent definition which can be referred to in the parent action `[](const vector<Any>& v)`. In other words, when a certain definition has been accepted, we can find all semantic values which are associated with the child definitions in `const vector<Any>& v`. The values are wrapped by peglib::Any class which is like `boost::any`. We can retrieve the value by using `get<T>` method where `T` is the actual type of the value. If no value is returned in an action, an undefined `Any` will be pushed up to the parent. Finally, the resulting value of the root definition is received in the out parameter of `parse` method in the parser. `long val` is the resulting value in this case.
|
||||||
|
|
||||||
Here are available user actions:
|
Here are available user actions:
|
||||||
|
|
||||||
|
35
peglib.h
35
peglib.h
@ -115,15 +115,24 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const std::string&() const {
|
|
||||||
return get<std::string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator std::string&() {
|
|
||||||
return get<std::string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add more implecit cast operators
|
// TODO: Add more implecit cast operators
|
||||||
|
operator bool() const { return get<bool>(); }
|
||||||
|
operator char() const { return get<char>(); }
|
||||||
|
operator wchar_t() const { return get<wchar_t>(); }
|
||||||
|
operator char16_t() const { return get<char16_t>(); }
|
||||||
|
operator char32_t() const { return get<char32_t>(); }
|
||||||
|
operator unsigned char() const { return get<unsigned char>(); }
|
||||||
|
operator int() const { return get<int>(); }
|
||||||
|
operator unsigned int() const { return get<unsigned int>(); }
|
||||||
|
operator short() const { return get<short>(); }
|
||||||
|
operator unsigned short() const { return get<unsigned short>(); }
|
||||||
|
operator long() const { return get<long>(); }
|
||||||
|
operator unsigned long() const { return get<unsigned long>(); }
|
||||||
|
operator long long() const { return get<long long>(); }
|
||||||
|
operator unsigned long long() const { return get<unsigned long long>(); }
|
||||||
|
operator float() const { return get<float>(); }
|
||||||
|
operator double() const { return get<double>(); }
|
||||||
|
operator const std::string&() const { return get<std::string>(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct placeholder {
|
struct placeholder {
|
||||||
@ -189,13 +198,16 @@ public:
|
|||||||
|
|
||||||
//Action(Action&& rhs) : fn_(std::move(rhs.fn_)) {}
|
//Action(Action&& rhs) : fn_(std::move(rhs.fn_)) {}
|
||||||
|
|
||||||
template <typename F, typename std::enable_if<!std::is_pointer<F>::value>::type*& = enabler>
|
template <typename F, typename std::enable_if<!std::is_pointer<F>::value && !std::is_null_pointer<F>::value>::type*& = enabler>
|
||||||
Action(F fn) : fn_(make_adaptor(fn, &F::operator())) {}
|
Action(F fn) : fn_(make_adaptor(fn, &F::operator())) {}
|
||||||
|
|
||||||
template <typename F, typename std::enable_if<std::is_pointer<F>::value>::type*& = enabler>
|
template <typename F, typename std::enable_if<std::is_pointer<F>::value>::type*& = enabler>
|
||||||
Action(F fn) : fn_(make_adaptor(fn, fn)) {}
|
Action(F fn) : fn_(make_adaptor(fn, fn)) {}
|
||||||
|
|
||||||
template <typename F, typename std::enable_if<!std::is_pointer<F>::value>::type*& = enabler>
|
template <typename F, typename std::enable_if<std::is_null_pointer<F>::value>::type*& = enabler>
|
||||||
|
Action(F fn) {}
|
||||||
|
|
||||||
|
template <typename F, typename std::enable_if<!std::is_pointer<F>::value && !std::is_null_pointer<F>::value>::type*& = enabler>
|
||||||
void operator=(F fn) {
|
void operator=(F fn) {
|
||||||
fn_ = make_adaptor(fn, &F::operator());
|
fn_ = make_adaptor(fn, &F::operator());
|
||||||
}
|
}
|
||||||
@ -205,6 +217,9 @@ public:
|
|||||||
fn_ = make_adaptor(fn, fn);
|
fn_ = make_adaptor(fn, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename F, typename std::enable_if<std::is_null_pointer<F>::value>::type*& = enabler>
|
||||||
|
void operator=(F fn) {}
|
||||||
|
|
||||||
operator bool() const {
|
operator bool() const {
|
||||||
return (bool)fn_;
|
return (bool)fn_;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ TEST_CASE("Simple calculator test", "[general]")
|
|||||||
|
|
||||||
parser["Additive"] = {
|
parser["Additive"] = {
|
||||||
// Default action
|
// Default action
|
||||||
[]() {},
|
nullptr,
|
||||||
// Action for the first choice
|
// Action for the first choice
|
||||||
[](const vector<Any>& v) { return v[0].get<int>() + v[1].get<int>(); },
|
[](const vector<Any>& v) { return v[0].get<int>() + v[1].get<int>(); },
|
||||||
// Action for the second choice
|
// Action for the second choice
|
||||||
@ -139,7 +139,7 @@ TEST_CASE("Simple calculator test", "[general]")
|
|||||||
};
|
};
|
||||||
|
|
||||||
parser["Multitive"] = [](const vector<Any>& v) {
|
parser["Multitive"] = [](const vector<Any>& v) {
|
||||||
return v.size() == 1 ? v[0] : v[0].get<int>() * v[1].get<int>();
|
return v.size() == 1 ? int(v[0]) : v[0].get<int>() * v[1].get<int>();
|
||||||
};
|
};
|
||||||
|
|
||||||
parser["Primary"] = [](const vector<Any>& v) {
|
parser["Primary"] = [](const vector<Any>& v) {
|
||||||
|
Loading…
Reference in New Issue
Block a user