Expression Evaluator

Please discuss general Delphi programming topics here.

Expression Evaluator

Postby Kambiz » July 5th, 2008, 6:44 pm

Recently I had to write an arithmetic expression evaluator function. I thought maybe someone needs such a function.

This expression evaluator accepts variables and custom functions. Here is the list of stuffs you find in this unit:

Code: Select all
{------------------------------------------------------------------------------}
{                             R E F E R E N C E                                }
{------------------------------------------------------------------------------}
{                                                                              }
{  type EEvaluateError = class(Exception)                                      }
{                                                                              }
{  If expression evaluation fails, this exception will be raised.              }
{  This exception contains the following information:                          }
{                                                                              }
{    * Message: String;                                                        }
{      The message describing the error.                                       }
{    * Expression: String;                                                     }
{      The expression that has raised the exception.                           }
{    * Offset: Integer;                                                        }
{      The offset of error from start of expression.                           }
{                                                                              }
{------------------------------------------------------------------------------}
{                                                                              }
{  type TCustomFunc = function(const FuncName: String;                         }
{     const Params: array of Double; var Value: Double): Boolean;              }
{                                                                              }
{  This is type of callback function that will be called when expression       }
{  evaluator encounters an undefined function.                                 }
{                                                                              }
{------------------------------------------------------------------------------}
{                                                                              }
{  function CallFunc(const Name: String;                                       }
{     const Params: array of Double): Double;                                  }
{                                                                              }
{  Returns the result of calling the function specified by the Name parameter  }
{  with the arguments specified by the Params parameter.                       }
{                                                                              }
{  Example:                                                                    }
{                                                                              }
{     Value := CallFunc('Power', [2, Exponent]);                               }
{                                                                              }
{------------------------------------------------------------------------------}
{                                                                              }
{  function Evaluate(const Expression: String;                                 }
{     CustomFuncHandler: TCustomFuncEvent = nil): Double;                      }
{                                                                              }
{  Returns the value of an expression.                                         }
{                                                                              }
{  Example 1:                                                                  }
{                                                                              }
{     Value := Evaluate('2 * Sin(Pi * 45)');                                   }
{                                                                              }
{  Example 2:                                                                  }
{                                                                              }
{     function MyCustomFunc(const FuncName: String;                            }
{        const Params: array of Double; var Value: Double): Boolean;           }
{     begin                                                                    }
{       Result := False;                                                       }
{       if SameText(FuncName, 'Cube') and (Length(Params) = 1) then            }
{       begin                                                                  }
{         Value := Params[0] * Params[0] * Params[0];                          }
{         Result := True;                                                      }
{       end;                                                                   }
{     end;                                                                     }
{                                                                              }
{     Value := Evaluate('2 * Cube(10) + 1', @MyCustomFunc);                    }
{                                                                              }
{------------------------------------------------------------------------------}
{                                                                              }
{  function Evaluate(const Expression: String;                                 }
{     const VarNames: array of String; const VarValues: array of Double;       }
{     CustomFuncHandler: TCustomFuncEvent = nil): Double;                      }
{                                                                              }
{  Returns the value of an expression with variable referencing.               }
{                                                                              }
{  Example:                                                                    }
{                                                                              }
{     Value := Evaluate('(a + b) / c', ['a', 'b', 'c'], [a, b, c]);            }
{                                                                              }
{------------------------------------------------------------------------------}

{------------------------------------------------------------------------------}
{                  P R E D E F I N E D   F U N C T I O N S                     }
{------------------------------------------------------------------------------}
{                                                                              }
{  Abs(X)                                                                      }
{  Int(X)                                                                      }
{  Frac(X)                                                                     }
{  Ceil(X)                                                                     }
{  Floor(X)                                                                    }
{  Sign(X)                                                                     }
{  Sqrt(X)                                                                     }
{  Sqr(X)                                                                      }
{  Hypot(X, Y)                                                                 }
{  Mod(Dividend, Divisor)                                                      }
{                                                                              }
{  Sin(X)                                                                      }
{  Cos(X)                                                                      }
{  Tan(X)                                                                      }
{  Cotan(X)                                                                    }
{  Secant(X)                                                                   }
{  Cosecant(X)                                                                 }
{  Cot(X)                                                                      }
{  Sec(X)                                                                      }
{  Csc(X)                                                                      }
{  CosH(X)                                                                     }
{  SinH(X)                                                                     }
{  TanH(X)                                                                     }
{  CotH(X)                                                                     }
{  SecH(X)                                                                     }
{  CscH(X)                                                                     }
{  ArcCos(X)                                                                   }
{  ArcSin(X)                                                                   }
{  ArcTan(X)                                                                   }
{  ArcTan2(Y, X)                                                               }
{  ArcCot(X)                                                                   }
{  ArcSec(X)                                                                   }
{  ArcCsc(X)                                                                   }
{  ArcCosH(X)                                                                  }
{  ArcSinH(X)                                                                  }
{  ArcTanH(X)                                                                  }
{  ArcCotH(X)                                                                  }
{  ArcSecH(X)                                                                  }
{  ArcCscH(X)                                                                  }
{                                                                              }
{  Ln(X)                                                                       }
{  LnXP1(X)                                                                    }
{  Log10(X)                                                                    }
{  Log2(X)                                                                     }
{  LogN(Base, X)                                                               }
{  Power(Base, Exponent)                                                       }
{  Exp(X)                                                                      }
{                                                                              }
{  RadToDeg(Radians)                                                           }
{  RadToGrad(Radians)                                                          }
{  RadToCycle(Radians)                                                         }
{  DegToRad(Degrees)                                                           }
{  DegToGrad(Degrees)                                                          }
{  DegToCycle(Degrees)                                                         }
{  GradToRad(Grads)                                                            }
{  GradToDeg(Grads)                                                            }
{  GradToCycle(Grads)                                                          }
{  CycleToRad(Cycles)                                                          }
{  CycleToDeg(Cycles)                                                          }
{  CycleToGrad(Cycles)                                                         }
{                                                                              }
{  Max(A, B)                                                                   }
{  Min(A, B)                                                                   }
{                                                                              }
{  IfZero(X, TrueValue, FalseValue)                                            }
{  IfNegative(X, TrueValue, FalseValue)                                        }
{  IfPositive(X, TrueValue, FalseValue)                                        }
{                                                                              }
{------------------------------------------------------------------------------}
Attachments
ExpEval.zip
Expression Evaluator + Example Code + Example Executable
(219.75 KiB) Downloaded 237 times
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2429
Joined: March 7th, 2003, 7:10 pm

Postby kokkoras » July 7th, 2008, 2:33 am

very nice! thank you.
Fotis
User avatar
kokkoras
Moderator
Moderator
 
Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece


Return to Delphi Programming

Who is online

Users browsing this forum: No registered users and 3 guests

cron