English Français Deutsch

Home Features Demos Download Installation User Manual Developer Manual Credits


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.


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",")"}


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")


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.