|
|
ru.algorithms- RU.ALGORITHMS ---------------------------------------------------------------- From : Artem Gubenkov 2:5020/400 15 May 2002 01:40:58 To : Alex Astafiev Subject : Re: Парсер математических выражений -------------------------------------------------------------------------------- Здраствуйте, Alex! Mon, 13 May 2002 13:04:10 Вы писали к Alexey Moiseev: AM>> P.S.: вообще я в свое время делал программу которая с учетом AM>> приоритета опреаций вычисляет результат выражения, но она AM>> примитивная: AM>> нет скобок и логических операций. Если надо могу кинуть. AA> Кидай. Смотрю я тут на все это и решил рассказать о клевом таком компоненте для Delphi\C++Builder, который нашел на каком-то сборнике, и очень в свое время оказался рад: =======parcer10.txt, однако========== TParser parses and evaluates mathematical expressions specified at runtime. Its performance is remarkable - only 40-80% slower than similar compiled expression - and it is by far the fastest parser on the freeware market. The programming interface is simple: - specify values for predefined variables in properties A,B,C,D,E,X,Y or T; - optionally add new variables or removing existing ones; - specify expression to be evaluated in Expression property; - optionally change value of variables - retrieve computed value in Value property. Example: Parser1.X := 100; Parser1.Y := 200; Parser1.Variable['z'] := 20; Parser1.Expression := 'sin(x)*cos(y)+z'; Result := Parser1.Value; If you want to compute several values of the same expression with different sets of variables, specify the expression once ONLY as this operation is rather time consuming, then assign new values for variables and retrieve the Value property as many times as you wish. Example: for i := 1 to 100 do begin Parser1.X := i; Result := Parser1.Value; end; You also may add your own variables by specifying their names and values using the SetVariable method, accessing them via a property or through direct memory access. (as usual variable names are not case-sensitive). Example (the following lines are all equivalent): (1) Parser1.Variable['Test'] := 100; Test := Parser1.Variable['Test']; (2) Parser1.SetVariable('Test', 100); Test := Parser1.GetVariable('Test'); (3) var PTest : PParserFloat; { pointer to memory } PTest := Parser1.SetVariable('Test', 100); PTest^ := 200; { set 'Test' = 200 } Test := PTest^; There is no limit for expression length in the 32bit version, while the 16bit version has a restriction of 255 characters. Predefined variables: PI Accepted operators: + , - , * , / , ^ , MOD, DIV [ MOD and DIV implicitly perform a trunc() on their operands ] The following functions are supported; it doesn't matter if you use lower or upper case: [ NOTE: to activate some additional functions you need to remove the SpeedCompare conditional define in PARSER10.PAS ! ] COS, SIN, SINH, COSH, TAN, COTAN, ARCTAN, ARG, EXP, LN, LOG10, LOG2, LOGN, SQRT, SQR, POWER, INTPOWER, MIN, MAX, ABS, TRUNC, INT, CEIL, FLOOR, HEAV (heav(x) is =1 for x>0 and =0 for x<=0), SIGN (sign(x) is 1 for x>1, 0 for x=0, -1 for x<0), ZERO (zero(x) is 0 for x=0, 1 for x<>0), PH (ph(x) = x - 2*pi*round(x/2/pi)) RND (rnd(x) = int(x) * Random) RANDOM (random(X) = Random; the argument X is not used) Adding your own functions is easy, too. Either use ... AddFunctionOneParam or AddFunctionTwoParam ... if you do not want to create a new class, or create a new class, inheriting from TParser and add your functions to the lists, as demonstrated in TParser.Create. IMPORTANT: DO NOT USE BLANKS (#32) IN THE EXPRESSION. THE PARSER IS UNABLE TO HANDLE THESE (and raises an exception in response). You can use bracketing (nestings) up to a level of 20. This can be increased at the expense of stack consumption by changing maxBracketLevels = 20; in P10BUILD.PAS. This should not be a problem. If you get a "Expression too complex" exception increase maxLevelWidth = 50; in P10BUILD.PAS. This should never happen. You can define your OWN variables at RUNTIME, in code you will use Parser1.Variable.Add('NAME', 123456) or simply (but slow) Parser1.Variable['ANOTHER'] := 1.23 =======parcer10.txt закончился========== Hу и еще там на Exception-ы ошибки завязаны. Вобщем, кому надо (он с исходниками 70Кб, я когда-то даже в них разобрался), велком в мыло :) WBR, Artem Gubenkov. E-mail: 006955@saronline.ru --- ifmail v.2.15dev5 * Origin: News Server of JSC Saratov-Mobile (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/10638c0629b96.html, оценка из 5, голосов 10
|