[Delphi (Object Pascal)] Delphi自定义可以直接执行运算表达式的类 →→→→→进入此内容的聊天室

来自 , 2021-03-10, 写在 Delphi (Object Pascal), 查看 162 次.
URL http://www.code666.cn/view/acaa23f7
  1. { ****************************************** }
  2. {                                            }
  3. { 四则运算的类                               }
  4. {                                            }
  5. {                                            }
  6. {                                  tansoo.cn }
  7. {                                     2005.3 }
  8. { ****************************************** }
  9.  
  10. unit Calc;
  11.  
  12. interface
  13.  
  14. uses Classes, Variants, SysUtils;
  15.  
  16. type
  17.   TGetPValueEvent = procedure(const s: String; var v: Variant) of object;
  18.   TFunctionEvent = procedure(const Name: String; p1, p2, p3: Variant;
  19.     var Val: Variant) of object;
  20.  
  21.   TCalcer = class
  22.   private
  23.     FOnGetValue: TGetPValueEvent;
  24.     FOnFunction: TFunctionEvent;
  25.     function GetIdentify(const s: String; var i: Integer): String;
  26.     function GetString(const s: String; var i: Integer): String;
  27.     procedure Get3Parameters(const s: String; var i: Integer;
  28.       var s1, s2, s3: String);
  29.   public
  30.     function Str2OPZ(s: String): String;
  31.     function CalcOPZ(const s: String): Variant;
  32.     function Calc(const s: String): Variant;
  33.     property OnGetValue: TGetPValueEvent read FOnGetValue write FOnGetValue;
  34.     property OnFunction: TFunctionEvent read FOnFunction write FOnFunction;
  35.   end;
  36.  
  37.   TVariables = class(TObject)
  38.   private
  39.     FList: TStringList;
  40.     procedure SetVariable(const Name: String; Value: Variant);
  41.     function GetVariable(const Name: String): Variant;
  42.     procedure SetValue(Index: Integer; Value: Variant);
  43.     function GetValue(Index: Integer): Variant;
  44.     procedure SetName(Index: Integer; Value: String);
  45.     function GetName(Index: Integer): String;
  46.     function GetCount: Integer;
  47.     procedure SetSorted(Value: Boolean);
  48.     function GetSorted: Boolean;
  49.   public
  50.     constructor Create;
  51.     destructor Destroy; override;
  52.     procedure Assign(Value: TVariables);
  53.     procedure Clear;
  54.     procedure Delete(Index: Integer);
  55.     function IndexOf(const Name: String): Integer;
  56.     procedure Insert(Position: Integer; const Name: String);
  57.     property Variable[const Name: String]
  58.       : Variant read GetVariable write SetVariable; default;
  59.     property Value[Index: Integer]: Variant read GetValue write SetValue;
  60.     property Name[Index: Integer]: String read GetName write SetName;
  61.     property Count: Integer read GetCount;
  62.     property Sorted: Boolean read GetSorted write SetSorted;
  63.   end;
  64.  
  65.   TFunctionSplitter = class
  66.   protected
  67.     FMatchFuncs, FSplitTo: TStrings;
  68.     FParser: TCalcer;
  69.     FVariables: TVariables;
  70.   public
  71.     constructor Create(MatchFuncs, SplitTo: TStrings; Variables: TVariables);
  72.     destructor Destroy; override;
  73.     procedure Split(s: String);
  74.   end;
  75.  
  76. function GetBrackedVariable(const s: String; var i, j: Integer): String;
  77.  
  78. implementation
  79.  
  80. type
  81.   PVariable = ^TVariable;
  82.  
  83.   TVariable = record
  84.     Value: Variant;
  85.   end;
  86.  
  87. const
  88.   ttGe = #1;
  89.   ttLe = #2;
  90.   ttNe = #3;
  91.   ttOr = #4;
  92.   ttAnd = #5;
  93.   ttInt = #6;
  94.   ttFrac = #7;
  95.   ttUnMinus = #9;
  96.   ttUnPlus = #10;
  97.   ttStr = #11;
  98.   ttNot = #12;
  99.   ttMod = #13;
  100.   ttRound = #14;
  101.  
  102. function GetBrackedVariable(const s: String; var i, j: Integer): String;
  103. var
  104.   c: Integer;
  105.   fl1, fl2: Boolean;
  106. begin
  107.   j := i;
  108.   fl1 := True;
  109.   fl2 := True;
  110.   c := 0;
  111.   Result := '';
  112.   if (s = '') or (j > Length(s)) then
  113.     Exit;
  114.   Dec(j);
  115.   repeat
  116.     Inc(j);
  117.     if fl1 and fl2 then
  118.       if s[j] = '[' then
  119.       begin
  120.         if c = 0 then
  121.           i := j;
  122.         Inc(c);
  123.       end
  124.       else if s[j] = ']' then
  125.         Dec(c);
  126.     if fl1 then
  127.       if s[j] = '"' then
  128.         fl2 := not fl2;
  129.     if fl2 then
  130.       if s[j] = '''' then
  131.         fl1 := not fl1;
  132.   until (c = 0) or (j >= Length(s));
  133.   Result := Copy(s, i + 1, j - i - 1);
  134. end;
  135.  
  136. { TVariables }
  137.  
  138. constructor TVariables.Create;
  139. begin
  140.   inherited Create;
  141.   FList := TStringList.Create;
  142.   FList.Duplicates := dupIgnore;
  143. end;
  144.  
  145. destructor TVariables.Destroy;
  146. begin
  147.   Clear;
  148.   FList.Free;
  149.   inherited Destroy;
  150. end;
  151.  
  152. procedure TVariables.Assign(Value: TVariables);
  153. var
  154.   i: Integer;
  155. begin
  156.   Clear;
  157.   for i := 0 to Value.Count - 1 do
  158.     SetVariable(Value.Name[i], Value.Value[i]);
  159. end;
  160.  
  161. procedure TVariables.Clear;
  162. begin
  163.   while FList.Count > 0 do
  164.     Delete(0);
  165. end;
  166.  
  167. procedure TVariables.SetVariable(const Name: String; Value: Variant);
  168. var
  169.   i: Integer;
  170.   p: PVariable;
  171. begin
  172.   i := IndexOf(Name);
  173.   if i <> -1 then
  174.     PVariable(FList.Objects[i]).Value := Value
  175.   else
  176.   begin
  177.     New(p);
  178.     p^.Value := Value;
  179.     FList.AddObject(Name, TObject(p));
  180.   end;
  181. end;
  182.  
  183. function TVariables.GetVariable(const Name: String): Variant;
  184. var
  185.   i: Integer;
  186. begin
  187.   Result := Null;
  188.   i := IndexOf(Name);
  189.   if i <> -1 then
  190.     Result := PVariable(FList.Objects[i]).Value;
  191. end;
  192.  
  193. procedure TVariables.SetValue(Index: Integer; Value: Variant);
  194. begin
  195.   if (Index < 0) or (Index >= FList.Count) then
  196.     Exit;
  197.   PVariable(FList.Objects[Index])^.Value := Value;
  198. end;
  199.  
  200. function TVariables.GetValue(Index: Integer): Variant;
  201. begin
  202.   Result := 0;
  203.   if (Index < 0) or (Index >= FList.Count) then
  204.     Exit;
  205.   Result := PVariable(FList.Objects[Index])^.Value;
  206. end;
  207.  
  208. function TVariables.IndexOf(const Name: String): Integer;
  209. begin
  210.   Result := FList.IndexOf(Name);
  211. end;
  212.  
  213. procedure TVariables.Insert(Position: Integer; const Name: String);
  214. begin
  215.   SetVariable(Name, 0);
  216.   FList.Move(FList.IndexOf(Name), Position);
  217. end;
  218.  
  219. function TVariables.GetCount: Integer;
  220. begin
  221.   Result := FList.Count;
  222. end;
  223.  
  224. procedure TVariables.SetName(Index: Integer; Value: String);
  225. begin
  226.   if (Index < 0) or (Index >= FList.Count) then
  227.     Exit;
  228.   FList[Index] := Value;
  229. end;
  230.  
  231. function TVariables.GetName(Index: Integer): String;
  232. begin
  233.   Result := '';
  234.   if (Index < 0) or (Index >= FList.Count) then
  235.     Exit;
  236.   Result := FList[Index];
  237. end;
  238.  
  239. procedure TVariables.Delete(Index: Integer);
  240. var
  241.   p: PVariable;
  242. begin
  243.   if (Index < 0) or (Index >= FList.Count) then
  244.     Exit;
  245.   p := PVariable(FList.Objects[Index]);
  246.   Dispose(p);
  247.   FList.Delete(Index);
  248. end;
  249.  
  250. procedure TVariables.SetSorted(Value: Boolean);
  251. begin
  252.   FList.Sorted := Value;
  253. end;
  254.  
  255. function TVariables.GetSorted: Boolean;
  256. begin
  257.   Result := FList.Sorted;
  258. end;
  259.  
  260. { TCalcer }
  261. {$WARNINGS OFF}
  262.  
  263. function TCalcer.CalcOPZ(const s: String): Variant;
  264. var
  265.   i, j, k, i1, st, ci, cn: Integer;
  266.   s1, s2, s3, s4: String;
  267.   nm: Array [1 .. 32] of Variant;
  268.   v: Double;
  269. begin
  270.   st := 1;
  271.   i := 1;
  272.   nm[1] := 0;
  273.   Result := 0;
  274.   while i <= Length(s) do
  275.   begin
  276.     j := i;
  277.     case s[i] of
  278.       '+':
  279.         nm[st - 2] := nm[st - 2] + nm[st - 1];
  280.       ttOr:
  281.         nm[st - 2] := nm[st - 2] or nm[st - 1];
  282.       '-':
  283.         nm[st - 2] := nm[st - 2] - nm[st - 1];
  284.       '*', ttAnd:
  285.         nm[st - 2] := nm[st - 2] * nm[st - 1];
  286.       '/':
  287.         if nm[st - 1] <> 0 then
  288.           nm[st - 2] := nm[st - 2] / nm[st - 1]
  289.         else
  290.           nm[st - 2] := 0;
  291.       '>':
  292.         if nm[st - 2] > nm[st - 1] then
  293.           nm[st - 2] := 1
  294.         else
  295.           nm[st - 2] := 0;
  296.       '<':
  297.         if nm[st - 2] < nm[st - 1] then
  298.           nm[st - 2] := 1
  299.         else
  300.           nm[st - 2] := 0;
  301.       '=':
  302.         if nm[st - 2] = nm[st - 1] then
  303.           nm[st - 2] := 1
  304.         else
  305.           nm[st - 2] := 0;
  306.       ttNe:
  307.         if nm[st - 2] <> nm[st - 1] then
  308.           nm[st - 2] := 1
  309.         else
  310.           nm[st - 2] := 0;
  311.       ttGe:
  312.         if nm[st - 2] >= nm[st - 1] then
  313.           nm[st - 2] := 1
  314.         else
  315.           nm[st - 2] := 0;
  316.       ttLe:
  317.         if nm[st - 2] <= nm[st - 1] then
  318.           nm[st - 2] := 1
  319.         else
  320.           nm[st - 2] := 0;
  321.       ttInt:
  322.         begin
  323.           v := nm[st - 1];
  324.           if Abs(Round(v) - v) < 1E-10 then
  325.             v := Round(v)
  326.           else
  327.             v := Int(v);
  328.  
  329.           nm[st - 1] := v;
  330.         end;
  331.       ttFrac:
  332.         begin
  333.           v := nm[st - 1];
  334.           if Abs(Round(v) - v) < 1E-10 then
  335.             v := Round(v);
  336.  
  337.           nm[st - 1] := Frac(v);
  338.         end;
  339.       ttRound:
  340.         nm[st - 1] := Integer(Round(nm[st - 1]));
  341.       ttUnMinus:
  342.         nm[st - 1] := -nm[st - 1];
  343.       ttUnPlus:
  344.         ;
  345.       ttStr:
  346.         begin
  347.           if nm[st - 1] <> Null then
  348.             s1 := nm[st - 1]
  349.           else
  350.             s1 := '';
  351.           nm[st - 1] := s1;
  352.         end;
  353.       ttNot:
  354.         if nm[st - 1] = 0 then
  355.           nm[st - 1] := 1
  356.         else
  357.           nm[st - 1] := 0;
  358.       ttMod:
  359.         nm[st - 2] := nm[st - 2] mod nm[st - 1];
  360.       ' ':
  361.         ;
  362.       '[':
  363.         begin
  364.           k := i;
  365.           s1 := GetBrackedVariable(s, k, i);
  366.           if Assigned(FOnGetValue) then
  367.             FOnGetValue(s1, nm[st]);
  368.           Inc(st);
  369.         end
  370.       else
  371.       begin
  372.         if s[i] = '''' then
  373.         begin
  374.           s1 := GetString(s, i);
  375.           s1 := Copy(s1, 2, Length(s1) - 2);
  376.           while Pos('''' + '''', s1) <> 0 do
  377.             Delete(s1, Pos('''' + '''', s1), 1);
  378.           nm[st] := s1;
  379.           k := i;
  380.         end
  381.         else
  382.         begin
  383.           k := i;
  384.           s1 := GetIdentify(s, k);
  385.           if (s1 <> '') and (s1[1] in ['0' .. '9', '.', ',']) then
  386.           begin
  387.             for i1 := 1 to Length(s1) do
  388.               if s1[i1] in ['.', ','] then
  389.                 s1[i1] := DecimalSeparator;
  390.             nm[st] := StrToFloat(s1);
  391.           end
  392.           else if AnsiCompareText(s1, 'TRUE') = 0 then
  393.             nm[st] := True
  394.           else if AnsiCompareText(s1, 'FALSE') = 0 then
  395.             nm[st] := False
  396.           else if s[k] = '[' then
  397.           begin
  398.             s1 := 'GETARRAY(' + s1 + ', ' + GetBrackedVariable(s, k, i) + ')';
  399.             nm[st] := Calc(s1);
  400.             k := i;
  401.           end
  402.           else if s[k] = '(' then
  403.           begin
  404.             s1 := AnsiUpperCase(s1);
  405.             Get3Parameters(s, k, s2, s3, s4);
  406.             if s1 = 'COPY' then
  407.             begin
  408.               ci := StrToInt(Calc(s3));
  409.               cn := StrToInt(Calc(s4));
  410.               nm[st] := Copy(Calc(s2), ci, cn);
  411.             end
  412.             else if s1 = 'IF' then
  413.             begin
  414.               if Int(StrToFloat(Calc(s2))) <> 0 then
  415.                 s1 := s3
  416.               else
  417.                 s1 := s4;
  418.               nm[st] := Calc(s1);
  419.             end
  420.             else if s1 = 'STRTODATE' then
  421.               nm[st] := StrToDate(Calc(s2))
  422.             else if s1 = 'STRTOTIME' then
  423.               nm[st] := StrToTime(Calc(s2))
  424.             else if Assigned(FOnFunction) then
  425.               FOnFunction(s1, s2, s3, s4, nm[st]);
  426.             Dec(k);
  427.           end
  428.           else if Assigned(FOnGetValue) then
  429.             FOnGetValue(AnsiUpperCase(s1), nm[st]);
  430.         end;
  431.         i := k;
  432.         Inc(st);
  433.       end;
  434.     end;
  435.     if s[j] in ['+', '-', '*', '/', '>', '<', '=', ttGe, ttLe, ttNe, ttOr,
  436.       ttAnd, ttMod] then
  437.       Dec(st);
  438.     Inc(i);
  439.   end;
  440.   Result := nm[1];
  441. end;
  442. {$WARNINGS ON}
  443.  
  444. function TCalcer.GetIdentify(const s: String; var i: Integer): String;
  445. var
  446.   k, n: Integer;
  447. begin
  448.   n := 0;
  449.   while (i <= Length(s)) and (s[i] <= ' ') do
  450.     Inc(i);
  451.   k := i;
  452.   Dec(i);
  453.   repeat
  454.     Inc(i);
  455.     while (i <= Length(s)) and not(s[i] in [' ', #13, '+', '-', '*', '/', '>',
  456.       '<', '=', '(', ')', '[']) do
  457.     begin
  458.       if s[i] = '"' then
  459.         Inc(n);
  460.       Inc(i);
  461.     end;
  462.   until (n mod 2 = 0) or (i >= Length(s));
  463.   Result := Copy(s, k, i - k);
  464. end;
  465.  
  466. function TCalcer.GetString(const s: String; var i: Integer): String;
  467. var
  468.   k: Integer;
  469.   f: Boolean;
  470. begin
  471.   k := i;
  472.   Inc(i);
  473.   repeat
  474.     while (i <= Length(s)) and (s[i] <> '''') do
  475.       Inc(i);
  476.     f := True;
  477.     if (i < Length(s)) and (s[i + 1] = '''') then
  478.     begin
  479.       f := False;
  480.       Inc(i, 2);
  481.     end;
  482.   until f;
  483.   Result := Copy(s, k, i - k + 1);
  484.   Inc(i);
  485. end;
  486.  
  487. procedure TCalcer.Get3Parameters(const s: String; var i: Integer;
  488.   var s1, s2, s3: String);
  489. var
  490.   c, d, oi, ci: Integer;
  491. begin
  492.   s1 := '';
  493.   s2 := '';
  494.   s3 := '';
  495.   c := 1;
  496.   d := 1;
  497.   oi := i + 1;
  498.   ci := 1;
  499.   repeat
  500.     Inc(i);
  501.     if s[i] = '''' then
  502.       if d = 1 then
  503.         Inc(d)
  504.       else
  505.         d := 1;
  506.     if d = 1 then
  507.     begin
  508.       if s[i] = '(' then
  509.         Inc(c)
  510.       else if s[i] = ')' then
  511.         Dec(c);
  512.       if (s[i] = ',') and (c = 1) then
  513.       begin
  514.         if ci = 1 then
  515.           s1 := Copy(s, oi, i - oi)
  516.         else
  517.           s2 := Copy(s, oi, i - oi);
  518.         oi := i + 1;
  519.         Inc(ci);
  520.       end;
  521.     end;
  522.   until (c = 0) or (i >= Length(s));
  523.   case ci of
  524.     1:
  525.       s1 := Copy(s, oi, i - oi);
  526.     2:
  527.       s2 := Copy(s, oi, i - oi);
  528.     3:
  529.       s3 := Copy(s, oi, i - oi);
  530.   end;
  531.   if c <> 0 then
  532.     raise Exception.Create('');
  533.   Inc(i);
  534. end;
  535.  
  536. function TCalcer.Str2OPZ(s: String): String;
  537. label 1;
  538. var
  539.   i, i1, j, p: Integer;
  540.   stack: String;
  541.   res, s1, s2, s3, s4: String;
  542.   vr: Boolean;
  543.   c: Char;
  544.  
  545.   function Priority(c: Char): Integer;
  546.   begin
  547.     case c of
  548.       '(':
  549.         Priority := 5;
  550.       ')':
  551.         Priority := 4;
  552.       '=', '>', '<', ttGe, ttLe, ttNe:
  553.         Priority := 3;
  554.       '+', '-', ttUnMinus, ttUnPlus:
  555.         Priority := 2;
  556.       '*', '/', ttOr, ttAnd, ttNot, ttMod:
  557.         Priority := 1;
  558.       ttInt, ttFrac, ttRound, ttStr:
  559.         Priority := 0;
  560.     else
  561.       Priority := 0;
  562.     end;
  563.   end;
  564.  
  565.   procedure ProcessQuotes(var s: String);
  566.   var
  567.     i: Integer;
  568.   begin
  569.     if (Length(s) = 0) or (s[1] <> '''') then
  570.       Exit;
  571.     i := 2;
  572.     if Length(s) > 2 then
  573.       while i <= Length(s) do
  574.       begin
  575.         if (s[i] = '''') and (i < Length(s)) then
  576.         begin
  577.           Insert('''', s, i);
  578.           Inc(i);
  579.         end;
  580.         Inc(i);
  581.       end;
  582.   end;
  583.  
  584. begin
  585.   res := '';
  586.   stack := '';
  587.   i := 1;
  588.   vr := False;
  589.   while i <= Length(s) do
  590.   begin
  591.     case s[i] of
  592.       '(':
  593.         begin
  594.           stack := '(' + stack;
  595.           vr := False;
  596.         end;
  597.       ')':
  598.         begin
  599.           p := Pos('(', stack);
  600.           res := res + Copy(stack, 1, p - 1);
  601.           stack := Copy(stack, p + 1, Length(stack) - p);
  602.         end;
  603.       '+', '-', '*', '/', '>', '<', '=':
  604.         begin
  605.           if (s[i] = '<') and (s[i + 1] = '>') then
  606.           begin
  607.             Inc(i);
  608.             s[i] := ttNe;
  609.           end
  610.           else if (s[i] = '>') and (s[i + 1] = '=') then
  611.           begin
  612.             Inc(i);
  613.             s[i] := ttGe;
  614.           end
  615.           else if (s[i] = '<') and (s[i + 1] = '=') then
  616.           begin
  617.             Inc(i);
  618.             s[i] := ttLe;
  619.           end;
  620.  
  621.         1 :
  622.           if not vr then
  623.           begin
  624.             if s[i] = '-' then
  625.               s[i] := ttUnMinus;
  626.             if s[i] = '+' then
  627.               s[i] := ttUnPlus;
  628.           end;
  629.           vr := False;
  630.           if stack = '' then
  631.             stack := s[i] + stack
  632.           else if Priority(s[i]) < Priority(stack[1]) then
  633.             stack := s[i] + stack
  634.           else
  635.           begin
  636.             repeat
  637.               res := res + stack[1];
  638.               stack := Copy(stack, 2, Length(stack) - 1);
  639.             until (stack = '') or (Priority(stack[1]) > Priority(s[i]));
  640.             stack := s[i] + stack;
  641.           end;
  642.         end;
  643.       ';':
  644.         break;
  645.       ' ', #13:
  646.         ;
  647.     else
  648.       begin
  649.         vr := True;
  650.         s2 := '';
  651.         i1 := i;
  652.         if s[i] = '%' then
  653.         begin
  654.           s2 := '%' + s[i + 1];
  655.           Inc(i, 2);
  656.         end;
  657.         if s[i] = '''' then
  658.           s2 := s2 + GetString(s, i)
  659.         else if s[i] = '[' then
  660.         begin
  661.           s2 := s2 + '[' + GetBrackedVariable(s, i, j) + ']';
  662.           i := j + 1;
  663.         end
  664.         else
  665.         begin
  666.           s2 := s2 + GetIdentify(s, i);
  667.           if s[i] = '[' then
  668.           begin
  669.             s2 := s2 + '[' + GetBrackedVariable(s, i, j) + ']';
  670.             i := j + 1;
  671.           end;
  672.         end;
  673.         c := s[i];
  674.         if (Length(s2) > 0) and (s2[1] in ['0' .. '9', '.', ',']) then
  675.           res := res + s2 + ' '
  676.         else
  677.         begin
  678.           s1 := AnsiUpperCase(s2);
  679.           if s1 = 'INT' then
  680.           begin
  681.             s[i - 1] := ttInt;
  682.             Dec(i);
  683.             goto 1;
  684.           end
  685.           else if s1 = 'FRAC' then
  686.           begin
  687.             s[i - 1] := ttFrac;
  688.             Dec(i);
  689.             goto 1;
  690.           end
  691.           else if s1 = 'ROUND' then
  692.           begin
  693.             s[i - 1] := ttRound;
  694.             Dec(i);
  695.             goto 1;
  696.           end
  697.           else if s1 = 'OR' then
  698.           begin
  699.             s[i - 1] := ttOr;
  700.             Dec(i);
  701.             goto 1;
  702.           end
  703.           else if s1 = 'AND' then
  704.           begin
  705.             s[i - 1] := ttAnd;
  706.             Dec(i);
  707.             goto 1;
  708.           end
  709.           else if s1 = 'NOT' then
  710.           begin
  711.             s[i - 1] := ttNot;
  712.             Dec(i);
  713.             goto 1;
  714.           end
  715.           else if s1 = 'STR' then
  716.           begin
  717.             s[i - 1] := ttStr;
  718.             Dec(i);
  719.             goto 1;
  720.           end
  721.           else if s1 = 'MOD' then
  722.           begin
  723.             s[i - 1] := ttMod;
  724.             Dec(i);
  725.             goto 1;
  726.           end
  727.           else if c = '(' then
  728.           begin
  729.             Get3Parameters(s, i, s2, s3, s4);
  730.             res := res + Copy(s, i1, i - i1);
  731.           end
  732.           else
  733.             res := res + s2 + ' ';
  734.         end;
  735.         Dec(i);
  736.       end;
  737.     end;
  738.     Inc(i);
  739.   end;
  740.   if stack <> '' then
  741.     res := res + stack;
  742.   Result := res;
  743. end;
  744.  
  745. function TCalcer.Calc(const s: String): Variant;
  746. begin
  747.   Result := CalcOPZ(Str2OPZ(s));
  748. end;
  749.  
  750. { TFunctionSplitter }
  751.  
  752. constructor TFunctionSplitter.Create(MatchFuncs, SplitTo: TStrings;
  753.   Variables: TVariables);
  754. begin
  755.   inherited Create;
  756.   FParser := TCalcer.Create;
  757.   FMatchFuncs := MatchFuncs;
  758.   FSplitTo := SplitTo;
  759.   FVariables := Variables;
  760. end;
  761.  
  762. destructor TFunctionSplitter.Destroy;
  763. begin
  764.   FParser.Free;
  765.   inherited Destroy;
  766. end;
  767.  
  768. procedure TFunctionSplitter.Split(s: String);
  769. var
  770.   i, k: Integer;
  771.   s1, s2, s3, s4: String;
  772. begin
  773.   i := 1;
  774.   s := Trim(s);
  775.   if (Length(s) > 0) and (s[1] = '''') then
  776.     Exit;
  777.   while i <= Length(s) do
  778.   begin
  779.     k := i;
  780.     if s[1] = '[' then
  781.     begin
  782.       s1 := GetBrackedVariable(s, k, i);
  783.       if FVariables.IndexOf(s1) <> -1 then
  784.         s1 := FVariables[s1];
  785.       Split(s1);
  786.       k := i + 1;
  787.     end
  788.     else
  789.     begin
  790.       s1 := FParser.GetIdentify(s, k);
  791.       if s[k] = '(' then
  792.       begin
  793.         FParser.Get3Parameters(s, k, s2, s3, s4);
  794.         Split(s2);
  795.         Split(s3);
  796.         Split(s4);
  797.         if FMatchFuncs.IndexOf(s1) <> -1 then
  798.           FSplitTo.Add(Copy(s, i, k - i));
  799.       end
  800.       else if FVariables.IndexOf(s1) <> -1 then
  801.       begin
  802.         s1 := FVariables[s1];
  803.         Split(s1);
  804.       end
  805.       else if s[k] in [' ', #13, '+', '-', '*', '/', '>', '<', '='] then
  806.         Inc(k)
  807.       else if s1 = '' then
  808.         break;
  809.     end;
  810.     i := k;
  811.   end;
  812. end;
  813.  
  814. end.
  815.  
  816.  
  817. //delphi/7124

回复 "Delphi自定义可以直接执行运算表达式的类"

这儿你可以回复上面这条便签

captcha