Einzelnen Beitrag anzeigen

ford42

Registriert seit: 2. Okt 2015
60 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Parser - einfache Mathematische Formel

  Alt 6. Okt 2015, 11:52
Delphi-Version: XE3
Hey,
ich versuche zur Zeit einen Parser für eine einfache Mathematische Formel (z.B: 2*4/3+5-4) zu schreiben, aber wenn ich z. B. 1*6*5 eingebe kommt 6 raus und nicht 30. :/

Weiß jemand wo ich den Fehler habe und hat vlt noch andere Verbesserungsvorschläge für den Parser?

Delphi-Quellcode:
unit Logic;

interface

uses
  System.Classes, System.SysUtils, StrUtils;

type
  TBerechnung = class
  private
    { Private-Deklarationen }
    m_EingabeZahl: TStringList;
    m_EingabeEreignis: String;
    m_EingabeRechenoperator: String;
  public
    { Public-Deklarationen }
    procedure AddZahl(p_Parameter: String);
    procedure AddEreignis(p_Parameter: String);
    procedure PosExRechnen(m_EingabeZahl: TStringList);
    function GetErgebnis(): String;
    procedure Erstelle;
    procedure Loesche;
    procedure Parser(zwErgebnis: String; zErgebnis: Double; i: Smallint; opFolge: Integer);
  end;

implementation

  procedure TBerechnung.Erstelle;
  begin
    m_EingabeZahl := TStringList.Create;
  end;

  procedure TBerechnung.Loesche;
  begin
    m_EingabeZahl.Free;
  end;

  procedure TBerechnung.AddZahl(p_Parameter: String);
  begin
    m_EingabeZahl.Add(p_Parameter);
  end;

  procedure TBerechnung.AddEreignis(p_Parameter: String);
  begin
    if p_Parameter = 'Cthen
    begin
      m_EingabeZahl.Clear;
      m_EingabeEreignis := '';
      m_EingabeRechenoperator := '';
    end;
    //Parser
    if p_Parameter = '=then
    begin
      PosExRechnen(m_EingabeZahl);
    end;
  end;

  procedure TBerechnung.Parser(zwErgebnis: String; zErgebnis: Double; i, opFolge: Integer);
  begin
    zwErgebnis := FloatToStr(zErgebnis);
    m_EingabeZahl.Delete(i);
    m_EingabeZahl.Delete(i);
    m_EingabeZahl[i - 1] := zwErgebnis;
    i := i - 2; //schauen, warum i nicht verändert
    if i = m_EingabeZahl.Count - 1 then
    begin
      opFolge := opFolge + 1;
    end;
  end;

  procedure TBerechnung.PosExRechnen(m_EingabeZahl: TStringList);
  var
    opFolge, arPos: Integer;
    i: Smallint;
    zErgebnis: Double;
    zwErgebnis: String;
    rOp: String;
  begin
    i := -1;
    opFolge := 1;
    while (i < m_EingabeZahl.Count - 1) do //Nacheinander (erst mal, dann durch,..)
    begin
      i := i + 1;
      rOp := m_EingabeZahl[i];
      if (opFolge = 1) and (rOp = '*') then
      begin
        zErgebnis := (StrToFloat(m_EingabeZahl[i - 1]) * StrToFloat(m_EingabeZahl[i + 1]));
        Parser(zwErgebnis, zErgebnis, i, opFolge);
      end
      else if (opFolge = 2) and (rOp = '/') then
      begin
        zErgebnis := (StrToFloat(m_EingabeZahl[i - 1]) / StrToFloat(m_EingabeZahl[i + 1]));
        Parser(zwErgebnis, zErgebnis, i, opFolge);
      end
      else if (opFolge = 3) and (rOp = '+') then
      begin
        zErgebnis := (StrToFloat(m_EingabeZahl[i - 1]) + StrToFloat(m_EingabeZahl[i + 1]));
        Parser(zwErgebnis, zErgebnis, i, opFolge);
      end
      else if (opFolge = 4) and (rOp = '-') then
      begin
        zErgebnis := (StrToFloat(m_EingabeZahl[i - 1]) - StrToFloat(m_EingabeZahl[i + 1]));
        Parser(zwErgebnis, zErgebnis, i, opFolge);
      end;
    end;
  end;

  function TBerechnung.GetErgebnis;
  begin
    result := m_EingabeZahl.Text;
  end;
end.
PS: Und wie in dem Kommi zu sehen müsste sich ja i da oben verändern, tut es aber nicht. Oo

Vielen Dank im Voraus
Grüße ford42
  Mit Zitat antworten Zitat