Home Features Demos Download Installation User Manual Developer Manual Relation function Credits

Login

Expression parser

The relation function uses an expression parser which is designed from the ground, eg. without use of an eval() function which would be a security risk.

The expression parser (swExpression in inc-expression.php) transforms algebraic expressions and evaluates them with a series of given values.

The expression parser accepts algebraic expressions with values and inline operators

  • 4 +3
  • 4 * 3 + 5
  • 4 * (3 + 5)

The expression usually has variables (starting with a letter) and pointers (indirect variables, starting with a ^)
  • 4 * 3 + a
  • 4 * 3 + ^a

The expression can have functions
  • max(4, 3)

The values can be numbers or strings. The context defines if a value is considered as number or string because each operator or function only accepts either numbers or strings
  • replace("old","new",text)

All operators are documented in https://www.belle-nuit.com/relation/expressions

The expression parsers works in 3 steps: tokenize, compile, evaluate. Tokenize and compile happen only once, evaluate for each row.

Tokenize

The expression string is transformed in an array with tokens.

Numbers, symbolic operators and names are tokenised literally.

"4 * 3 + a" becomes {"4", "*", "3", "+", "a"}

Strings are transformed to a hex representation of the string and are preceded by #.

""ab" . "c"" becomes {"#6162",".","#63"}

Function names are preceded by @

"sin(5)" becomes {"@(sin","5",")"}

Compile

The tokenised array is transformed to an array in RPN notation (reverse polish notation, like HP calculators). It uses the shunting-yard algorithm that keeps to running stacks and orders the tokens by operator precedence. It interpreted the tokens and replaces operators with their name.

{"4", "*", "3", "+", "a"} becomes {"4","3",":mul","a","::add"}
{"#6162",".","#63"} becomes {"#6162","#63",":concat"}
{"@(sin","5",")"} becomes {"5", ":sin")

Evaluate

The RPN stack is evaluated using given values for the variables. For the variables, there is a cascading precedence row value over local value over global value.