JEP - Java Expression Parser SourceForge Logo

Main  |  Samples  |  Documentation  |  Version Log  |  Forum  |  Download
Usage | Operators & Functions | Grammar | Custom Functions | JavaDoc | FAQ

Usage

Basic usage

Using the JEP package of classes in your project is simple. The following steps will get you started quickly.

  1. Download the JEP package from the download section
  2. Unpack the archive
  3. Move the jep-x.xx.jar file to a directory of your choice (optional)
  4. IMPORTANT: For the Java compiler to be able to find the JEP classes when compiling your program, it needs to know their location. So you will need to add the location of the .jar file to your CLASSPATH environment variable (if you don't know how, read this). Your CLASSPATH variable should contain something like C:\java\packages\jep-x.xx.jar, depending on where you place the jar file.
  5. In your program, create a new parser object with
    org.nfunk.jep.JEP myParser = new org.nfunk.jep.JEP();
  6. Add the standard functions and constants if you want to be able to evaluate expressions with trigonometric functions and the constants pi and e.
    myParser.addStandardFunctions();
    myParser.addStandardConstants();
  7. By default you need to specify which variables can be used in the expression. If a variable is not added before the expression is parsed, the parser will claim that the expression is invalid (this can be changed by allowing undeclared variables).
    To add the variable x and initialize it to 0 for example, write
    myParser.addVariable("x", 0);
  8. Parse the expression, and evaluate it:
    myParser.parseExpression(ExpressionString);
    result = myParser.getValue();
  9. The values of variables can be changed with the addVariable(String, double) method.

The code of the sample applets provide more extensive look at how the parser methods are used.



Evaluating expressions

Three methods for evaluating an expression are available:

The first two methods call getValueAsObject() internally, and perform the necessary conversions into either a double value, or a Complex object.



Implicit multiplication

You can enable the implicit multiplication option with setImplicitMul(true). The default setting is false (no implicit multiplication).

Implicit multiplication allows expressions such as "2 x" to be interpreted as "2*x". Note that a space is required between two variables for them to be interpreted as being multiplied. The same holds for a variable followed by a number. For example "y 3" is interpreted as "y*3", but "y3" is interpreted as a single variable with the name y3. If a variable is preceded by a number, no space is required between them for implicit multiplication to come in effect.



Allowing undeclared variables

To enable parsing of undeclared variables, use setAllowUndeclared(true). The default setting is false (undeclared variables are not allowed).

If you do not know what variable names may occur in the expression before parsing it, you can use setAllowUndeclared(true). With this option enabled, it is not necessary to add variables to the parser before parsing an expression. If a new variable is found while parsing, it is automatically added and initialized to 0. See Obtaining a list of variables to read about how to access these variables.



Obtaining a list of variables

A list of all the variables and constants that have been added to the parser, can be obtained with the getSymbolTable() method.

This method is most useful when the undeclared variables option is enabled. After an expression has been parsed, a list of all variables occurring in that expression can be obtained using the getSymbolTable() method. The return value is a SymbolTable object. Note that SymbolTable extends Hashtable.



Complex numbers

If you want to use complex numbers in your expression, you can call addComplex() after creating the parser object. This will add the imaginary unit as constant i. Two parser functions re() and im() are also added and can be used to obtain the real and imaginary components of complex numbers. You will need to import the org.nfunk.jep.type.Complex class to be able to manipulate complex values from expressions.

By using the imaginary unit constant i, you can work with complex numbers in your expressions. A sample complex expression would be (1+2*i)^3. Currently the (re,IM) notation is not supported.

To obtain a complex value from an expression, you must use the getComplexValue() function. It will evaluate the expression and return the result as a Complex object. Note that the class used internally for Complex numbers is also used for returning the value.

Adding a complex variable or constant to the parser before evaluating an expression can be done with addComplexValue(). It takes three parameters: the name of the variable as string, the real component, and the imaginary component.



Using Vectors

Vectors are ordered sets of Double elements. A vector is a list of values, separated by commas, and enclosed by square brackets. An example expression involving a vector is:

[3, 4, 5]*2

It would be evaluated as [6, 8, 10] by JEP. To add a vector as variable, use the addVariableAsObject() method. If the result of an expression is a vector, it can be obtained by calling the getValueAsObject() function.



Using Strings

Strings can be entered in an expression by using double quotes. They can be concatenated with the + operator and compared with the == and != relational operators. A sample expression involving the string type is "foo" + "bar" == "foobar", which would be evaluated by JEP as 1 (true).

To add a string as a variable, use the addVariableAsObject() method. If the result of an expression is a string, it can be obtained by calling the getValueAsObject() function.



Custom types

In most cases, you will only need to work with the few built in types that JEP supplies (Double, Complex, Vector, String). But suppose you want to evaluate expressions that involve other types. This is possible by using the addVariableAsObject() method to add variables of any type. The only place where the type of a variable matters, is in the function classes.

When an expression is evaluated, values are operated on with the classes in the function package. These include the operators (such as Add and Subtract), as well as the functions (such as Sine and Cosine). Without making modifications to the source code, only the default types are handled with these classes. So, in order to be able to handle your own types, you will need to modify theses classes, or make your own function classes as described in the custom functions section.



Manipulating expressions

The getTopNode() method can be used to get the expression tree after parsing an expression. This will be useful if you want to do more than just evaluate the expressions you parse. For example, you may want to determine the derivative of an expression. In order to be able to this, you will need direct access to the expression tree.

The expression tree consists of nodes. Each of the nodes in the parse tree is an object of one of the following types:

All of them extend the SimpleNode class (which implements the Node interface). Binary operators (+,-,*,/...) and functions are ASTFunNodes. The type of operator (the function class) is stored in the pfmc member, and as a string in the name member. Use the getPFMC() and getName() methods to access these members.

To traverse the expression tree you can use a visitor class (ParserDumpVisitor is an example class used to print out all the nodes). Look at the EvaluatorVisitor class to see how expressions are evaluated using the Visitor design pattern.



Using custom number classes

By default when an expression such as "1+2" is parsed, the constants "1" and "2" are created internally as Double objects. In most cases this is fine, but in some cases you may want to use custom classes for representing numbers.

This is made possible through creating a number class that implements the NumberFactory interface. It includes one method called createNumber(double value), which should return an object initialized to the value of the parameter. You can load your custom number factory with the JEP constructor JEP(boolean traverse_in, Boolean allowUndeclared_in, Boolean implicitMul_in, NumberFactory numberFactory_in).

The custom number objects need to be handled by custom functions which you can create by following the instructions on the Custom Functions page.






:: © 2000 Nathan Funk