jdesmet / jmep

Automatically exported from code.google.com/p/jmep

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Jmep

The next big task

This project has been cute so far ... but the Shunting algorithm isn't going to cut it for me anymore. The syntactical processing of the current algorithm has grown pretty stable, but I have decided that it is worth converting it over to using either JavaCC or ANTLR. This will separate the Syntax description through abstracting the AST (Abstract Syntax Tree). I believe that this will be cause for better processing offering following benefits:

  • Faster, I hope ...
  • Better pinpointing of error locations.
  • Solve the issue of zero parameter functions (doesn't work in the current implementation).
  • Easier and faster to fix newly discovered issues, or implement new features
  • Minimize complex java coding

Parse and evaluate mathematical expressions.

This Expression parser is intended to work as natural as possible, and in doing so will actually deviate from what expressions in a language like java or C would do. Special care has been made for optimizing expression evaluation by carefully separating out the parsing step from the actual evaluation step, allowing faster consecutive execution of the same expression with different parameters.

Its use is simple:

int x = 0;
Environment env = Environment.getInstance(Expression.OperationalMode.BASIC);
// Add a unit called 'mm' to the environment
env.registerUnit("mm", Double.class, (t)->0.001*t);
env.addVariable("time",()->System.currentTimeMillis()/1000);
env.addVariable("x",()->x);
expression = new Expression("2*x",env);
result = expression.evaluate();
System.out.println("Result = ("+result.getClass().getSimpleName()+")" + result);
x = 10;
// No need to recompile the expression, just evaluate again, and the new value for x will be automatically captured.
result = expression.evaluate();
System.out.println("Result = ("+result.getClass().getSimpleName()+")```" + result);

The parser has built-in knowledge about operator precedence. Operator precedence is predetermined, and cannot be changed at run-time. It matches Operator Precedence as defined for expressions in languages like Java and C.

This API is completely agnostic to the type of the operators, and in fact will accept any type extending Object, that simple. The work is just in registering implementations for

  • Binary Operators
  • Unary Operators
  • Units of Measure
  • Constants and Variables
  • Up-Conversions

Look at the documentation for [Complex how to add support for Complex numbers], to see how some of these can be implemented. You will note the use of Lambda expressions throughout.

A BasicEnvironment is already preconfigured to operate on String, Long, and Double. Boolean support is built in by evaluating true/false as 1/0.

Equally a FinancialEnvironment has been preconfigured to be more stricter, and disallow the usage of Double and preferring BigDecimal instead. We could have been more lenient by allowing a mix of Double and BigNumber, but such restrictions promotes proper use in financial applications. The programmer is left free to maybe create their own LenientFinancialEnvironment, or MixedFinancialEnvironment, but then it is up to the final user to be careful not to use calculations that break the integrity of the numbers.

For those interested, the compilation phase of expressions is implemented using the Dijkstra shunting-yard algorithm.

About

Automatically exported from code.google.com/p/jmep


Languages

Language:Java 100.0%