javaexpressionevaluator

evaluating expressions containing functions in java


I have written a project that calculates different functions like sine,MCM etc without using existing packages like math in java now I want to get an expression from the user in form of a string and then print out the result
like :

import java.util.Scanner;

public class Phase2main {

public static void main(String[] args) {

    Scanner s = new Scanner(System.in);
    String expression   ;
    double result = 0 ;

    System.out.println(" Enter your desired expression from the available functions ");

    expression = s.nextLine();


    System.out.println("Result is : " + result);                
 }
}

then it should run like this: Enter an Expression: ADD(DIV(SIN(FACT(3)),CEIL(TAN(MUL(1.5,FIB(4))))),GCD(2,10)) The Result is: 1.94

how can I make the program to identify my functions like CEIL and their input ? I've checked many of the similar questions but the ones that I found are rather libraries that are too complex for me to understand or do basic arithmetic without identifying functions and their inputs

so how can I write a simple evaluator for this specific problem?


Solution

  • May be use JavaScript interpreter?

    First create engine instance and init:

    // Manager creates engines by mime/language names.
    // It has own global scope for engiges created by it.
    ScriptEngineManager manager = new ScriptEngineManager();
    // Create JavaScript interpreter instance.
    // (Nashorn is bundled JavaScript interpreter)
    ScriptEngine scope = manager.getEngineByName("JavaScript");
    // Define functions you need
    String initialScript = "cos = Math.cos;" // ; or \n
        + "sin = Math.sin;"
        + "tg  = Math.tan;"
        + "PI  = Math.PI;"
    // Any other function
        + "ctg = function (x) { return cos(x)/sin(x); };";
    // ...
    
    try {
        // Add these functions to scope
        scope.eval(initialScript);
    } catch(ScriptException ex) {
        // Evaluating exceptions, syntax errors are thrown here
    }
    

    And then you can evaluate expressions in the "scope" many times:

    try {
        double d = (double)scope.eval("sin(PI/2) + cos(PI/2)");
        System.out.println("Calculated: " + d);
    } catch(ScriptException e) {
        // ...
    }
    

    Be warned:

    1. There is language interpreting - user can pass any script and...
    2. ... it can reduce perfomance of application.

    You can also use, for example, Jython or JRuby as interpreter.