Thema: Delphi Einheiten parsen

Einzelnen Beitrag anzeigen

Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#25

AW: Einheiten parsen

  Alt 10. Mär 2015, 18:01
Das Parsen gestaltet sich jetzt doch schwieriger als angenommen.

Der Term sieht intern so aus. In eckigen Klammern die Einheiten. Die Einheiten werden durch einfache Token ersetzt.

5,0[D]*0,70[K]/cos(30)

Das das soll jetzt hier durchgejagt werden. Hab keinen Plan wie ich das hier anstellen soll? (Getrenntes Parsen von Einheitn und Term ist m.E. aus syntaktischen Gründen nicht möglich.)

Im Beispiel landet der Parser irgendwann in GetPlus. Er muß aber auch mal irengdwann in FUnit.GetPlus landen (Der Parser hat ein Feld der Klasse TUntis (Siehe #18)).

Delphi-Quellcode:
// Die eigentliche Auflösung des Terms;
// *** Die Rekursion arbeitet rückwärts;
// "~" (unäres Minus) immer zuerst prüfen ;
// Sqrt vor Sqr, ArcXXX vor XXX;
// Entweder LastPos und true oder FirstPos und false;
// LastPos und true: "+", "-", "*", "/", ":", "\", (":" = div, "\" = mod);
// FirstPos und false: "^", Functions;
function TJMUnitParser.Solve(S: string; var Style: TUnitStyle): double;
begin
  try
    if LastPos('+', S) > 0 then
      Result := GetPlus(Solve(Left(S, '+', true), Style), Solve(Right(S, '+', true), Style))
    else
      ... Weitere ..
    else
    if Parenthesis(S, true) then // "~( .. )"
      Result := -Solve(S, Style)
    else
    if Parenthesis(S, false) then // "( .. )"
      Result := Solve(S, Style)
    else
      Result := StrToFloat(MyStringReplace(S, '~', '-', false, false));
  except
    Result := 0;
  end;
end;

// Gibt den linken Teil einer Operation zurück;
function TJMUnitParser.Left(const S, Substr: string; const Last: boolean): string;
begin
  if Last then // Den Term von rechts nach links durchsuchen;
    Result := StrLeft(S, LastPos(Substr, S) - 1)
  else // Den Term von links nach rechts durchsuchen;
    Result := StrLeft(S, FirstPos(Substr, S) - 1);
 end;

// Gibt den rechten Teil einer Operation zurück;
function TJMUnitParser.Right(const S, Substr: string; const Last: boolean): string;
begin
  if Last then // Den Term von rechts nach links durchsuchen;
    Result := StrRight(S, LastPos(Substr, S) + Length(Substr))
  else // Den Term von links nach rechts durchsuchen;
    Result := StrRight(S, FirstPos(Substr, S) + Length(Substr));
end;

function TJMUnitParser.GetPlus(const X, Y: double): double;
begin
  Result := X + Y;
end;
  Mit Zitat antworten Zitat