2

i want evaluate at runtime some string expression like:

((foo = true) or (bar <> 'test')) and (baz >= 1)

The string are inputted by user. The user can create a rule by coupling a property choised from a set (eg. foo, bar, baz), inputting the target value to evaluate (string, number and boolean) and choising the operator (=, <>, >, <), eg.:

| Id | Property | Operator | Value  |   Expression                                        |
-------------------------------------------------------------------------------------------
| $1 |   foo    |    =     |  true  | (foo = true)                                        |
-------------------------------------------------------------------------------------------
| $2 |    bar   |    <>    | 'test' | (bar <> 'test')                                     |
-------------------------------------------------------------------------------------------
| $3 |    baz   |    >=    |   1    | (baz >= 1)                                          |
-------------------------------------------------------------------------------------------

the single rule can be coupled and nested in child/parent rule by choosing an operator like and, or, eg.:

| Id | Property | Operator | Value  |   Expression                                        |
-------------------------------------------------------------------------------------------
| $1 |   foo    |    =     |  true  | (foo = true)                                        |
-------------------------------------------------------------------------------------------
| $2 |    bar   |    <>    | 'test' | (bar <> 'test')                                     |
-------------------------------------------------------------------------------------------
| $3 |    baz   |    >=    |   1    | (baz >= 1)                                          |
-------------------------------------------------------------------------------------------
| $4 |    $1    |    or    |  $2    | ((foo = true) or (bar <> 'test'))                   |
-------------------------------------------------------------------------------------------
| $5 |    $4    |   and    |  $3    | ((foo = true) or (bar <> 'test')) and (baz >= 1)    |
-------------------------------------------------------------------------------------------

in peseudo code, the idea is:

aExpressionEngine := TExpressionEngine.Create;
try
    // Adds to the evaluation scope all the properties with the
    // inputted value. AddToScope accept string, variant
    aExpressionEngine.AddToScope('foo', false);
    aExpressionEngine.AddToScope('bar', 'qux');
    aExpressionEngine.AddToScope('baz', 10);

    // evaluate the expression, the result is always a boolean
    Result := aExpressionEngine.eval('(((foo = true) or (bar <> ''test'')) and (baz >= 1))');
finally
    aExpressionEngine.free;
end;

in this pseudo code example, the expression to evaluate become (after replacing the properties with the scope value):

(((false = true) or ('qux' <> 'test')) and (10 >= 1)) // TRUE

by googling, i have found a bit of library for evaluate math expression, but nothing for logical condition evaluating.

Has delphi something for evaluate string expression?

Simone Nigro
  • 4,717
  • 2
  • 37
  • 72
  • If the strings are not too large, you may be able to replace them with long integers. – Jean-Claude Colette Jul 29 '17 at 13:22
  • @Jean-ClaudeColette yes, good idea! thanks! but if exists an eval() way it's better! – Simone Nigro Jul 29 '17 at 13:24
  • 4
    These languages are interpreted, and they simply pass the condition to be evaluated through their interpreter. Delphi is a compiled language, and has no interpreter. Of course you could write an interpreter for simple expressions, but I don't think there is an existing one. It would be similar to the ones that evaluate arithmetic expressions, but it would have to be extended to evaluate string expressions. Not really a "simple operator". And `('baz' <> 0)` would be invalid anyway. – Rudy Velthuis Jul 29 '17 at 15:12
  • 2
    Perhaps you could build such an expression using Variants. It would still be some work. It would have to parse and interpret such expressions, in other words, you would be building a simple interpreter. – Rudy Velthuis Jul 29 '17 at 15:17
  • How will you evaluate this? Where will you get the variables from? – David Heffernan Jul 29 '17 at 17:10
  • One also wonders how you imagine comparison of string and integer to work – David Heffernan Jul 29 '17 at 18:33
  • Comparate string and integer it's a my mistake into the example. – Simone Nigro Jul 29 '17 at 19:04
  • 1
    Maybe [TBindingExpression](http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Bindings.Expression.TBindingExpression). – Victoria Jul 29 '17 at 20:20
  • 3
    Have you checked this out ? https://stackoverflow.com/questions/572796/best-algorithm-for-evaluating-a-mathematical-expression I know the title says c#, but the accepted answer is for Delphi. – Dsm Jul 29 '17 at 20:29
  • 1
    Maybe overkill, but perhaps what you want is... http://www.remobjects.com/ps.aspx – J... Jul 29 '17 at 20:51
  • 1
    All I can say is DWScript. That is not an answer, but an option. I've used it in the past to store instructions for drawing graphics. So that the user can create their own script file to paint to a canvas. Can also be used for general expressions too. – Jerry Dodge Jul 29 '17 at 23:27
  • @David Those don't look like variables. They look like value types. – Jerry Dodge Jul 29 '17 at 23:29
  • 2
    Delphi does indeed have the ability to compile and evaluate expressions- see https://theroadtodelphi.com/2012/07/06/a-quick-guide-to-evaluate-and-compile-expressions-using-the-livebindings-expression-evaluator/ and this code by Nick Hodges - https://bitbucket.org/NickHodges/nickdemocode/src/842eb3fc74d7/SampleExpressionEvaluator.dpr?at=default&fileviewer=file-view-default – alcalde Jul 30 '17 at 01:34
  • @Victoria thanks, i have also found this example https://stackoverflow.com/questions/16650447/building-and-evaluating-expressions-using-delphi-rtti/16651657#16651657 – Simone Nigro Jul 30 '17 at 08:36
  • 1
    thanks all for the suggestions, after some downvotes i have totally update my question with more details and a pratical example. – Simone Nigro Jul 30 '17 at 09:39
  • 1
    Asking for external sources is off topic here. A brief search found these examples: [Components|Science|Expressions](http://torry.net/pages.php?id=307). – LU RD Jul 30 '17 at 16:21

0 Answers0