# 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.