For example: 1. CalceXPR ('2 * 5 1') = '11' 2. Condition Calcexpr ('2> 1 & 4 <= 5: 2 * 5') = '10' Calcexpr ('6 <2: 3' ) = '0' 3. Tape function CALCEXPR ('max (1, 2, 3, 6, 4 7, 7)') = '11'
Usage: Add uncalc.pas to your project and then call CalceXPR.
Here is the source code:
Unit unpjcalc;
Interface
Uses classes, sysutils;
type TJStack = class private Lines: TStrings; public constructor Create; destructor Destroy; procedure init; procedure push (s: string); function GetTop: String; function Pop: String; end; TJExpr = class private Expr: String; Position: Integer MIN, MAX: INTEGER; EOF: Boolean; Public Constructor Creter (PEXPR: String); function read: string; process;
function CalcExpr (sExpr: String): String; function CalcExprItem (sOptr, sA, sB: String): String; function OptrIndex (w: string): Integer; function GetParamCount (pFunc: String): Integer; function ExecFunc (pFunc: String PParam: Array Of String; PParamcount: Integer: String;
IMPLEMENTATION
Constructor tjstack.create; begin inherited create;
Procedure tjstack.init; begin lines.free;
DESTRUCTOR TJSTACK.DESTROY; begin lines.free; inherited destroy;
Procedure tjstack.push (s: string); begin lines.add (s); end;
Function TJSTACK.GETTOP: STRING; Begin if lines.count> 0 Then Result: = lines [lines.count-1] else result: = '; end;
Function TJSTACK.POP: STRING; Begin if lines.count> 0 Then Begin Result: = Gettop; Lines.delete (LINES.COUNT-1); Else Result: = '; end; // tjexpr
Constructor tjexpr.create (pexpr: string); begin expr: = Lowercase (PEXPR) '#'; min: = 1; max: = length (expr); Position: = 1; EOF: = FALSE; END;
Function tjexpr.read:String; Function Sametype (S1, S2: String): Boolean; Var C1, C2: String; Begin C1: = '; C2: ='; if Length (S1)> 0 THEN C1: = S1 [Length (S1)]; if Length (S2)> 0 THEN C2: = S2 [Length (S2)]; IF ((POS (C1, '0123456789.')> 0) AND (POS (C2, '0123456789 . ')> 0)) The begin result: = true; END ELSE begin Result: = false; end; if (c1 =' - ') and (c2 =' - ') THEN Result: = false; if S1 S2 = '> =' Ten Result: = true; if S1 S2 = '<=' TENRE: = true; if S1 S2 = '<>' Then Result: = true; if POS (S1 S2, 'MAX (')> 0 Then Result: = true; if POS (' - ', S1 S2)> 1 Then Res: = false; if (S1 =') or (S2 = ') THEN Result: = true; End; begin if position <= max life begin result: = trim (expr [position]); inc (position); while position <= max do begin if Sametype (Result, expr [position]) THEN BEGIN Result: = Result TRIM (expr [position]); inc (position); end Else Begin Exit; End; End; Else Begin Result: = '; EOF: = true; end; end; procedure tjexpr.gofirst; begin position: = 1; EOF: = false;
/
Function Diffoptr (A, B: String): Integer; Const Sa: Array [1..17, 1..17] of integer = (/ - * / () #> <> = <= = <> & :, Max ({ } (2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0), {-} (2, 2 , 0, 0, 0, 2, 2, 2, 2, 2, 2, 0), {*} (2, 2, 2, 2, 0, 2, 2) 2, 2, 2, 2, 2, 2, 2, 2, 2, 0), {/} (2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2) , 2, 2, 2, 0), {(} (0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0), { (2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1), {#} (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), {>} (0, 0, 0, 0, 0, 2, 2, 2, 2, 2) , 2, 2, 2, 2, 2, 2, 0), {<} (0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,) 2, 0), {> =} (0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0), {<=} 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0), {=} (0, 0, 0, 0, 0, 2 , 2, 2, 2, 2, 2, 2, 2, 2, 2, 0), {<>} (0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2) , 2, 2, 2, 2, 2, 0), {&} (0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2) 0 ), {:} (0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0), {,} (0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0), {max (} (0, 0, 0, 0, 0, 1, 2, 0) , 0, 0, 0, 0)); var aindex, bindex: integer; begin aindex: = optrindex (a); bindex: = optrindex (b); if (Aindex> 0 ) and (bindex> 0) Then Result: = sa [aindex, bindex] -1 else result: = 1;
Function Calcexpr (Sexpr: String): String; Var Optr, Opnd: TJStack; W, Theta, A, B: String; Position: Integer; Jexpr: Tjexpr; Spram: Array [1..20] of string; sfunc: string I, nParamcount: integer; begin jexpr: = tjexpr.create (sexpr); optr: = tjstack.create; opTr.push ('#'); w: = jexpr.read; while NOT ((w = '#') and (optr.gettop = '#'))))))))) "AND (JEXPR.EOF = false) DO Begin if Optrindex (W) <0 Then Begin Opnd.push (W); W: = JEXPR.READ; ELSE BEGIN CASE DIFFOPTR (Optr.gettop, W) of -1: //
Function Calcexpritem (Soptr, SA, SB: STRING): String; Begin if Soptr = ' ' TENBEGIN IF (SA <> ') And (SB <>') THEN Begin Result: = FLOATTOSTR (STRTOFLOAT (SA) STRTOFLOAT (SB)); END ELSE BEGIN RESULT: = SA Sb; if Result = '' Then Result: = '0'; End; EXIT; End; if Soptr = '-' Then Begin if SA = '' THEN Result: = floattostr (-strtofloat (sb)) Else Res: = floattostr (STRTOFLOAT (SA) -strtofloat (SB)); exit; end; if Soptr = '*' Then Begin Result: = floattostr (STRTOFLOAT (SA) * STRTOFLOAT (SB)); EXIT; End; if Soptr = '/' Then Begin Result: = FLOATTOSTR (STRTOFLOAT / STRTOFLOAT; EXIT; END; if Soptr = '>' Then Begin if stratofloat (sa > StrtOFLOAT (SB) THEN RESULT: = '1' else result: = '0'; exit; end; if Soptr = '<' The begin if straofloat (SA)
Else Result: = '0'; EXIT; END; if Soptr = '<>' Then Begin if straofloat (SA) <> strand (sb) Then Result: = '1' else result: = '0'; exit; If Soptr = '&' Then Begin IF (STRTOFLOAT (SA) <> 0) and (strtofloat (SB) <> 0) THEN Result: = '1' else result: = '0'; exit; end; if Soptr = ':' Then Begin if strand (sa) = 0 Then Result: = '0' else result: = sb; exit; end; end; function getParamcount (pfunc: string): integer; begin if pfunc = 'max (' Then Result: = 2;
Function Optrindex (W: String): Integer; Begin If W = ' ' TEN BEGIN Res: = 1; EXIT; End; if W = '-' Then Begin Result: = 2; EXIT; End; if W = '* 'Ten Begin Result: = 3; EXIT; END; if W =' / 'Then Begin Result: = 4; EXIT; END; IF W =' ('Then Begin Result: = 5; EXIT; END; if W =' ) 'Then Begin Result: = 6; EXIT; END; if w =' # 'Then Begin Result: = 7; EXIT; END; if W ='> 'Then Begin Result: = 8; EXIT; END; if w = '<' Then Begin Result: = 9; EXIT; End; IF W = '> =' Then Begin Result: = 10; EXIT; END; if W = '<=' Then Begin Result: = 11; EXIT; IF w = '=' Then Begin Result: = 12; exit; end; if w = '<>' Then Begin Result: = 13; exit; end; if w = '&' Then Begin Result: = 14; End; if w = ':' Then Begin Result: = 15; EXIT; END; if w = ',' Then Begin Result: = 16; EXIT; END; if w = 'max (' the begin Result: = 17; EXIT; End; Result: = - 1; End; Function Execfunc (PFUNC: String; PParam: Array Of; PPAramcount: Integer: string; var tmpfloat: real; i: integer; begin // if pfunc = 'max ( 'Then Begin Tmpfloat: = Strtof Loat (pParam [0]); for i: = 1 to PParamcount-1 Do Begin if Tmpfloat End.