LCOV - code coverage report
Current view: top level - src/qi - parser_def.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 83 84 98.8 %
Date: 2022-11-05 14:57:37 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #ifndef MATHEVAL_IMPLEMENTATION
       2             : #error "Do not include parser_def.hpp directly!"
       3             : #endif
       4             : 
       5             : #pragma once
       6             : 
       7             : #include "ast.hpp"
       8             : #include "ast_adapted.hpp"
       9             : #include "math.hpp"
      10             : #include "parser.hpp"
      11             : 
      12             : #include <boost/spirit/include/phoenix.hpp>
      13             : #define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
      14             : #include <boost/spirit/include/qi.hpp>
      15             : 
      16             : #include <cmath>
      17             : #include <iostream>
      18             : #include <limits>
      19             : #include <sstream>
      20             : #include <string>
      21             : 
      22             : namespace matheval {
      23             : 
      24             : namespace qi = boost::spirit::qi;
      25             : 
      26             : namespace parser {
      27             : 
      28             : template <typename Iterator>
      29          90 : grammar<Iterator>::grammar() : grammar::base_type(expression) {
      30             :     qi::_2_type _2;
      31             :     qi::_3_type _3;
      32             :     qi::_4_type _4;
      33             : 
      34             :     qi::alnum_type alnum;
      35             :     qi::alpha_type alpha;
      36          90 :     qi::double_type double_;
      37             :     qi::lexeme_type lexeme;
      38             :     qi::raw_type raw;
      39             : 
      40             :     // clang-format off
      41             : 
      42             :     constant.add
      43           0 :         ("e"      , boost::math::constants::e<double>())
      44          90 :         ("epsilon", std::numeric_limits<double>::epsilon())
      45          90 :         ("phi"    , boost::math::constants::phi<double>())
      46          90 :         ("pi"     , boost::math::constants::pi<double>())
      47             :         ;
      48             : 
      49             :     ufunc.add
      50             :         ("abs"  , static_cast<double (*)(double)>(&std::abs))
      51          90 :         ("acos" , static_cast<double (*)(double)>(&std::acos))
      52          90 :         ("asin" , static_cast<double (*)(double)>(&std::asin))
      53          90 :         ("atan" , static_cast<double (*)(double)>(&std::atan))
      54          90 :         ("ceil" , static_cast<double (*)(double)>(&std::ceil))
      55          90 :         ("cos"  , static_cast<double (*)(double)>(&std::cos))
      56          90 :         ("cosh" , static_cast<double (*)(double)>(&std::cosh))
      57          90 :         ("deg"  , static_cast<double (*)(double)>(&math::deg))
      58          90 :         ("exp"  , static_cast<double (*)(double)>(&std::exp))
      59          90 :         ("floor", static_cast<double (*)(double)>(&std::floor))
      60          90 :         ("isinf", static_cast<double (*)(double)>(&math::isinf))
      61          90 :         ("isnan", static_cast<double (*)(double)>(&math::isnan))
      62          90 :         ("log"  , static_cast<double (*)(double)>(&std::log))
      63          90 :         ("log10", static_cast<double (*)(double)>(&std::log10))
      64          90 :         ("rad"  , static_cast<double (*)(double)>(&math::rad))
      65          90 :         ("sgn"  , static_cast<double (*)(double)>(&math::sgn))
      66          90 :         ("sin"  , static_cast<double (*)(double)>(&std::sin))
      67          90 :         ("sinh" , static_cast<double (*)(double)>(&std::sinh))
      68          90 :         ("sqrt" , static_cast<double (*)(double)>(&std::sqrt))
      69          90 :         ("tan"  , static_cast<double (*)(double)>(&std::tan))
      70          90 :         ("tanh" , static_cast<double (*)(double)>(&std::tanh))
      71             :         ;
      72             : 
      73             :     bfunc.add
      74             :         ("atan2", static_cast<double (*)(double, double)>(&std::atan2))
      75          90 :         ("pow"  , static_cast<double (*)(double, double)>(&std::pow))
      76             :         ;
      77             : 
      78          90 :     tfunc.add
      79             :         ("ifthenelse", static_cast<double (*)(double, double, double)>(&math::ifthenelse))
      80             :         ;
      81             : 
      82             :     unary_op.add
      83             :         ("+", static_cast<double (*)(double)>(&math::plus))
      84          90 :         ("-", static_cast<double (*)(double)>(&math::minus))
      85          90 :         ("!", static_cast<double (*)(double)>(&math::unary_not))
      86             :         ;
      87             : 
      88             :     additive_op.add
      89             :         ("+", static_cast<double (*)(double, double)>(&math::plus))
      90          90 :         ("-", static_cast<double (*)(double, double)>(&math::minus))
      91             :         ;
      92             : 
      93             :     multiplicative_op.add
      94             :         ("*", static_cast<double (*)(double, double)>(&math::multiplies))
      95          90 :         ("/", static_cast<double (*)(double, double)>(&math::divides))
      96          90 :         ("%", static_cast<double (*)(double, double)>(&std::fmod))
      97             :         ;
      98             : 
      99             :     logical_op.add
     100             :         ("&&", static_cast<double (*)(double, double)>(&math::logical_and))
     101          90 :         ("||", static_cast<double (*)(double, double)>(&math::logical_or))
     102             :         ;
     103             : 
     104             :     relational_op.add
     105             :         ("<" , static_cast<double (*)(double, double)>(&math::less))
     106          90 :         ("<=", static_cast<double (*)(double, double)>(&math::less_equals))
     107          90 :         (">" , static_cast<double (*)(double, double)>(&math::greater))
     108          90 :         (">=", static_cast<double (*)(double, double)>(&math::greater_equals))
     109             :         ;
     110             : 
     111             :     equality_op.add
     112             :         ("==", static_cast<double (*)(double, double)>(&math::equals))
     113          90 :         ("!=", static_cast<double (*)(double, double)>(&math::not_equals))
     114             :         ;
     115             : 
     116          90 :     power.add
     117             :         ("**", static_cast<double (*)(double, double)>(&std::pow))
     118             :         ;
     119             : 
     120          90 :     expression =
     121             :         logical.alias()
     122             :         ;
     123             : 
     124          90 :     logical =
     125         360 :         equality >> *(logical_op > equality)
     126             :         ;
     127             : 
     128          90 :     equality =
     129         360 :         relational >> *(equality_op > relational)
     130             :         ;
     131             : 
     132          90 :     relational =
     133         360 :         additive >> *(relational_op > additive)
     134             :         ;
     135             : 
     136          90 :     additive =
     137         360 :         multiplicative >> *(additive_op > multiplicative)
     138             :         ;
     139             : 
     140          90 :     multiplicative =
     141         360 :         factor >> *(multiplicative_op > factor)
     142             :         ;
     143             : 
     144          90 :     factor =
     145         360 :         primary >> *( power > factor )
     146             :         ;
     147             : 
     148          90 :     unary =
     149         360 :         ufunc > '(' > expression > ')'
     150             :         ;
     151             : 
     152          90 :     binary =
     153         540 :         bfunc > '(' > expression > ',' > expression > ')'
     154             :         ;
     155             : 
     156          90 :     ternary =
     157         720 :         tfunc > '(' > expression > ',' > expression > ',' > expression > ')'
     158             :         ;
     159             : 
     160         180 :     variable =
     161         360 :         raw[lexeme[alpha >> *(alnum | '_')]]
     162             :         ;
     163             : 
     164          90 :     primary =
     165             :           double_
     166         270 :         | ('(' > expression > ')')
     167         180 :         | (unary_op > primary)
     168          90 :         | ternary
     169          90 :         | binary
     170          90 :         | unary
     171          90 :         | constant
     172         180 :         | variable
     173             :         ;
     174             : 
     175             :     // clang-format on
     176             : 
     177          90 :     expression.name("expression");
     178          90 :     logical.name("logical");
     179          90 :     equality.name("equality");
     180          90 :     relational.name("relational");
     181          90 :     additive.name("additive");
     182          90 :     multiplicative.name("multiplicative");
     183          90 :     factor.name("factor");
     184          90 :     variable.name("variable");
     185          90 :     primary.name("primary");
     186          90 :     unary.name("unary");
     187          90 :     binary.name("binary");
     188          90 :     ternary.name("ternary");
     189             : 
     190             :     // typedef boost::phoenix::function<error_handler<Iterator> >
     191             :     // error_handler_function; qi::on_error<qi::fail>(expression,
     192             :     //        error_handler_function(error_handler<Iterator>())(
     193             :     //            "Error! Expecting ", qi::_4, qi::_3));
     194          90 :     qi::on_error<qi::fail>(
     195          90 :         expression,
     196          90 :         boost::phoenix::bind(boost::phoenix::ref(err_handler), _3, _2, _4));
     197          90 : }
     198             : 
     199             : } // namespace parser
     200             : 
     201             : } // namespace matheval

Generated by: LCOV version 1.14