﻿{"id":776,"date":"2012-03-13T10:41:27","date_gmt":"2012-03-13T02:41:27","guid":{"rendered":"http:\/\/www.tansoo.cn\/?p=776"},"modified":"2014-09-11T10:43:39","modified_gmt":"2014-09-11T02:43:39","slug":"delphi%e7%bc%96%e7%a8%8b%e4%b8%ad%ef%bc%8c%e5%a6%82%e4%bd%95%e5%9c%a8%e5%8f%af%e6%89%a7%e8%a1%8c%e7%a8%8b%e5%ba%8f%e4%b8%ad%e6%89%a7%e8%a1%8c%e5%9b%9b%e5%88%99%e8%bf%90%e7%ae%97","status":"publish","type":"post","link":"http:\/\/www.tansoo.cn\/?p=776","title":{"rendered":"Delphi\u7f16\u7a0b\u4e2d\uff0c\u5982\u4f55\u5728\u53ef\u6267\u884c\u7a0b\u5e8f\u4e2d\u6267\u884c\u56db\u5219\u8fd0\u7b97"},"content":{"rendered":"<p>Delphi\u7f16\u7a0b\u4e2d\uff0c\u6709\u65f6\u6211\u4eec\u9700\u8981\u5728\u7f16\u8bd1\u5b8c\u540e\u7684\u53ef\u6267\u884c\u7a0b\u5e8f\u4e2d\u6267\u884c\u56db\u5219\u8fd0\u7b97\uff0c\u8fd9\u662f\u597d\u591a\u5e74\u524d\u7528\u8fc7\u7684\uff0c\u73b0\u628a\u5b83\u6574\u7406\u51fa\u6765\u4f9b\u5927\u5bb6\u4f7f\u7528\uff0c\u7b97\u8ba1\u5f62\u5f0f\u5982\u4e0b\u56fe\u6240\u793a\uff1a<!--more--><\/p>\n<p>\u8c03\u7528\u65b9\u6cd5\u5982\u4e0b\u4ee3\u7801\uff1a <\/p>\n<pre class=\"lang:delphi decode:true \" >procedure TForm1.Button1Click(Sender: TObject);\r\nvar\r\n  c:TCalcer;\r\nbegin\r\n  c := TCalcer.Create;\r\n  Edit2.Text := c.Calc(Edit1.Text);\r\n  c.Free;\r\nend;<\/pre>\n<p>\u4e0b\u9762\u662f\u7528\u4e0e\u56db\u5219\u8fd0\u7b97\u7c7b\u7684\u5b9a\u4e49\uff0c\u63d0\u53d6\u81f3\u67d0\u7b2c\u4e09\u65b9\u63a7\u4ef6\uff0c\u5c06\u4e0b\u5217\u4ee3\u7801\u53e6\u5b58\u4e3aCalc.pas\u6587\u4ef6\u540e\uff0c\u518d\u5728\u5de5\u7a0b\u4e2d\u8c03\u7528\u3002 <\/p>\n<pre class=\"lang:delphi decode:true \" >{ ****************************************** }\r\n{                                            }\r\n{ \u56db\u5219\u8fd0\u7b97\u7684\u7c7b                                }\r\n{                                            }\r\n{                                            }\r\n{                                  tansoo.cn }\r\n{                                     2005.3 }\r\n{ ****************************************** }\r\n\r\nunit Calc;\r\n\r\ninterface\r\n\r\nuses Classes, Variants, SysUtils;\r\n\r\ntype\r\n  TGetPValueEvent = procedure(const s: String; var v: Variant) of object;\r\n  TFunctionEvent = procedure(const Name: String; p1, p2, p3: Variant;\r\n    var Val: Variant) of object;\r\n\r\n  TCalcer = class\r\n  private\r\n    FOnGetValue: TGetPValueEvent;\r\n    FOnFunction: TFunctionEvent;\r\n    function GetIdentify(const s: String; var i: Integer): String;\r\n    function GetString(const s: String; var i: Integer): String;\r\n    procedure Get3Parameters(const s: String; var i: Integer;\r\n      var s1, s2, s3: String);\r\n  public\r\n    function Str2OPZ(s: String): String;\r\n    function CalcOPZ(const s: String): Variant;\r\n    function Calc(const s: String): Variant;\r\n    property OnGetValue: TGetPValueEvent read FOnGetValue write FOnGetValue;\r\n    property OnFunction: TFunctionEvent read FOnFunction write FOnFunction;\r\n  end;\r\n\r\n  TVariables = class(TObject)\r\n  private\r\n    FList: TStringList;\r\n    procedure SetVariable(const Name: String; Value: Variant);\r\n    function GetVariable(const Name: String): Variant;\r\n    procedure SetValue(Index: Integer; Value: Variant);\r\n    function GetValue(Index: Integer): Variant;\r\n    procedure SetName(Index: Integer; Value: String);\r\n    function GetName(Index: Integer): String;\r\n    function GetCount: Integer;\r\n    procedure SetSorted(Value: Boolean);\r\n    function GetSorted: Boolean;\r\n  public\r\n    constructor Create;\r\n    destructor Destroy; override;\r\n    procedure Assign(Value: TVariables);\r\n    procedure Clear;\r\n    procedure Delete(Index: Integer);\r\n    function IndexOf(const Name: String): Integer;\r\n    procedure Insert(Position: Integer; const Name: String);\r\n    property Variable[const Name: String]\r\n      : Variant read GetVariable write SetVariable; default;\r\n    property Value[Index: Integer]: Variant read GetValue write SetValue;\r\n    property Name[Index: Integer]: String read GetName write SetName;\r\n    property Count: Integer read GetCount;\r\n    property Sorted: Boolean read GetSorted write SetSorted;\r\n  end;\r\n\r\n  TFunctionSplitter = class\r\n  protected\r\n    FMatchFuncs, FSplitTo: TStrings;\r\n    FParser: TCalcer;\r\n    FVariables: TVariables;\r\n  public\r\n    constructor Create(MatchFuncs, SplitTo: TStrings; Variables: TVariables);\r\n    destructor Destroy; override;\r\n    procedure Split(s: String);\r\n  end;\r\n\r\nfunction GetBrackedVariable(const s: String; var i, j: Integer): String;\r\n\r\nimplementation\r\n\r\ntype\r\n  PVariable = ^TVariable;\r\n\r\n  TVariable = record\r\n    Value: Variant;\r\n  end;\r\n\r\nconst\r\n  ttGe = #1;\r\n  ttLe = #2;\r\n  ttNe = #3;\r\n  ttOr = #4;\r\n  ttAnd = #5;\r\n  ttInt = #6;\r\n  ttFrac = #7;\r\n  ttUnMinus = #9;\r\n  ttUnPlus = #10;\r\n  ttStr = #11;\r\n  ttNot = #12;\r\n  ttMod = #13;\r\n  ttRound = #14;\r\n\r\nfunction GetBrackedVariable(const s: String; var i, j: Integer): String;\r\nvar\r\n  c: Integer;\r\n  fl1, fl2: Boolean;\r\nbegin\r\n  j := i;\r\n  fl1 := True;\r\n  fl2 := True;\r\n  c := 0;\r\n  Result := '';\r\n  if (s = '') or (j &gt; Length(s)) then\r\n    Exit;\r\n  Dec(j);\r\n  repeat\r\n    Inc(j);\r\n    if fl1 and fl2 then\r\n      if s[j] = '[' then\r\n      begin\r\n        if c = 0 then\r\n          i := j;\r\n        Inc(c);\r\n      end\r\n      else if s[j] = ']' then\r\n        Dec(c);\r\n    if fl1 then\r\n      if s[j] = '\"' then\r\n        fl2 := not fl2;\r\n    if fl2 then\r\n      if s[j] = '''' then\r\n        fl1 := not fl1;\r\n  until (c = 0) or (j &gt;= Length(s));\r\n  Result := Copy(s, i + 1, j - i - 1);\r\nend;\r\n\r\n{ TVariables }\r\n\r\nconstructor TVariables.Create;\r\nbegin\r\n  inherited Create;\r\n  FList := TStringList.Create;\r\n  FList.Duplicates := dupIgnore;\r\nend;\r\n\r\ndestructor TVariables.Destroy;\r\nbegin\r\n  Clear;\r\n  FList.Free;\r\n  inherited Destroy;\r\nend;\r\n\r\nprocedure TVariables.Assign(Value: TVariables);\r\nvar\r\n  i: Integer;\r\nbegin\r\n  Clear;\r\n  for i := 0 to Value.Count - 1 do\r\n    SetVariable(Value.Name[i], Value.Value[i]);\r\nend;\r\n\r\nprocedure TVariables.Clear;\r\nbegin\r\n  while FList.Count &gt; 0 do\r\n    Delete(0);\r\nend;\r\n\r\nprocedure TVariables.SetVariable(const Name: String; Value: Variant);\r\nvar\r\n  i: Integer;\r\n  p: PVariable;\r\nbegin\r\n  i := IndexOf(Name);\r\n  if i &lt;&gt; -1 then\r\n    PVariable(FList.Objects[i]).Value := Value\r\n  else\r\n  begin\r\n    New(p);\r\n    p^.Value := Value;\r\n    FList.AddObject(Name, TObject(p));\r\n  end;\r\nend;\r\n\r\nfunction TVariables.GetVariable(const Name: String): Variant;\r\nvar\r\n  i: Integer;\r\nbegin\r\n  Result := Null;\r\n  i := IndexOf(Name);\r\n  if i &lt;&gt; -1 then\r\n    Result := PVariable(FList.Objects[i]).Value;\r\nend;\r\n\r\nprocedure TVariables.SetValue(Index: Integer; Value: Variant);\r\nbegin\r\n  if (Index &lt; 0) or (Index &gt;= FList.Count) then\r\n    Exit;\r\n  PVariable(FList.Objects[Index])^.Value := Value;\r\nend;\r\n\r\nfunction TVariables.GetValue(Index: Integer): Variant;\r\nbegin\r\n  Result := 0;\r\n  if (Index &lt; 0) or (Index &gt;= FList.Count) then\r\n    Exit;\r\n  Result := PVariable(FList.Objects[Index])^.Value;\r\nend;\r\n\r\nfunction TVariables.IndexOf(const Name: String): Integer;\r\nbegin\r\n  Result := FList.IndexOf(Name);\r\nend;\r\n\r\nprocedure TVariables.Insert(Position: Integer; const Name: String);\r\nbegin\r\n  SetVariable(Name, 0);\r\n  FList.Move(FList.IndexOf(Name), Position);\r\nend;\r\n\r\nfunction TVariables.GetCount: Integer;\r\nbegin\r\n  Result := FList.Count;\r\nend;\r\n\r\nprocedure TVariables.SetName(Index: Integer; Value: String);\r\nbegin\r\n  if (Index &lt; 0) or (Index &gt;= FList.Count) then\r\n    Exit;\r\n  FList[Index] := Value;\r\nend;\r\n\r\nfunction TVariables.GetName(Index: Integer): String;\r\nbegin\r\n  Result := '';\r\n  if (Index &lt; 0) or (Index &gt;= FList.Count) then\r\n    Exit;\r\n  Result := FList[Index];\r\nend;\r\n\r\nprocedure TVariables.Delete(Index: Integer);\r\nvar\r\n  p: PVariable;\r\nbegin\r\n  if (Index &lt; 0) or (Index &gt;= FList.Count) then\r\n    Exit;\r\n  p := PVariable(FList.Objects[Index]);\r\n  Dispose(p);\r\n  FList.Delete(Index);\r\nend;\r\n\r\nprocedure TVariables.SetSorted(Value: Boolean);\r\nbegin\r\n  FList.Sorted := Value;\r\nend;\r\n\r\nfunction TVariables.GetSorted: Boolean;\r\nbegin\r\n  Result := FList.Sorted;\r\nend;\r\n\r\n{ TCalcer }\r\n{$WARNINGS OFF}\r\n\r\nfunction TCalcer.CalcOPZ(const s: String): Variant;\r\nvar\r\n  i, j, k, i1, st, ci, cn: Integer;\r\n  s1, s2, s3, s4: String;\r\n  nm: Array [1 .. 32] of Variant;\r\n  v: Double;\r\nbegin\r\n  st := 1;\r\n  i := 1;\r\n  nm[1] := 0;\r\n  Result := 0;\r\n  while i &lt;= Length(s) do\r\n  begin\r\n    j := i;\r\n    case s[i] of\r\n      '+':\r\n        nm[st - 2] := nm[st - 2] + nm[st - 1];\r\n      ttOr:\r\n        nm[st - 2] := nm[st - 2] or nm[st - 1];\r\n      '-':\r\n        nm[st - 2] := nm[st - 2] - nm[st - 1];\r\n      '*', ttAnd:\r\n        nm[st - 2] := nm[st - 2] * nm[st - 1];\r\n      '\/':\r\n        if nm[st - 1] &lt;&gt; 0 then\r\n          nm[st - 2] := nm[st - 2] \/ nm[st - 1]\r\n        else\r\n          nm[st - 2] := 0;\r\n      '&gt;':\r\n        if nm[st - 2] &gt; nm[st - 1] then\r\n          nm[st - 2] := 1\r\n        else\r\n          nm[st - 2] := 0;\r\n      '&lt;':\r\n        if nm[st - 2] &lt; nm[st - 1] then\r\n          nm[st - 2] := 1\r\n        else\r\n          nm[st - 2] := 0;\r\n      '=':\r\n        if nm[st - 2] = nm[st - 1] then\r\n          nm[st - 2] := 1\r\n        else\r\n          nm[st - 2] := 0;\r\n      ttNe:\r\n        if nm[st - 2] &lt;&gt; nm[st - 1] then\r\n          nm[st - 2] := 1\r\n        else\r\n          nm[st - 2] := 0;\r\n      ttGe:\r\n        if nm[st - 2] &gt;= nm[st - 1] then\r\n          nm[st - 2] := 1\r\n        else\r\n          nm[st - 2] := 0;\r\n      ttLe:\r\n        if nm[st - 2] &lt;= nm[st - 1] then\r\n          nm[st - 2] := 1\r\n        else\r\n          nm[st - 2] := 0;\r\n      ttInt:\r\n        begin\r\n          v := nm[st - 1];\r\n          if Abs(Round(v) - v) &lt; 1E-10 then\r\n            v := Round(v)\r\n          else\r\n            v := Int(v);\r\n\r\n          nm[st - 1] := v;\r\n        end;\r\n      ttFrac:\r\n        begin\r\n          v := nm[st - 1];\r\n          if Abs(Round(v) - v) &lt; 1E-10 then\r\n            v := Round(v);\r\n\r\n          nm[st - 1] := Frac(v);\r\n        end;\r\n      ttRound:\r\n        nm[st - 1] := Integer(Round(nm[st - 1]));\r\n      ttUnMinus:\r\n        nm[st - 1] := -nm[st - 1];\r\n      ttUnPlus:\r\n        ;\r\n      ttStr:\r\n        begin\r\n          if nm[st - 1] &lt;&gt; Null then\r\n            s1 := nm[st - 1]\r\n          else\r\n            s1 := '';\r\n          nm[st - 1] := s1;\r\n        end;\r\n      ttNot:\r\n        if nm[st - 1] = 0 then\r\n          nm[st - 1] := 1\r\n        else\r\n          nm[st - 1] := 0;\r\n      ttMod:\r\n        nm[st - 2] := nm[st - 2] mod nm[st - 1];\r\n      ' ':\r\n        ;\r\n      '[':\r\n        begin\r\n          k := i;\r\n          s1 := GetBrackedVariable(s, k, i);\r\n          if Assigned(FOnGetValue) then\r\n            FOnGetValue(s1, nm[st]);\r\n          Inc(st);\r\n        end\r\n      else\r\n      begin\r\n        if s[i] = '''' then\r\n        begin\r\n          s1 := GetString(s, i);\r\n          s1 := Copy(s1, 2, Length(s1) - 2);\r\n          while Pos('''' + '''', s1) &lt;&gt; 0 do\r\n            Delete(s1, Pos('''' + '''', s1), 1);\r\n          nm[st] := s1;\r\n          k := i;\r\n        end\r\n        else\r\n        begin\r\n          k := i;\r\n          s1 := GetIdentify(s, k);\r\n          if (s1 &lt;&gt; '') and (s1[1] in ['0' .. '9', '.', ',']) then\r\n          begin\r\n            for i1 := 1 to Length(s1) do\r\n              if s1[i1] in ['.', ','] then\r\n                s1[i1] := DecimalSeparator;\r\n            nm[st] := StrToFloat(s1);\r\n          end\r\n          else if AnsiCompareText(s1, 'TRUE') = 0 then\r\n            nm[st] := True\r\n          else if AnsiCompareText(s1, 'FALSE') = 0 then\r\n            nm[st] := False\r\n          else if s[k] = '[' then\r\n          begin\r\n            s1 := 'GETARRAY(' + s1 + ', ' + GetBrackedVariable(s, k, i) + ')';\r\n            nm[st] := Calc(s1);\r\n            k := i;\r\n          end\r\n          else if s[k] = '(' then\r\n          begin\r\n            s1 := AnsiUpperCase(s1);\r\n            Get3Parameters(s, k, s2, s3, s4);\r\n            if s1 = 'COPY' then\r\n            begin\r\n              ci := StrToInt(Calc(s3));\r\n              cn := StrToInt(Calc(s4));\r\n              nm[st] := Copy(Calc(s2), ci, cn);\r\n            end\r\n            else if s1 = 'IF' then\r\n            begin\r\n              if Int(StrToFloat(Calc(s2))) &lt;&gt; 0 then\r\n                s1 := s3\r\n              else\r\n                s1 := s4;\r\n              nm[st] := Calc(s1);\r\n            end\r\n            else if s1 = 'STRTODATE' then\r\n              nm[st] := StrToDate(Calc(s2))\r\n            else if s1 = 'STRTOTIME' then\r\n              nm[st] := StrToTime(Calc(s2))\r\n            else if Assigned(FOnFunction) then\r\n              FOnFunction(s1, s2, s3, s4, nm[st]);\r\n            Dec(k);\r\n          end\r\n          else if Assigned(FOnGetValue) then\r\n            FOnGetValue(AnsiUpperCase(s1), nm[st]);\r\n        end;\r\n        i := k;\r\n        Inc(st);\r\n      end;\r\n    end;\r\n    if s[j] in ['+', '-', '*', '\/', '&gt;', '&lt;', '=', ttGe, ttLe, ttNe, ttOr,\r\n      ttAnd, ttMod] then\r\n      Dec(st);\r\n    Inc(i);\r\n  end;\r\n  Result := nm[1];\r\nend;\r\n{$WARNINGS ON}\r\n\r\nfunction TCalcer.GetIdentify(const s: String; var i: Integer): String;\r\nvar\r\n  k, n: Integer;\r\nbegin\r\n  n := 0;\r\n  while (i &lt;= Length(s)) and (s[i] &lt;= ' ') do\r\n    Inc(i);\r\n  k := i;\r\n  Dec(i);\r\n  repeat\r\n    Inc(i);\r\n    while (i &lt;= Length(s)) and not(s[i] in [' ', #13, '+', '-', '*', '\/', '&gt;',\r\n      '&lt;', '=', '(', ')', '[']) do\r\n    begin\r\n      if s[i] = '\"' then\r\n        Inc(n);\r\n      Inc(i);\r\n    end;\r\n  until (n mod 2 = 0) or (i &gt;= Length(s));\r\n  Result := Copy(s, k, i - k);\r\nend;\r\n\r\nfunction TCalcer.GetString(const s: String; var i: Integer): String;\r\nvar\r\n  k: Integer;\r\n  f: Boolean;\r\nbegin\r\n  k := i;\r\n  Inc(i);\r\n  repeat\r\n    while (i &lt;= Length(s)) and (s[i] &lt;&gt; '''') do\r\n      Inc(i);\r\n    f := True;\r\n    if (i &lt; Length(s)) and (s[i + 1] = '''') then\r\n    begin\r\n      f := False;\r\n      Inc(i, 2);\r\n    end;\r\n  until f;\r\n  Result := Copy(s, k, i - k + 1);\r\n  Inc(i);\r\nend;\r\n\r\nprocedure TCalcer.Get3Parameters(const s: String; var i: Integer;\r\n  var s1, s2, s3: String);\r\nvar\r\n  c, d, oi, ci: Integer;\r\nbegin\r\n  s1 := '';\r\n  s2 := '';\r\n  s3 := '';\r\n  c := 1;\r\n  d := 1;\r\n  oi := i + 1;\r\n  ci := 1;\r\n  repeat\r\n    Inc(i);\r\n    if s[i] = '''' then\r\n      if d = 1 then\r\n        Inc(d)\r\n      else\r\n        d := 1;\r\n    if d = 1 then\r\n    begin\r\n      if s[i] = '(' then\r\n        Inc(c)\r\n      else if s[i] = ')' then\r\n        Dec(c);\r\n      if (s[i] = ',') and (c = 1) then\r\n      begin\r\n        if ci = 1 then\r\n          s1 := Copy(s, oi, i - oi)\r\n        else\r\n          s2 := Copy(s, oi, i - oi);\r\n        oi := i + 1;\r\n        Inc(ci);\r\n      end;\r\n    end;\r\n  until (c = 0) or (i &gt;= Length(s));\r\n  case ci of\r\n    1:\r\n      s1 := Copy(s, oi, i - oi);\r\n    2:\r\n      s2 := Copy(s, oi, i - oi);\r\n    3:\r\n      s3 := Copy(s, oi, i - oi);\r\n  end;\r\n  if c &lt;&gt; 0 then\r\n    raise Exception.Create('');\r\n  Inc(i);\r\nend;\r\n\r\nfunction TCalcer.Str2OPZ(s: String): String;\r\nlabel 1;\r\nvar\r\n  i, i1, j, p: Integer;\r\n  stack: String;\r\n  res, s1, s2, s3, s4: String;\r\n  vr: Boolean;\r\n  c: Char;\r\n\r\n  function Priority(c: Char): Integer;\r\n  begin\r\n    case c of\r\n      '(':\r\n        Priority := 5;\r\n      ')':\r\n        Priority := 4;\r\n      '=', '&gt;', '&lt;', ttGe, ttLe, ttNe:\r\n        Priority := 3;\r\n      '+', '-', ttUnMinus, ttUnPlus:\r\n        Priority := 2;\r\n      '*', '\/', ttOr, ttAnd, ttNot, ttMod:\r\n        Priority := 1;\r\n      ttInt, ttFrac, ttRound, ttStr:\r\n        Priority := 0;\r\n    else\r\n      Priority := 0;\r\n    end;\r\n  end;\r\n\r\n  procedure ProcessQuotes(var s: String);\r\n  var\r\n    i: Integer;\r\n  begin\r\n    if (Length(s) = 0) or (s[1] &lt;&gt; '''') then\r\n      Exit;\r\n    i := 2;\r\n    if Length(s) &gt; 2 then\r\n      while i &lt;= Length(s) do\r\n      begin\r\n        if (s[i] = '''') and (i &lt; Length(s)) then\r\n        begin\r\n          Insert('''', s, i);\r\n          Inc(i);\r\n        end;\r\n        Inc(i);\r\n      end;\r\n  end;\r\n\r\nbegin\r\n  res := '';\r\n  stack := '';\r\n  i := 1;\r\n  vr := False;\r\n  while i &lt;= Length(s) do\r\n  begin\r\n    case s[i] of\r\n      '(':\r\n        begin\r\n          stack := '(' + stack;\r\n          vr := False;\r\n        end;\r\n      ')':\r\n        begin\r\n          p := Pos('(', stack);\r\n          res := res + Copy(stack, 1, p - 1);\r\n          stack := Copy(stack, p + 1, Length(stack) - p);\r\n        end;\r\n      '+', '-', '*', '\/', '&gt;', '&lt;', '=':\r\n        begin\r\n          if (s[i] = '&lt;') and (s[i + 1] = '&gt;') then\r\n          begin\r\n            Inc(i);\r\n            s[i] := ttNe;\r\n          end\r\n          else if (s[i] = '&gt;') and (s[i + 1] = '=') then\r\n          begin\r\n            Inc(i);\r\n            s[i] := ttGe;\r\n          end\r\n          else if (s[i] = '&lt;') and (s[i + 1] = '=') then\r\n          begin\r\n            Inc(i);\r\n            s[i] := ttLe;\r\n          end;\r\n\r\n        1 :\r\n          if not vr then\r\n          begin\r\n            if s[i] = '-' then\r\n              s[i] := ttUnMinus;\r\n            if s[i] = '+' then\r\n              s[i] := ttUnPlus;\r\n          end;\r\n          vr := False;\r\n          if stack = '' then\r\n            stack := s[i] + stack\r\n          else if Priority(s[i]) &lt; Priority(stack[1]) then\r\n            stack := s[i] + stack\r\n          else\r\n          begin\r\n            repeat\r\n              res := res + stack[1];\r\n              stack := Copy(stack, 2, Length(stack) - 1);\r\n            until (stack = '') or (Priority(stack[1]) &gt; Priority(s[i]));\r\n            stack := s[i] + stack;\r\n          end;\r\n        end;\r\n      ';':\r\n        break;\r\n      ' ', #13:\r\n        ;\r\n    else\r\n      begin\r\n        vr := True;\r\n        s2 := '';\r\n        i1 := i;\r\n        if s[i] = '%' then\r\n        begin\r\n          s2 := '%' + s[i + 1];\r\n          Inc(i, 2);\r\n        end;\r\n        if s[i] = '''' then\r\n          s2 := s2 + GetString(s, i)\r\n        else if s[i] = '[' then\r\n        begin\r\n          s2 := s2 + '[' + GetBrackedVariable(s, i, j) + ']';\r\n          i := j + 1;\r\n        end\r\n        else\r\n        begin\r\n          s2 := s2 + GetIdentify(s, i);\r\n          if s[i] = '[' then\r\n          begin\r\n            s2 := s2 + '[' + GetBrackedVariable(s, i, j) + ']';\r\n            i := j + 1;\r\n          end;\r\n        end;\r\n        c := s[i];\r\n        if (Length(s2) &gt; 0) and (s2[1] in ['0' .. '9', '.', ',']) then\r\n          res := res + s2 + ' '\r\n        else\r\n        begin\r\n          s1 := AnsiUpperCase(s2);\r\n          if s1 = 'INT' then\r\n          begin\r\n            s[i - 1] := ttInt;\r\n            Dec(i);\r\n            goto 1;\r\n          end\r\n          else if s1 = 'FRAC' then\r\n          begin\r\n            s[i - 1] := ttFrac;\r\n            Dec(i);\r\n            goto 1;\r\n          end\r\n          else if s1 = 'ROUND' then\r\n          begin\r\n            s[i - 1] := ttRound;\r\n            Dec(i);\r\n            goto 1;\r\n          end\r\n          else if s1 = 'OR' then\r\n          begin\r\n            s[i - 1] := ttOr;\r\n            Dec(i);\r\n            goto 1;\r\n          end\r\n          else if s1 = 'AND' then\r\n          begin\r\n            s[i - 1] := ttAnd;\r\n            Dec(i);\r\n            goto 1;\r\n          end\r\n          else if s1 = 'NOT' then\r\n          begin\r\n            s[i - 1] := ttNot;\r\n            Dec(i);\r\n            goto 1;\r\n          end\r\n          else if s1 = 'STR' then\r\n          begin\r\n            s[i - 1] := ttStr;\r\n            Dec(i);\r\n            goto 1;\r\n          end\r\n          else if s1 = 'MOD' then\r\n          begin\r\n            s[i - 1] := ttMod;\r\n            Dec(i);\r\n            goto 1;\r\n          end\r\n          else if c = '(' then\r\n          begin\r\n            Get3Parameters(s, i, s2, s3, s4);\r\n            res := res + Copy(s, i1, i - i1);\r\n          end\r\n          else\r\n            res := res + s2 + ' ';\r\n        end;\r\n        Dec(i);\r\n      end;\r\n    end;\r\n    Inc(i);\r\n  end;\r\n  if stack &lt;&gt; '' then\r\n    res := res + stack;\r\n  Result := res;\r\nend;\r\n\r\nfunction TCalcer.Calc(const s: String): Variant;\r\nbegin\r\n  Result := CalcOPZ(Str2OPZ(s));\r\nend;\r\n\r\n{ TFunctionSplitter }\r\n\r\nconstructor TFunctionSplitter.Create(MatchFuncs, SplitTo: TStrings;\r\n  Variables: TVariables);\r\nbegin\r\n  inherited Create;\r\n  FParser := TCalcer.Create;\r\n  FMatchFuncs := MatchFuncs;\r\n  FSplitTo := SplitTo;\r\n  FVariables := Variables;\r\nend;\r\n\r\ndestructor TFunctionSplitter.Destroy;\r\nbegin\r\n  FParser.Free;\r\n  inherited Destroy;\r\nend;\r\n\r\nprocedure TFunctionSplitter.Split(s: String);\r\nvar\r\n  i, k: Integer;\r\n  s1, s2, s3, s4: String;\r\nbegin\r\n  i := 1;\r\n  s := Trim(s);\r\n  if (Length(s) &gt; 0) and (s[1] = '''') then\r\n    Exit;\r\n  while i &lt;= Length(s) do\r\n  begin\r\n    k := i;\r\n    if s[1] = '[' then\r\n    begin\r\n      s1 := GetBrackedVariable(s, k, i);\r\n      if FVariables.IndexOf(s1) &lt;&gt; -1 then\r\n        s1 := FVariables[s1];\r\n      Split(s1);\r\n      k := i + 1;\r\n    end\r\n    else\r\n    begin\r\n      s1 := FParser.GetIdentify(s, k);\r\n      if s[k] = '(' then\r\n      begin\r\n        FParser.Get3Parameters(s, k, s2, s3, s4);\r\n        Split(s2);\r\n        Split(s3);\r\n        Split(s4);\r\n        if FMatchFuncs.IndexOf(s1) &lt;&gt; -1 then\r\n          FSplitTo.Add(Copy(s, i, k - i));\r\n      end\r\n      else if FVariables.IndexOf(s1) &lt;&gt; -1 then\r\n      begin\r\n        s1 := FVariables[s1];\r\n        Split(s1);\r\n      end\r\n      else if s[k] in [' ', #13, '+', '-', '*', '\/', '&gt;', '&lt;', '='] then\r\n        Inc(k)\r\n      else if s1 = '' then\r\n        break;\r\n    end;\r\n    i := k;\r\n  end;\r\nend;\r\n\r\nend.<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Delphi\u7f16\u7a0b\u4e2d\uff0c\u6709\u65f6\u6211\u4eec\u9700\u8981\u5728\u7f16\u8bd1\u5b8c\u540e\u7684\u53ef\u6267\u884c\u7a0b\u5e8f\u4e2d\u6267\u884c\u56db\u5219\u8fd0\u7b97\uff0c\u8fd9\u662f\u597d\u591a\u5e74\u524d\u7528\u8fc7\u7684\uff0c\u73b0\u628a\u5b83\u6574\u7406\u51fa\u6765\u4f9b\u5927\u5bb6 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[14,33],"class_list":["post-776","post","type-post","status-publish","format-standard","hentry","category-program","tag-delphi","tag-33"],"_links":{"self":[{"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=\/wp\/v2\/posts\/776","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=776"}],"version-history":[{"count":0,"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=\/wp\/v2\/posts\/776\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=776"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=776"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.tansoo.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=776"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}