Her kommer den så 

... 175 linjer kode 

:
function CalculateResult(Exp: String; Validate: Boolean = True): Extended;
const
  Decimal: Char = '.';
type
  PPart = ^TPart;
  TPart = record
    Content: String;
    Positive: Boolean;
    Result: Extended;
  end;
  TParts = array of TPart;
var
  I: Integer;
  Parts: TParts;
  function GetFloatingPoint(): String;
  var
    Dec: PChar;
  begin
    Dec := StrAlloc(10);
    GetLocaleInfo(
      LOCALE_SYSTEM_DEFAULT,
      LOCALE_SDECIMAL,
      Dec,
      10);
    Result := Dec;
  end;
  function SplitInParts(S: String): TParts;
  var
    I: Integer;
    Tmp: String;
    function StripSpaces(S: String): String;
    var
      I: Integer;
    begin
      I := Pos(' ', S);
      while I > 0 do begin
        Delete(S, I, 1);
        I := Pos(' ', S);
      end;
      Result := S;
    end;
  begin
    S := StripSpaces(S); // Vi fjerner lige mellemrum
    // Her kommer tre grimme fixes :D
    S := S + '+';
    if (S[1] <> '+') and (S[1] <> '-') then
      S := '+' + S;
    Tmp := S[1];
    for I := 2 to Length(S) do begin
      if (S[I] <> '+') and (S[I] <> '-') then
        Tmp := Tmp + S[I]
      else begin
        SetLength(Result, High(Result)+2);
        Result[High(Result)].Content := Tmp;
        case S[I] of
          '+': Result[High(Result)].Positive := True;
          '-': Result[High(Result)].Positive := False;
        end;
        Tmp := S[I];
      end;
    end;
  end;
  procedure CalculatePart(Part: PPart);
  type
    TSplitted = record
      Content: String;
      Action: Integer;
    end;
  var
    I: Integer;
    Splitted: array of TSplitted;
    Tmp: String;
    Tmp2: String;
    TmpResult: Extended;
  begin
    Tmp := '';
    // Grimt grimt fix!
    Tmp2 := Part.Content + '*';
    for I := 1 to Length(Tmp2) do begin
      if (Tmp2[I] <> '*') and (Tmp2[I] <> '/') then
        Tmp := Tmp + Tmp2[I]
      else begin
        SetLength(Splitted, High(Splitted)+2);
        if (Tmp[1] <> '-') and (Tmp[1] <> '+') then
          Tmp := '+' + Tmp;
        Splitted[High(Splitted)].Content := Tmp;
        case Tmp2[I] of
          '*': Splitted[High(Splitted)].Action := 0;
          '/': Splitted[High(Splitted)].Action := 1;
        end;
        Tmp := '';
      end;
    end;
    // Vi har nu alt hvad vi skal bruge for at udregne resultatet :D
    TmpResult := StrToFloat(Splitted[0].Content);
    for I := 1 to High(Splitted) do begin
      case Splitted[I-1].Action of
        0: TmpResult := TmpResult * StrToFloat(Splitted[I].Content);
        1: TmpResult := TmpResult / StrToFloat(Splitted[I].Content);
      end;
    end;
    Part.Result := TmpResult;
  end;
  function FindClosingBracket(S: String; StartingBracket: Integer): Integer;
  var
    I: Integer;
    Cur: Integer;
  begin
    Cur := 1;
    for I := StartingBracket+1 to Length(S) do begin
      if S[I] = '(' then
        Inc(Cur)
      else if S[I] = ')' then
        Dec(Cur);
      if Cur = 0 then begin
        Result := I-StartingBracket+1;
        Break;
      end;
    end;
  end;
var
  J: Integer;
begin
  try
    // Valider inputtet
    if Validate then begin
      for I := 1 to Length(Exp) do begin
        if not (Exp[I] in ['0'..'9', '*', '/', '+', '-', '(', ')', Decimal]) then
          raise Exception.Create('');
      end;
      Exp := StringReplace(Exp,
                           Decimal,
                           GetFloatingPoint,
                           [rfReplaceAll]+[rfIgnoreCase]);
      Exp := StringReplace(Exp, '+-', '-', [rfReplaceAll]);
      Exp := StringReplace(Exp, '--', '+', [rfReplaceAll]);
      Exp := StringReplace(Exp, '-+', '-', [rfReplaceAll]);
      Exp := StringReplace(Exp, '++', '+', [rfReplaceAll]);
    end;
    // "Smart" lille fix til at udregne parenteser :D
    I := Pos('(', Exp);
    while I <> 0 do begin
      J := FindClosingBracket(Exp, I);
      Exp := StringReplace(Exp,
                           Copy(Exp, I, J),
                           FloatToStr(CalculateResult(Copy(Exp, I+1, J-2), False)),
                           [rfReplaceAll]+[rfIgnoreCase]);
      I := Pos('(', Exp);
    end;
    Parts := SplitInParts(Exp); // Først deler vi vores expression op
    for I := 0 to High(Parts) do begin
      CalculatePart(@Parts[I]);
    end;
    // Nu skal vi lige lave sidste udregning og så er vi færdige :D
    Result := Parts[0].Result;
    for I := 1 to High(Parts) do begin
      case Parts[I].Positive of
        True: Result := Result + Parts[I].Result;
        False: Result := Result - Parts[I].Result;
      end;
    end;
  except
    on E: Exception do begin Result := NaN; end;
  end;
end;
For at virke kræver det at SysUtils, Math og Windows unitsne er under "uses" sektionen. For at bruge parsen kan du gøre sådan her:
var
  F: Extended;
  Exp: String; // Dette er stringen med matematisk indhold
begin
  Exp := '(65+98*4/(65))';
  F := CalculateResult(Exp);
  if not IsNaN(F) then
    ShowMessage(FloatToStr(F))
  else
    ShowMessage('Det matematiske udtryk er ukorrekt!');
end;
EDIT: Glemte at skrive at decimal-seperatoren i inputtet SKAL være "." (Altså et punktum)
MH.
    The-Freak
Livet er for kort til at kede sig.
[Redigeret d. 19/01-05 14:56:07 af The-Freak]