--- /dev/null
+Contains revisions 6407:917d117ba6b0 6597:5b768c308932 6688:dde84e96b755 6689:e237d6d1d873 of ParseExp.cpp/h
+
+diff -r 917d117ba6b0 -r e237d6d1d873 src/tools/ParseExp.cpp
+--- a/src/tools/ParseExp.cpp Sun Dec 15 18:20:14 2013 +0100
++++ b/src/tools/ParseExp.cpp Sat Sep 13 11:22:39 2014 +0200
+@@ -1,262 +1,246 @@
+-// -*- c-basic-offset: 4 -*-\r
+-\r
+-/** @file ParseExp.cpp\r
+- *\r
+- * @brief functions to parse expressions from strings\r
+- *\r
+- * @author T. Modes\r
+- *\r
+- */\r
+-\r
+-/* This program is free software; you can redistribute it and/or\r
+- * modify it under the terms of the GNU General Public\r
+- * License as published by the Free Software Foundation; either\r
+- * version 2 of the License, or (at your option) any later version.\r
+- *\r
+- * This software is distributed in the hope that it will be useful,\r
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+- * General Public License for more details.\r
+- *\r
+- * You should have received a copy of the GNU General Public\r
+- * License along with this software; if not, write to the Free Software\r
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+- *\r
+- */\r
+-\r
+-// implementation is based on blog at\r
+-// http://agentzlerich.blogspot.de/2011/06/using-boost-spirit-21-to-evaluate.html\r
+-// modified to Hugins need\r
+-// added if statement\r
+-\r
+-#include "ParseExp.h"\r
+-\r
+-#include <limits>\r
+-#include <iterator>\r
+-\r
+-#include <boost/spirit/version.hpp>\r
+-#if !defined(SPIRIT_VERSION) || SPIRIT_VERSION < 0x2010\r
+-#error "At least Spirit version 2.1 required"\r
+-#endif\r
+-#include <boost/math/constants/constants.hpp>\r
+-#include <boost/spirit/include/phoenix.hpp>\r
+-#include <boost/spirit/include/qi.hpp>\r
+-\r
+-namespace Parser\r
+-{\r
+-\r
+-// helper classes to implement operators\r
+-\r
+-//power function\r
+-struct lazy_pow_\r
+-{\r
+- template <typename X, typename Y>\r
+- struct result { typedef X type; };\r
+-\r
+- template <typename X, typename Y>\r
+- X operator()(X x, Y y) const\r
+- {\r
+- return std::pow(x, y);\r
+- }\r
+-};\r
+-\r
+-// modulus for double values\r
+-struct lazy_mod_\r
+-{\r
+- template <typename X, typename Y>\r
+- struct result { typedef X type; };\r
+-\r
+- template <typename X, typename Y>\r
+- X operator()(X x, Y y) const\r
+- {\r
+- return std::fmod(x,y);\r
+- }\r
+-};\r
+-\r
+-// if statement\r
+-struct lazy_if_\r
+-{\r
+- template <typename X, typename Y, typename Z>\r
+- struct result { typedef Y type; };\r
+-\r
+- template <typename X, typename Y, typename Z>\r
+- X operator()(X x, Y y, Z z) const\r
+- {\r
+- return x ? y : z;\r
+- }\r
+-};\r
+-\r
+-// wrapper for unary function\r
+-struct lazy_ufunc_\r
+-{\r
+- template <typename F, typename A1>\r
+- struct result { typedef A1 type; };\r
+-\r
+- template <typename F, typename A1>\r
+- A1 operator()(F f, A1 a1) const\r
+- {\r
+- return f(a1);\r
+- }\r
+-};\r
+-\r
+-// convert rad into deg\r
+-double deg(const double d)\r
+-{\r
+- return d*180.0/boost::math::constants::pi<double>();\r
+-};\r
+-\r
+-// convert deg into rad\r
+-double rad(const double d)\r
+-{\r
+- return d*boost::math::constants::pi<double>()/180;\r
+-};\r
+-\r
+-// the main grammar class\r
+-struct grammar:boost::spirit::qi::grammar<std::string::const_iterator, double(), boost::spirit::ascii::space_type>\r
+-{\r
+-\r
+- // symbol table for constants like "pi", e.g. image number and value\r
+- struct constant_ : boost::spirit::qi::symbols<char, double>\r
+- {\r
+- constant_(const ConstantMap constMap)\r
+- {\r
+- this->add("pi", boost::math::constants::pi<double>());\r
+- if(constMap.size()>0)\r
+- {\r
+- for(ConstantMap::const_iterator it=constMap.begin(); it!=constMap.end(); it++)\r
+- {\r
+- this->add(it->first, it->second); \r
+- };\r
+- };\r
+- };\r
+- };\r
+-\r
+- // symbol table for unary functions like "abs"\r
+- struct ufunc_ : boost::spirit::qi::symbols<char, double(*)(double) >\r
+- {\r
+- ufunc_()\r
+- {\r
+- this->add\r
+- ("abs" , (double (*)(double)) std::abs )\r
+- ("acos" , (double (*)(double)) std::acos )\r
+- ("asin" , (double (*)(double)) std::asin )\r
+- ("atan" , (double (*)(double)) std::atan )\r
+- ("ceil" , (double (*)(double)) std::ceil )\r
+- ("sin" , (double (*)(double)) std::sin )\r
+- ("cos" , (double (*)(double)) std::cos )\r
+- ("tan" , (double (*)(double)) std::tan )\r
+- ("exp" , (double (*)(double)) std::exp )\r
+- ("floor" , (double (*)(double)) std::floor)\r
+- ("sqrt" , (double (*)(double)) std::sqrt )\r
+- ("deg" , (double (*)(double)) deg )\r
+- ("rad" , (double (*)(double)) rad )\r
+- ;\r
+- }\r
+- } ufunc;\r
+-\r
+- boost::spirit::qi::rule<std::string::const_iterator, double(), boost::spirit::ascii::space_type> expression, term, factor, primary, compExpression, compTerm, numExpression;\r
+-\r
+- grammar(const ConstantMap constMap) : grammar::base_type(expression)\r
+- {\r
+- using boost::spirit::qi::real_parser;\r
+- using boost::spirit::qi::real_policies;\r
+- real_parser<double,real_policies<double> > real;\r
+-\r
+- using boost::spirit::qi::_1;\r
+- using boost::spirit::qi::_2;\r
+- using boost::spirit::qi::_3;\r
+- using boost::spirit::qi::no_case;\r
+- using boost::spirit::qi::_val;\r
+- struct constant_ constant(constMap);\r
+-\r
+- boost::phoenix::function<lazy_pow_> lazy_pow;\r
+- boost::phoenix::function<lazy_mod_> lazy_mod;\r
+- boost::phoenix::function<lazy_if_> lazy_if;\r
+- boost::phoenix::function<lazy_ufunc_> lazy_ufunc;\r
+-\r
+- expression = \r
+- (compExpression >> '\?' >> compExpression >> ':' >> compExpression) [_val = lazy_if(_1, _2, _3)]\r
+- | compExpression [_val=_1]\r
+- ;\r
+- \r
+- compExpression=\r
+- compTerm [_val=_1]\r
+- >> * ( ("&&" >> compTerm [_val = _val && _1] )\r
+- |("||" >> compTerm [_val = _val || _1] )\r
+- )\r
+- ;\r
+-\r
+- compTerm =\r
+- numExpression [_val = _1 ]\r
+- >>*( ( '<' >> numExpression [_val = _val < _1])\r
+- |( '>' >> numExpression [_val = _val > _1])\r
+- |( "<=" >> numExpression [_val = _val <= _1])\r
+- |( ">=" >> numExpression [_val = _val >= _1])\r
+- |( "==" >> numExpression [_val = _val == _1])\r
+- |( "!=" >> numExpression [_val = _val != _1])\r
+- )\r
+- ;\r
+-\r
+- numExpression =\r
+- term [_val = _1]\r
+- >> *( ('+' >> term [_val += _1])\r
+- | ('-' >> term [_val -= _1])\r
+- )\r
+- ;\r
+-\r
+- term =\r
+- factor [_val = _1]\r
+- >> *( ('*' >> factor [_val *= _1])\r
+- | ('/' >> factor [_val /= _1])\r
+- | ('%' >> factor [_val = lazy_mod(_val, _1)])\r
+- )\r
+- ;\r
+-\r
+- factor =\r
+- primary [_val = _1]\r
+- >> *( ('^' >> factor [_val = lazy_pow(_val, _1)]) )\r
+- ;\r
+-\r
+- primary =\r
+- real [_val = _1]\r
+- | '(' >> expression [_val = _1] >> ')'\r
+- | ('-' >> primary [_val = -_1])\r
+- | ('+' >> primary [_val = _1])\r
+- | no_case[constant] [_val = _1]\r
+- | (no_case[ufunc] >> '(' >> expression >> ')') [_val = lazy_ufunc(_1, _2) ]\r
+- ;\r
+-\r
+- };\r
+-};\r
+-\r
+-//template <typename ParserType, typename Iterator>\r
+-bool parse(std::string::const_iterator &iter,\r
+- std::string::const_iterator end,\r
+- const grammar &g,\r
+- double& result)\r
+-{\r
+- if(!boost::spirit::qi::phrase_parse(iter, end, g, boost::spirit::ascii::space, result))\r
+- {\r
+- return false;\r
+- };\r
+- // we check if the full string could parsed\r
+- return iter==end;\r
+-}\r
+-\r
+-// the function which exposes the interface to external\r
+-// version without pre-defined constants \r
+-bool ParseExpression(const std::string& expression, double& result)\r
+-{\r
+- ConstantMap constants;\r
+- return ParseExpression(expression, result, constants);\r
+-};\r
+- \r
+-// version with pre-defined constants\r
+-bool ParseExpression(const std::string& expression, double& result, const ConstantMap& constants)\r
+-{\r
+- grammar g(constants);\r
+- std::string::const_iterator it=expression.begin();\r
+- return parse(it, expression.end(), g, result);\r
+-};\r
+-\r
+-} // namespace\r
++// -*- c-basic-offset: 4 -*-
++
++/** @file ParseExp.cpp
++ *
++ * @brief functions to parse expressions from strings
++ *
++ * @author T. Modes
++ *
++ */
++
++/* This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This software is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this software; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++// implementation is based on blog at
++// http://agentzlerich.blogspot.de/2011/06/using-boost-spirit-21-to-evaluate.html
++// modified to Hugins need
++// added if statement
++
++#include "ParseExp.h"
++
++#include <limits>
++#include <iterator>
++
++#define BOOST_SPIRIT_USE_PHOENIX_V3 1
++#include <boost/spirit/version.hpp>
++#if !defined(SPIRIT_VERSION) || SPIRIT_VERSION < 0x2010
++#error "At least Spirit version 2.1 required"
++#endif
++#include <boost/math/constants/constants.hpp>
++#include <boost/spirit/include/phoenix.hpp>
++#include <boost/spirit/include/qi.hpp>
++
++namespace Parser
++{
++
++// helper classes to implement operators
++
++//power function
++struct lazy_pow_
++{
++ typedef double result_type;
++
++ double operator()(double x, double y) const
++ {
++ return std::pow(x, y);
++ }
++};
++
++// modulus for double values
++struct lazy_mod_
++{
++ typedef double result_type;
++
++ double operator()(double x, double y) const
++ {
++ return std::fmod(x,y);
++ }
++};
++
++// if statement
++struct lazy_if_
++{
++ typedef double result_type;
++
++ double operator()(double x, double y, double z) const
++ {
++ return (std::fabs(x)>1e-5) ? y : z;
++ }
++};
++
++// wrapper for unary function
++struct lazy_ufunc_
++{
++ typedef double result_type;
++
++ double operator()(double (*f)(double), double a1) const
++ {
++ return f(a1);
++ }
++};
++
++// convert rad into deg
++const double deg(const double d)
++{
++ return d*180.0/boost::math::constants::pi<double>();
++};
++
++// convert deg into rad
++const double rad(const double d)
++{
++ return d*boost::math::constants::pi<double>()/180;
++};
++
++// the main grammar class
++struct grammar:boost::spirit::qi::grammar<std::string::const_iterator, double(), boost::spirit::ascii::space_type>
++{
++
++ // symbol table for constants like "pi", e.g. image number and value
++ struct constant_ : boost::spirit::qi::symbols<char, double>
++ {
++ constant_(const ConstantMap constMap)
++ {
++ this->add("pi", boost::math::constants::pi<double>());
++ if (constMap.size()>0)
++ {
++ for (ConstantMap::const_iterator it = constMap.begin(); it != constMap.end(); it++)
++ {
++ this->add(it->first, it->second);
++ };
++ };
++ };
++ };
++
++ // symbol table for unary functions like "abs"
++ struct ufunc_ : boost::spirit::qi::symbols<char, double(*)(double) >
++ {
++ ufunc_()
++ {
++ this->add
++ ("abs", (double(*)(double)) std::abs)
++ ("acos", (double(*)(double)) std::acos)
++ ("asin", (double(*)(double)) std::asin)
++ ("atan", (double(*)(double)) std::atan)
++ ("ceil", (double(*)(double)) std::ceil)
++ ("sin", (double(*)(double)) std::sin)
++ ("cos", (double(*)(double)) std::cos)
++ ("tan", (double(*)(double)) std::tan)
++ ("exp", (double(*)(double)) std::exp)
++ ("floor", (double(*)(double)) std::floor)
++ ("sqrt", (double(*)(double)) std::sqrt)
++ ("deg", (double(*)(double)) deg)
++ ("rad", (double(*)(double)) rad)
++ ;
++ }
++ } ufunc;
++
++ boost::spirit::qi::rule<std::string::const_iterator, double(), boost::spirit::ascii::space_type> expression, term, factor, primary, compExpression, compTerm, numExpression;
++
++ grammar(const ConstantMap constMap) : grammar::base_type(expression)
++ {
++ using boost::spirit::qi::real_parser;
++ using boost::spirit::qi::real_policies;
++ real_parser<double, real_policies<double> > real;
++
++ using boost::spirit::qi::_1;
++ using boost::spirit::qi::_2;
++ using boost::spirit::qi::_3;
++ using boost::spirit::qi::no_case;
++ using boost::spirit::qi::_val;
++ struct constant_ constant(constMap);
++
++ boost::phoenix::function<lazy_pow_> lazy_pow;
++ boost::phoenix::function<lazy_mod_> lazy_mod;
++ boost::phoenix::function<lazy_if_> lazy_if;
++ boost::phoenix::function<lazy_ufunc_> lazy_ufunc;
++
++ expression =
++ (compExpression >> '\?' >> compExpression >> ':' >> compExpression)[_val = lazy_if(_1, _2, _3)]
++ | compExpression[_val = _1]
++ ;
++
++ compExpression =
++ compTerm[_val = _1]
++ >> *(("&&" >> compTerm[_val = _val && _1])
++ | ("||" >> compTerm[_val = _val || _1])
++ )
++ ;
++
++ compTerm =
++ numExpression[_val = _1]
++ >> *(('<' >> numExpression[_val = _val < _1])
++ | ('>' >> numExpression[_val = _val > _1])
++ | ("<=" >> numExpression[_val = _val <= _1])
++ | (">=" >> numExpression[_val = _val >= _1])
++ | ("==" >> numExpression[_val = _val == _1])
++ | ("!=" >> numExpression[_val = _val != _1])
++ )
++ ;
++
++ numExpression =
++ term[_val = _1]
++ >> *(('+' >> term[_val += _1])
++ | ('-' >> term[_val -= _1])
++ )
++ ;
++
++ term =
++ factor[_val = _1]
++ >> *(('*' >> factor[_val *= _1])
++ | ('/' >> factor[_val /= _1])
++ | ('%' >> factor[_val = lazy_mod(_val, _1)])
++ )
++ ;
++
++ factor =
++ primary[_val = _1]
++ >> *(('^' >> factor[_val = lazy_pow(_val, _1)]))
++ ;
++
++ primary =
++ real[_val = _1]
++ | '(' >> expression[_val = _1] >> ')'
++ | ('-' >> primary[_val = -_1])
++ | ('+' >> primary[_val = _1])
++ | no_case[constant][_val = _1]
++ | (no_case[ufunc] >> '(' >> expression >> ')')[_val = lazy_ufunc(_1, _2)]
++ ;
++
++ };
++};
++
++bool parse(std::string::const_iterator& iter,
++ std::string::const_iterator end,
++ const grammar& g,
++ double& result)
++{
++ if(!boost::spirit::qi::phrase_parse(iter, end, g, boost::spirit::ascii::space, result))
++ {
++ return false;
++ };
++ // we check if the full string could parsed
++ return iter==end;
++}
++
++// version with pre-defined constants
++bool ParseExpression(const std::string& expression, double& result, const ConstantMap& constants)
++{
++ grammar g(constants);
++ std::string::const_iterator it=expression.begin();
++ return parse(it, expression.end(), g, result);
++};
++
++} // namespace
+diff -r 917d117ba6b0 -r e237d6d1d873 src/tools/ParseExp.h
+--- a/src/tools/ParseExp.h Sun Dec 15 18:20:14 2013 +0100
++++ b/src/tools/ParseExp.h Sat Sep 13 11:22:39 2014 +0200
+@@ -33,8 +33,7 @@
+ {
+ typedef std::map<const char*, double> ConstantMap;
+
+-bool ParseExpression(const std::string& expression, double& result);
+-bool ParseExpression(const std::string& expression, double& result, const ConstantMap& constants);
++bool ParseExpression(const std::string& expression, double& result, const ConstantMap& constants=ConstantMap());
+
+ };
+