Skip to content

Commit

Permalink
added parser.h file, and fixed trailing whitespace in master
Browse files Browse the repository at this point in the history
  • Loading branch information
srajangarg committed Feb 7, 2016
1 parent 184a679 commit 0c64af9
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 55 deletions.
2 changes: 1 addition & 1 deletion symengine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ endif()
set(HEADERS
add.h symengine_assert.h functions.h monomials.h polynomial.h number.h rings.h
basic.h symengine_rcp.h integer.h mul.h pow.h constants.h
symbol.h expression.h
symbol.h expression.h parser.h
basic-inl.h dict.h matrix.h ntheory.h rational.h complex.h
visitor.h eval_double.h diophantine.h cwrapper.h printer.h real_double.h
eval_mpfr.h eval_arb.h eval_mpc.h complex_double.h series_visitor.h
Expand Down
2 changes: 1 addition & 1 deletion symengine/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class ExpressionParser {

public:
// does all the preprocessing related to parsing
RCP<const Basic> parse(const std::string &in)
RCP<const Basic> parse_expr(const std::string &in)
{
// stack to maintain right brackets, to match with corresponding left brackets
std::stack<unsigned int> right_bracket;
Expand Down
17 changes: 17 additions & 0 deletions symengine/parser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef SYMENGINE_PARSER_H
#define SYMENGINE_PARSER_H

#include <symengine/basic.h>
#include <symengine/dict.h>
#include <symengine/parser.cpp>

namespace SymEngine {

inline RCP<const Basic> parse(std::string& s) {
ExpressionParser p;
return p.parse_expr(s);
}

} // SymEngine

#endif
2 changes: 1 addition & 1 deletion symengine/series.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ RCP<const SeriesCoeffInterface> series(const RCP<const Basic> &ex, const RCP<con

if (syms.size() > 1)
throw std::runtime_error("Only univariate series expansion implemented with Flint");

return URatPSeriesFlint::series(ex, var->get_name(), prec);
#else
throw std::runtime_error("Series expansion is supported only with Piranha or Flint");
Expand Down
2 changes: 1 addition & 1 deletion symengine/series_flint.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class URatPSeriesFlint : public SeriesBase<fp_t, flint::fmpqxx, URatPSeriesFlint
virtual RCP<const Basic> as_basic() const;
virtual umap_int_basic as_dict() const;
virtual RCP<const Basic> get_coeff(int) const;

static RCP<const URatPSeriesFlint> series(const RCP<const Basic> &t, const std::string &x, unsigned int prec);
static flint::fmpzxx convert(const Integer &x);
static flint::fmpqxx convert(const mpq_class &x);
Expand Down
96 changes: 45 additions & 51 deletions symengine/tests/basic/test_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <symengine/functions.h>
#include <symengine/visitor.h>
#include <symengine/eval_double.h>
#include <symengine/parser.cpp>
#include <symengine/parser.h>

using SymEngine::Basic;
using SymEngine::Add;
Expand All @@ -31,233 +31,227 @@ using SymEngine::RCP;
using SymEngine::make_rcp;
using SymEngine::has_symbol;
using SymEngine::is_a;
using SymEngine::ExpressionParser;
using SymEngine::pi;
using SymEngine::function_symbol;
using SymEngine::real_double;
using SymEngine::E;
using SymEngine::parse;

TEST_CASE("Parsing: integers, basic operations", "[parser]")
{
std::string s;
ExpressionParser p;
RCP<const Basic> res;

s = "-3-5";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(-8)));

s = "((3)+(1*0))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(3)));

s = "((2))*(1+(2*3))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(14)));

s = "(1+1)*((1+1)+(1+1))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(8)));

s = "(1*3)*(2+4)*(2)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(36)));

s = "(1+3)/(2+4)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *div(integer(2), integer(3))));

s = "2*3 + 50*2";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(106)));

s = "2**(3+2)+ 10";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(42)));

s = "(5^3)/8 + 12";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(div(integer(125), integer(8)), integer(12))));

s = "3*2+3-5+2/2";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(5)));

s = "4^2/2+2";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *integer(10)));

s = "(1+2*(3+1)-5/(2+2))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(integer(9), div(integer(-5), integer(4)))));
}

TEST_CASE("Parsing: symbols", "[parser]")
{
std::string s;
ExpressionParser p;
RCP<const Basic> res;
RCP<const Basic> x = symbol("x");
RCP<const Basic> y = symbol("y");
RCP<const Basic> w = symbol("w1");
RCP<const Basic> l = symbol("l0ngn4me");

s = "x + 2*y";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(x, mul(integer(2), y))));

s = "w1*y";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *mul(w ,y)));

s = "x**(3+w1)-2/y";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(pow(x, add(integer(3), w)), div(integer(-2), y))));

s = "l0ngn4me - w1*y + 2^(x)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(add(l, neg(mul(w, y))), pow(integer(2), x))));

s = "4*x/8 - (w1*y)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(neg(mul(w, y)), div(x, integer(2)))));

s = "3*y + (2*y)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *mul(y, integer(5))));

s = "3*y/(1+x)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *div(mul(y, integer(3)), add(x, integer(1)))));

s = "y/x*x";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *y));
}

TEST_CASE("Parsing: functions", "[parser]")
{
std::string s;
ExpressionParser p;
RCP<const Basic> res;
RCP<const Basic> x = symbol("x");
RCP<const Basic> y = symbol("y");

s = "sin(x)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *sin(x)));

s = "asin(-1)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *neg(div(pi, integer(2)))));

s = "asin(sin(x))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *asin(sin(x))));

s = "beta(x,y)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *beta(x,y)));

s = "beta(sin(x+3), gamma(2^y+sin(y)))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *beta(sin(add(x, integer(3))), gamma(add(sin(y), pow(integer(2), y))))));

s = "y^(abs(sin(3) + x)) + sinh(2)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(pow(y, abs(add(sin(integer(3)), x))), sinh(integer(2)))));

s = "2 + zeta(2, x) + zeta(ln(3))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(integer(2), add(zeta(integer(2), x), zeta(log(integer(3)))))));

s = "sin(asin(x)) + y";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(x, y)));

s = "log(x, gamma(y))*sin(3)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *mul(log(x, gamma(y)), sin(integer(3)))));
}

TEST_CASE("Parsing: constants", "[parser]")
{
std::string s;
ExpressionParser p;
RCP<const Basic> res;
RCP<const Basic> x = symbol("x");

s = "E*pi";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *mul(E, pi)));

s = "sin(pi/2)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *one));

s = "log(e)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *one));

s = "ln(e/e) + sin(pi*2/2) + 3*x";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *mul(integer(3), x)));

s = "(3+4*I)/(5+cos(pi/2)*I)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *div(Complex::from_two_nums(*integer(3), *integer(4)), integer(5))));

s = "(2*I +6*I)*3*I + 4*I";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *Complex::from_two_nums(*integer(-24), *integer(4))));
}

TEST_CASE("Parsing: function_symbols", "[parser]")
{
std::string s;
ExpressionParser p;
RCP<const Basic> res;
RCP<const Basic> x = symbol("x");
RCP<const Basic> y = symbol("y");
RCP<const Basic> z = symbol("wt");

s = "f(x)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *function_symbol("f", x)));

s = "my_func(x, wt) + sin(f(y))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(function_symbol("my_func", {x, z}), sin(function_symbol("f", y)))));

s = "func(x, y, wt) + f(sin(x))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(function_symbol("func", {x, y, z}), function_symbol("f", sin(x)))));

s = "f(g(2^x))";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *function_symbol("f", function_symbol("g", pow(integer(2), x)))));
}

TEST_CASE("Parsing: doubles", "[parser]")
{
std::string s;
ExpressionParser p;
RCP<const Basic> res;
RCP<const Basic> x = symbol("x");

s = "1.324";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *real_double(1.324)));

s = "0.0324*x + 2*3";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *add(mul(real_double(0.0324), x), integer(6))));

s = "1.324/(2+3)";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *real_double(0.2648)));

s = "sqrt(2.0)+5";
res = p.parse(s);
res = parse(s);
REQUIRE(eq(*res, *real_double(sqrt(2) + 5)));
}

0 comments on commit 0c64af9

Please sign in to comment.