18#define BOOST_SPIRIT_QI_DEBUG
21#define _USE_MATH_DEFINES
24#include <boost/fusion/include/adapt_struct.hpp>
25#include <boost/fusion/include/io.hpp>
26#include <boost/phoenix.hpp>
27#include <boost/phoenix/object.hpp>
28#include <boost/spirit/include/qi.hpp>
37namespace qi = boost::spirit::qi;
38namespace ascii = boost::spirit::ascii;
39namespace phx = boost::phoenix;
44 virtual double Eval()
const {
return 0; }
46 const std::unordered_map<std::string, double> &variables)
const {
60template <
typename Expr>
62 return std::make_shared<Expr>(t);
82 double Eval()
const override {
return value; }
84 const std::unordered_map<std::string, double> &variables)
const override {
108 Variable(
const std::string &value =
"") : value(value) {}
115 double Eval()
const override {
return 0; }
117 const std::unordered_map<std::string, double> &variables)
const override {
118 auto it = variables.find(value);
119 if (it != variables.end())
122 throw std::invalid_argument(
"Variable not found: " + value);
137 template <
typename V>
147 template <
typename L,
typename R>
149 : op(op), left(
Clone(left)), right(
Clone(right)) {}
154 return left->Eval() + right->Eval();
156 return left->Eval() - right->Eval();
158 return left->Eval() * right->Eval();
160 return left->Eval() / right->Eval();
162 return pow(left->Eval(), right->Eval());
164 throw std::invalid_argument(
"Unknown binary operator");
171 const std::unordered_map<std::string, double> &variables)
const override {
174 return left->Eval(variables) + right->Eval(variables);
176 return left->Eval(variables) - right->Eval(variables);
178 return left->Eval(variables) * right->Eval(variables);
180 return left->Eval(variables) / right->Eval(variables);
182 return pow(left->Eval(variables), right->Eval(variables));
184 throw std::invalid_argument(
"Unknown binary operator");
196 template <
typename,
typename,
typename>
201 template <
typename C,
typename L,
typename R>
213 template <
typename R>
219 return right->Eval();
221 return -right->Eval();
223 throw std::invalid_argument(
"Unknown unary operator");
230 const std::unordered_map<std::string, double> &variables)
const override {
233 return right->Eval(variables);
235 return -right->Eval(variables);
237 throw std::invalid_argument(
"Unknown unary operator");
248 template <
typename,
typename>
253 template <
typename C,
typename R>
263 template <
typename F>
265 : func(func), param(
Clone(param)) {}
269 return sin(param->Eval());
270 else if (func ==
"cos")
271 return cos(param->Eval());
272 else if (func ==
"tan")
273 return tan(param->Eval());
274 else if (func ==
"exp")
275 return exp(param->Eval());
276 else if (func ==
"ln")
277 return log(param->Eval());
278 else if (func ==
"sqrt")
279 return sqrt(param->Eval());
281 throw std::invalid_argument(
"Unknown function");
287 const std::unordered_map<std::string, double> &variables)
const override {
289 return sin(param->Eval(variables));
290 else if (func ==
"cos")
291 return cos(param->Eval(variables));
292 else if (func ==
"tan")
293 return tan(param->Eval(variables));
294 else if (func ==
"exp")
295 return exp(param->Eval(variables));
296 else if (func ==
"ln")
297 return log(param->Eval(variables));
298 else if (func ==
"sqrt")
299 return sqrt(param->Eval(variables));
301 throw std::invalid_argument(
"Unknown function");
312 template <
typename,
typename,
typename>
317 template <
typename Params>
330 template <
typename E>
333 double Eval()
const override {
return expr->Eval(); }
336 const std::unordered_map<std::string, double> &variables)
const override {
337 return expr->Eval(variables);
AbstractSyntaxTree(AbstractSyntaxTree &&)=default
AbstractSyntaxTree(const AbstractSyntaxTree &)=default
AbstractSyntaxTree()=default
virtual ~AbstractSyntaxTree()=default
virtual double Eval(const std::unordered_map< std::string, double > &variables) const
virtual double Eval() const
AbstractSyntaxTree & operator=(const AbstractSyntaxTree &)=default
AbstractSyntaxTree & operator=(AbstractSyntaxTree &&)=default
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
BinaryOperator(char op, const L &left, const R &right)
double Eval() const override
Constant & operator=(int value)
Constant & operator=(double value)
double Eval(const std::unordered_map< std::string, double > &variables) const override
friend AbstractSyntaxTreePtr Clone(Expression const &e)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
Function(const std::string &func, const F ¶m)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
UnaryOperator(char op, const R &right)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
Variable & operator=(int value)
double Eval() const override
Variable(const std::string &value="")
double Eval(const std::unordered_map< std::string, double > &variables) const override
phx::function< MakeFunctionExpression > MakeFunction
phx::function< MakeUnaryExpression > MakeUnary
phx::function< MakeBinaryExpression > MakeBinary
static AbstractSyntaxTreePtr Clone(Expr const &t)
std::shared_ptr< AbstractSyntaxTree > AbstractSyntaxTreePtr
phx::function< MakeVariableExpression > MakeVariable
phx::function< MakeConstantExpression > MakeConstant
BinaryOperator operator()(C op, const L &lhs, const R &rhs) const
Constant operator()(C op) const
Function operator()(const std::string &funcName, const Params ¶ms) const
UnaryOperator operator()(C op, const R &rhs) const
Variable operator()(V v) const