#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef boost::function<double()> Value;
#define BINARY_FUNCTOR(name, op) \
struct name \
{ \
name(Value x, Value y): x_(x), y_(y) {} \
double operator()() { return x_() op y_(); } \
Value x_, y_; \
};
BINARY_FUNCTOR(ADD, +)
BINARY_FUNCTOR(SUB, -)
BINARY_FUNCTOR(MUL, *)
BINARY_FUNCTOR(DIV, /)
struct LIT
{
LIT(double x): x_(x) {}
double operator()()
{
return x_;
}
double x_;
};
struct NEG
{
NEG(Value x): x_(x) {}
double operator()()
{
return -x_();
}
Value x_;
};
struct SQRT
{
SQRT(Value x): x_(x) {}
double operator()()
{
return sqrt(x_());
}
Value x_;
};
// expression grammar definition
template <typename It, typename Skipper=qi::space_type>
struct parser : qi::grammar<It, Value(), Skipper>
{
parser() : parser::base_type(expression)
{
using namespace qi;
expression =
term [_val = _1]
>> *(('+' >> term [_val = phx::construct<ADD>(_val, _1)])
| ('-' >> term [_val = phx::construct<SUB>(_val, _1)])
);
term =
factor [_val = _1]
>> *(('*' >> factor [_val = phx::construct<MUL>(_val, _1)])
| ('/' >> factor [_val = phx::construct<DIV>(_val, _1)])
);
factor =
double_ [_val = phx::construct<LIT>(_1)]
| '(' >> expression [_val = _1] >> ')'
| ('-' >> factor [_val = phx::construct<NEG>(_1)])
| ('+' >> factor [_val = _1])
| (string("SQRT") >> '(' >> expression [_val = phx::construct<SQRT>(_1)] >> ')');
BOOST_SPIRIT_DEBUG_NODE(expression);
BOOST_SPIRIT_DEBUG_NODE(term);
BOOST_SPIRIT_DEBUG_NODE(factor);
}
private:
qi::rule<It, std::wstring(), Skipper> scientificNumber;
qi::rule<It, Value(), Skipper> expression, term, factor;
};
int main()
{
const std::wstring testExp = L"3E-10*(12-3)";
typedef std::wstring::const_iterator It;
It f(testExp.begin()), e(testExp.end());
parser<It, qi::space_type> expressionParser;
Value logicExpression;
bool ok = phrase_parse(f,e,expressionParser,qi::space,logicExpression);
std::cout << "Success: " << std::boolalpha << ok << "\tValue: " << logicExpression() << '\n';
}
I2luY2x1ZGUgPGJvb3N0L3NwaXJpdC9pbmNsdWRlL3FpLmhwcD4KI2luY2x1ZGUgPGJvb3N0L3NwaXJpdC9pbmNsdWRlL3Bob2VuaXguaHBwPgoKbmFtZXNwYWNlIHFpICAgID0gYm9vc3Q6OnNwaXJpdDo6cWk7Cm5hbWVzcGFjZSBwaHggICA9IGJvb3N0OjpwaG9lbml4OwoKdHlwZWRlZiBib29zdDo6ZnVuY3Rpb248ZG91YmxlKCk+IFZhbHVlOwoKI2RlZmluZSBCSU5BUllfRlVOQ1RPUihuYW1lLCBvcCkgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBzdHJ1Y3QgbmFtZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICBuYW1lKFZhbHVlIHgsIFZhbHVlIHkpOiB4Xyh4KSwgeV8oeSkge30gICAgICAgICBcCiAgICAgICAgZG91YmxlIG9wZXJhdG9yKCkoKSB7IHJldHVybiB4XygpIG9wIHlfKCk7IH0gICAgXAogICAgICAgIFZhbHVlIHhfLCB5XzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIH07CgpCSU5BUllfRlVOQ1RPUihBREQsICspCkJJTkFSWV9GVU5DVE9SKFNVQiwgLSkKQklOQVJZX0ZVTkNUT1IoTVVMLCAqKQpCSU5BUllfRlVOQ1RPUihESVYsIC8pCgpzdHJ1Y3QgTElUCnsKICAgIExJVChkb3VibGUgeCk6IHhfKHgpIHt9CiAgICBkb3VibGUgb3BlcmF0b3IoKSgpCiAgICB7CiAgICAgICAgcmV0dXJuIHhfOwogICAgfQogICAgZG91YmxlIHhfOwp9OwoKc3RydWN0IE5FRwp7CiAgICBORUcoVmFsdWUgeCk6IHhfKHgpIHt9CiAgICBkb3VibGUgb3BlcmF0b3IoKSgpCiAgICB7CiAgICAgICAgcmV0dXJuIC14XygpOwogICAgfQogICAgVmFsdWUgeF87Cn07CgpzdHJ1Y3QgU1FSVAp7CiAgICBTUVJUKFZhbHVlIHgpOiB4Xyh4KSB7fQogICAgZG91YmxlIG9wZXJhdG9yKCkoKQogICAgewogICAgICAgIHJldHVybiBzcXJ0KHhfKCkpOwogICAgfQogICAgVmFsdWUgeF87Cn07CgovLyBleHByZXNzaW9uIGdyYW1tYXIgZGVmaW5pdGlvbgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSXQsIHR5cGVuYW1lIFNraXBwZXI9cWk6OnNwYWNlX3R5cGU+CnN0cnVjdCBwYXJzZXIgOiBxaTo6Z3JhbW1hcjxJdCwgVmFsdWUoKSwgIFNraXBwZXI+CnsKICAgIHBhcnNlcigpIDogcGFyc2VyOjpiYXNlX3R5cGUoZXhwcmVzc2lvbikKICAgIHsKICAgICAgICB1c2luZyBuYW1lc3BhY2UgcWk7CiAgICAgICAgZXhwcmVzc2lvbiA9CiAgICAgICAgICAgIHRlcm0gICAgICAgICAgICAgICAgICAgIFtfdmFsID0gXzFdCiAgICAgICAgICAgID4+ICooKCcrJyA+PiB0ZXJtICAgICAgIFtfdmFsID0gcGh4Ojpjb25zdHJ1Y3Q8QUREPihfdmFsLCBfMSldKQogICAgICAgICAgICAgICAgICAgIHwgKCctJyA+PiB0ZXJtICBbX3ZhbCA9IHBoeDo6Y29uc3RydWN0PFNVQj4oX3ZhbCwgXzEpXSkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgdGVybSA9CiAgICAgICAgICAgIGZhY3RvciAgICAgICAgICAgICAgICAgIFtfdmFsID0gXzFdCiAgICAgICAgICAgID4+ICooKCcqJyA+PiBmYWN0b3IgICAgIFtfdmFsID0gcGh4Ojpjb25zdHJ1Y3Q8TVVMPihfdmFsLCBfMSldKQogICAgICAgICAgICAgICAgIHwgKCcvJyA+PiBmYWN0b3IgICBbX3ZhbCA9IHBoeDo6Y29uc3RydWN0PERJVj4oX3ZhbCwgXzEpXSkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgZmFjdG9yID0KICAgICAgICAgICAgZG91YmxlXyAgICAgICAgICAgICAgICAgW192YWwgPSBwaHg6OmNvbnN0cnVjdDxMSVQ+KF8xKV0KICAgICAgICAgICAgfCAnKCcgPj4gZXhwcmVzc2lvbiBbX3ZhbCA9IF8xXSA+PiAnKScKICAgICAgICAgICAgfCAoJy0nID4+IGZhY3RvciAgICAgICAgW192YWwgPSBwaHg6OmNvbnN0cnVjdDxORUc+KF8xKV0pCiAgICAgICAgICAgIHwgKCcrJyA+PiBmYWN0b3IgICAgICAgIFtfdmFsID0gXzFdKQogICAgICAgICAgICB8IChzdHJpbmcoIlNRUlQiKSA+PiAnKCcgPj4gZXhwcmVzc2lvbiBbX3ZhbCA9IHBoeDo6Y29uc3RydWN0PFNRUlQ+KF8xKV0gPj4gJyknKTsKICAgICAgICAKICAgICAgICBCT09TVF9TUElSSVRfREVCVUdfTk9ERShleHByZXNzaW9uKTsKICAgICAgICBCT09TVF9TUElSSVRfREVCVUdfTk9ERSh0ZXJtKTsKICAgICAgICBCT09TVF9TUElSSVRfREVCVUdfTk9ERShmYWN0b3IpOwogICAgfQoKICAgIHByaXZhdGU6CiAgICBxaTo6cnVsZTxJdCwgc3RkOjp3c3RyaW5nKCksIFNraXBwZXI+IHNjaWVudGlmaWNOdW1iZXI7CiAgICBxaTo6cnVsZTxJdCwgVmFsdWUoKSwgU2tpcHBlcj4gZXhwcmVzc2lvbiwgdGVybSwgZmFjdG9yOwoKfTsKCgoKaW50IG1haW4oKQp7CiAgICBjb25zdCBzdGQ6OndzdHJpbmcgdGVzdEV4cCA9IEwiM0UtMTAqKDEyLTMpIjsKCiAgICB0eXBlZGVmIHN0ZDo6d3N0cmluZzo6Y29uc3RfaXRlcmF0b3IgSXQ7CiAgICBJdCBmKHRlc3RFeHAuYmVnaW4oKSksIGUodGVzdEV4cC5lbmQoKSk7CiAgICBwYXJzZXI8SXQsIHFpOjpzcGFjZV90eXBlPiBleHByZXNzaW9uUGFyc2VyOwoKICAgIFZhbHVlIGxvZ2ljRXhwcmVzc2lvbjsKICAgIGJvb2wgb2sgPSBwaHJhc2VfcGFyc2UoZixlLGV4cHJlc3Npb25QYXJzZXIscWk6OnNwYWNlLGxvZ2ljRXhwcmVzc2lvbik7CgogICAgc3RkOjpjb3V0IDw8ICJTdWNjZXNzOiAiIDw8IHN0ZDo6Ym9vbGFscGhhIDw8IG9rIDw8ICJcdFZhbHVlOiAiIDw8IGxvZ2ljRXhwcmVzc2lvbigpIDw8ICdcbic7Cn0K