2

I have to give the user the option to enter in a text field a mathematical formula and then save it in the DB as a String. That is easy enough, but I also need to retrieve it and use it to do calculations.

For example, assume I allow someone to specify the formula of employee salary calculation which I must save in String format in the DB.

GROSS_PAY = BASIC_SALARY - NO_PAY + TOTAL_OT +  ALLOWANCE_TOTAL

Assume that terms such as GROSS_PAY, BASIC_SALARY are known to us and we can make out what they evaluate to. The real issue is we can't predict which combinations of such terms (e.g. GROSS_PAY etc.) and other mathematical operators the user may choose to enter (not just the +, -, ×, / but also the radical sigh - indicating roots - and powers etc. etc.). So how do we interpret this formula in string format once where have retrieved it from DB, so we can do calculations based on the composition of the formula.

Miy
  • 45
  • 7
  • @a_horse_with_no_name I tried to do that, but didn't work. Thnx –  Miy Sep 09 '16 at 10:19
  • You can try a regular Expression (or sth. else (Write a parse Method where you split an pick out all of them) to pick out all Operators and do what you want with it. Because there is no possibility to "convert a String into Operator". – Markus G. Sep 09 '16 at 10:31
  • did you figure out how to implement this? – dhiraj suvarna Mar 06 '19 at 18:30
  • No, actually; I did not get to implement this. But thanks to all those who answered. I've also now chosen an answer, that I think explains the best approach to this/how I would have gone about this if I had had to implement this. Thanks again. –  Miy Mar 08 '19 at 01:11

3 Answers3

1

as of Evaluating a math expression given in string form there is a JavaScript Engine in Java which can execute a String functionality with operators.

Hope this helps.

Community
  • 1
  • 1
kism3t
  • 1,343
  • 1
  • 14
  • 33
  • You hardly need to go to such indirection to get an expression evaluator. You can do such expression evaluatio in Java directly.. – Ira Baxter Sep 09 '16 at 12:02
  • Hey Ira, sure it is also possible in java. I would have in mind, as Markus, regular Expression. What and how would your suggestion be? – kism3t Sep 09 '16 at 12:05
  • Regex is always the wrong answer when it comes to parsing; it can't handle nested parentheses. See the answer I just provided. – Ira Baxter Sep 09 '16 at 12:08
1

Building an expression evaluator is actually fairly easy.

See my SO answer on how to write a parser. With a BNF for the range of expression operators and operands you exactly want, you can follow this process to build a parser for exactly those expressions, directly in Java.

The answer links to a second answer that discusses how to evaluate the expression as you parse it.

So, you read the string from the database, collect the set of possible variables that can occur in the expression, and then parse/evaluate the string. If you don't know the variables in advance (seems like you must), you can parse the expression twice, the first time just to get the variable names.

Community
  • 1
  • 1
Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
0

You could build a string representation of a class that effectively wraps your expression and compile it using the system JavaCompiler — it requires a file system. You can evaluate strings directly using javaScript or groovy. In each case, you need to figure out a way to bind variables. One approach would be to use regex to find and replace known variable names with a call to a binding function:

getValue("BASIC_SALARY") - getValue("NO_PAY") + getValue("TOTAL_OT") +  getValue("ALLOWANCE_TOTAL")

or

getBASIC_SALARY() - getNO_PAY() + getTOTAL_OT() + getALLOWANCE_TOTAL()

This approach, however, exposes you to all kinds of injection type security bugs; so, it would not be appropriate if security was required. The approach is also weak when it comes to error diagnostics. How will you tell the user why their expression is broken?

An alternative is to use something like ANTLR to generate a parser in java. It's not too hard and there are a lot of examples. This approach will provide both security (users can't inject malicious code because it won't parse) and diagnostics.

John Morris
  • 396
  • 2
  • 10