diff --git a/README.md b/README.md index 936ead0..acbdd6c 100644 --- a/README.md +++ b/README.md @@ -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, ...). -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& 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& v`. The values are wrapped by peblib::Any class which is like `boost::any`. We can retrieve the value by using `get` 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& 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& v`. The values are wrapped by peglib::Any class which is like `boost::any`. We can retrieve the value by using `get` 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: diff --git a/peglib.h b/peglib.h index ddf6ad0..39f9bf2 100644 --- a/peglib.h +++ b/peglib.h @@ -115,15 +115,24 @@ public: return *this; } - operator const std::string&() const { - return get(); - } - - operator std::string&() { - return get(); - } - // TODO: Add more implecit cast operators + operator bool() const { return get(); } + operator char() const { return get(); } + operator wchar_t() const { return get(); } + operator char16_t() const { return get(); } + operator char32_t() const { return get(); } + operator unsigned char() const { return get(); } + operator int() const { return get(); } + operator unsigned int() const { return get(); } + operator short() const { return get(); } + operator unsigned short() const { return get(); } + operator long() const { return get(); } + operator unsigned long() const { return get(); } + operator long long() const { return get(); } + operator unsigned long long() const { return get(); } + operator float() const { return get(); } + operator double() const { return get(); } + operator const std::string&() const { return get(); } private: struct placeholder { @@ -189,13 +198,16 @@ public: //Action(Action&& rhs) : fn_(std::move(rhs.fn_)) {} - template ::value>::type*& = enabler> + template ::value && !std::is_null_pointer::value>::type*& = enabler> Action(F fn) : fn_(make_adaptor(fn, &F::operator())) {} template ::value>::type*& = enabler> Action(F fn) : fn_(make_adaptor(fn, fn)) {} - template ::value>::type*& = enabler> + template ::value>::type*& = enabler> + Action(F fn) {} + + template ::value && !std::is_null_pointer::value>::type*& = enabler> void operator=(F fn) { fn_ = make_adaptor(fn, &F::operator()); } @@ -205,6 +217,9 @@ public: fn_ = make_adaptor(fn, fn); } + template ::value>::type*& = enabler> + void operator=(F fn) {} + operator bool() const { return (bool)fn_; } diff --git a/test/test.cc b/test/test.cc index ba9467a..e4cd902 100644 --- a/test/test.cc +++ b/test/test.cc @@ -131,7 +131,7 @@ TEST_CASE("Simple calculator test", "[general]") parser["Additive"] = { // Default action - []() {}, + nullptr, // Action for the first choice [](const vector& v) { return v[0].get() + v[1].get(); }, // Action for the second choice @@ -139,7 +139,7 @@ TEST_CASE("Simple calculator test", "[general]") }; parser["Multitive"] = [](const vector& v) { - return v.size() == 1 ? v[0] : v[0].get() * v[1].get(); + return v.size() == 1 ? int(v[0]) : v[0].get() * v[1].get(); }; parser["Primary"] = [](const vector& v) {