Line data Source code
1 : #define MATHEVAL_IMPLEMENTATION 2 : 3 : #include "matheval.hpp" 4 : #include "ast.hpp" 5 : #include "evaluator.hpp" 6 : #include "parser.hpp" 7 : 8 : #include <memory> 9 : #include <stdexcept> 10 : #include <string> 11 : 12 : namespace matheval { 13 : 14 : class Parser::impl { 15 : ast::operand ast; 16 : 17 : public: 18 90 : void parse(std::string const &expr) { 19 180 : ast::expression ast_; 20 : 21 90 : std::string::const_iterator first = expr.begin(); 22 90 : std::string::const_iterator last = expr.end(); 23 : 24 : boost::spirit::ascii::space_type space; 25 90 : bool r = qi::phrase_parse( 26 182 : first, last, grammar(), space, 27 : ast_); 28 : 29 88 : if (!r || first != last) { 30 2 : std::string rest(first, last); 31 1 : throw std::runtime_error("Parsing failed at " + rest); // NOLINT 32 : } 33 : 34 87 : ast = ast_; 35 87 : } 36 : 37 1 : void optimize() { ast = boost::apply_visitor(ast::ConstantFolder(), ast); } 38 : 39 86 : double evaluate(std::map<std::string, double> const &st) { 40 86 : return boost::apply_visitor(ast::eval(st), ast); 41 : } 42 : }; 43 : 44 90 : Parser::Parser() : pimpl(new Parser::impl()) {} 45 : 46 90 : Parser::~Parser() {} 47 : 48 90 : void Parser::parse(std::string const &expr) { pimpl->parse(expr); } 49 : 50 1 : void Parser::optimize() { pimpl->optimize(); } 51 : 52 86 : double Parser::evaluate(std::map<std::string, double> const &st) { 53 86 : return pimpl->evaluate(st); 54 : } 55 : 56 : } // namespace matheval