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 102 : void parse(std::string const &expr) { 19 204 : auto ast_ = ast::expression{}; 20 : 21 102 : auto first = expr.begin(); 22 102 : auto last = expr.end(); 23 : 24 : boost::spirit::x3::ascii::space_type space; 25 102 : bool r = phrase_parse(first, last, grammar(), space, ast_); 26 : 27 102 : if (!r || first != last) { 28 6 : std::string rest(first, last); 29 3 : throw std::runtime_error("Parsing failed at " + rest); // NOLINT 30 : } 31 : 32 99 : ast = ast_; 33 99 : } 34 : 35 1 : void optimize() { ast = boost::apply_visitor(ast::ConstantFolder{}, ast); } 36 : 37 98 : double evaluate(std::map<std::string, double> const &st) { 38 100 : return boost::apply_visitor(ast::eval{st}, ast); 39 : } 40 : }; 41 : 42 102 : Parser::Parser() : pimpl{std::make_unique<Parser::impl>()} {} 43 : 44 102 : Parser::~Parser() {} 45 : 46 102 : void Parser::parse(std::string const &expr) { pimpl->parse(expr); } 47 : 48 1 : void Parser::optimize() { pimpl->optimize(); } 49 : 50 98 : double Parser::evaluate(std::map<std::string, double> const &st) { 51 98 : return pimpl->evaluate(st); 52 : } 53 : 54 : } // namespace matheval