scireum / parsii Goto Github PK
View Code? Open in Web Editor NEWSuper fast and simple evaluator for mathematical expressions written in Java
License: MIT License
Super fast and simple evaluator for mathematical expressions written in Java
License: MIT License
It seems that arithmetic and relational operations are both supported. It seems also logical-and "&&" and logical-or "||" operations are supported.
However, when I tried to use "!(a1>b1)" or "not(a1>b1)", I got parse error. is logical-not operator available?
I noticed that the parsing methods are all protected, but because the constructor is private, it's not possible to extend from Parser and add to its grammar.
I was able to directly modify the class to do what I wanted but it would be nice to extend it without having to fork the code.
Could you please add support for parentheses with positive sign, like "+(2.2)". This currently leads to a parse error.
Background: I'm currently running a test with over 1.200.000 mathematical expressions from a real application which have been parsed by JEP and this seems to be the only remaining difference ..
Thank you!
@test
public void signedParentheses() throws ParseException {
assertEquals(0.2, Parser.parse("-(-0.2)").evaluate(), EPSILON);
assertEquals(1.2, Parser.parse("1-(-0.2)").evaluate(), EPSILON);
assertEquals(0.8, Parser.parse("1+(-0.2)").evaluate(), EPSILON);
assertEquals(2.2, Parser.parse("+(2.2)").evaluate(), EPSILON); // ERROR !
}
I'm using JEP for years and I came recently over parsii. I find it a very lightweight and well written parser. The application in which I would like to implement parsii allows the final user to write its expressions in a simple text file. Obviously, mistakes can be typed in the expressions, such as making reference to non existent variables. For instance, if the user defines a=5 and b=7, but writes "a + c" as expression to parse, parsii will return 5 because it initializes c = 0, while it was never defined by the user.
JEP throws a special exception for undefined variables, which can be intercepted in order to warn the user that he made a mistake. If such a mechanism could be rather difficult to implement in parsii, a simple workaround is to modify the default value that is given to a Variable. So, in the Variable class, I replaced
private double value = 0d;
with
private double value = Double.NaN;
Parsii will not throw an exception, but the Expression.evaluate(...) method will return a NaN if an unknown variable is references in the expression. Obviously, this is not perfect as it is not possible to give a precise information (which variable is unknown for instance), but, at least, the error is detected.
Is there any reason for which the default value is set to 0? If it is not the case, could this workaround be pushed in the source tree?
Regards,
Bart
Hi,
It seems that Parsii doesn't like scientific notations... Did I miss something ?
String value = "-5.408380743914645e-10";
// Simple Java is working
double d = Double.valueOf(value);
// The parser throws an error : " Unexpected token: 'e'. Expected a valid quantifier."
try {
Parser.parse(value).evaluate();
} catch (ParseException e) {
e.printStackTrace();
}
We need to do some calculations were the variables are a series of numbers. could add the following features?
Would that be possible?
Parsii, gives 3-6^2 = 39 where I would expect -33?
Very good library! But the following test case produces a parse error because of the '+' sign in front of the numeric literal. Would have expected this to work. Any chance to see this working in the next release? Thank you!
@Test
public void signed() throws ParseException {
assertEquals(2.02, Parser.parse("+2.02").evaluate(), 0.0000001);
}
Although the POM states <maven.compiler.target>1.6</maven.compiler.target>, the resulting JAR from a compile with JDK 8 is not runnable under Java 7 ("unsupported major.minor version 52.0"). The same problem occurs with the parsii-2.2.jar downloaded from Maven central. Am I doing something wrong or is the cross compile option not working?
Thank you, Jürgen
Hi,
thanks a lot for this great expression parser. I did some magic on it here: https://github.com/subes/invesdwin-util/tree/master/invesdwin-util/src/main/java/de/invesdwin/util/math/expression
This is essentially a fork that adds the following improvements:
[x]
operator for accessing previous values via index/expression (IPreviousKeyFunction needs to be provided for this feature), works on variables and functions by just modifying the key for evaluationI felt the modifications were too much to create pull requests, so instead I did a major rewrite of most parts and published the results in invesdwin-util. I might find more improvements which I will also make public in that repo.
You might be able to pick some of those improvements and reintegrate them in parsii. Otherwise you can just close this issue since I just wanted to inform you about the performance improvements that are still available.
Best regards,
Edwin
In readme.md: "For your convenience: A pre-built jar can be found in the build directory."
excuse me, i just want a jar, but i can't find build directory
We are trying to use parsii in our project. We tested and parsii performance is satisfactory. However we are still using JDK 1.6 at runtime, and we got the following errors. It would be great if parsii could support JDK 1.6 when release.
javax.servlet.ServletException: java.lang.UnsupportedClassVersionError: parsii/eval/Scope : Unsupported major.minor version 51.0 (unable to load class parsii.eval.Scope)
Hello,
I have a boolean expression but need additional context to the eval method to determine its boolean value. For example
(4 && 9) || 11
Then I want to pass a collection to eval() and invoke contains() on the collection to see if the literal is there or not and return that true or false value. Is this possible? Thanks!
Is this thread safe, or is there any way to use it thread safely without synchronized?
logical inconsistency in BinaryFunction between comments and code.
In fact, like the comments, BinaryFunction has two arguments, so the method getNumberOfArguments() and eval(List args) work incorrectly.
The expression
5>=5 yields false because the code tests that
5>5 (false) or that abs(5-5)>epsilon
the same applies to 5<=5
Any option to achieve this?
Thank you very much for your support. I've found two more minor cases where Parsii throws an Exception, but they are considered legal in Java and JEP. Perhaps you might want to have a look at this.
Will write an email to you in the next days on what I'm currently doing ... :-)
@Test
public void trailingDecimalPoint() throws ParseException {
assertEquals(2., Parser.parse("2.").evaluate(), EPSILON); // ERROR
}
@Test
public void signedValueAfterOperand() throws ParseException {
assertEquals(-1.2, Parser.parse("1+-2.2").evaluate(), EPSILON); // OK
assertEquals(3.2, Parser.parse("1++2.2").evaluate(), EPSILON); // ERROR
assertEquals(6*-1.1, Parser.parse("6*-1.1").evaluate(), EPSILON); // OK
assertEquals(6*+1.1, Parser.parse("6*+1.1").evaluate(), EPSILON); // ERROR
}
calculate the following,the result is wroing
Scope scope = new Scope();
Variable a = scope.create("a");
Expression expr = Parser.parse("a + 2.4", scope);
a.setValue(1.2);
double evaluate = expr.evaluate();
System.out.println(evaluate);
the result is 3.5999999999999996
How to calculate use BigDecimal , then result is 3.6 ?
I tried to do max(variable) but it didn't work. Is there a way to do it?
Per Java language specification, floating point literats may start with the decimal point, eg. ".2". This leads to a parser error in Parsii. Would be great to see this in Parsii, too ..
@test
public void startingWithDecimalPoint() throws ParseException {
// Throws a ParseException
assertEquals(.2, Parser.parse(".2").evaluate(), EPSILON);
}
I've noticed a small issue with block comments. The second example with the block comment directly starting after the + operand throws a ParseException. This would work in other libs like JEP.
@Test
public void blockComment() throws ParseException {
assertEquals(29, Parser.parse("27+ /*xxx*/ 2").evaluate(), EPSILON); // OK
assertEquals(29, Parser.parse("27+/*xxx*/ 2").evaluate(), EPSILON); // ERROR !
assertEquals(29, Parser.parse("27/*xxx*/+2").evaluate(), EPSILON); // OK
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.