Seite 1 von 1

Formeln mathematisch parsen einfach gemacht

Verfasst: 27.02.2006 10:34
von Kiffi
Shalom,

wer vor der Aufgabe steht, vom Anwender eingegebene Formeln
auszurechnen, kommt nicht umhin, einen mathematischen Parser für diese
Eingaben zu schreiben. Der nachfolgende Code zeigt, wie man sich eine
Menge Arbeit ersparen kann, indem die zu berechnende Formel der
Microsoft JET-Engine übergibt, die dann die Aufgabe des Parsens
übernimmt und das Ergebnis zurückgibt.

Da sich meine Mathe-Kenntnisse auf ein Mindestmaß beschränken, bitte
ich jemand kompetenteren, die Fähigkeiten der Parser mal auszuloten.
Nach meinen Tests kann ich sagen, dass folgendes unterstützt wird:

Addition (+)
Subtraktion (-)
Multiplikation (*)
Division (/)
Wurzel (SQR())
Potenz (^)

Wichtig:Der nun folgende Code funktioniert nur mit der MDB-Lib
von Paul Leischow und ist somit vorerst nur unter PB 3.94 lauffähig, da es
diese Lib meines Wissens noch nicht für PB 4.0 gibt.

Wer sich keine Gedanken um eine temporäre Datenbank machen muss,
weil in seiner Anwendung bereits eine MDB verwendet wird, muss dann
natürlich die MDB-Lib nicht mehr verwenden.

Code: Alles auswählen

Global MathParserDatabase$

Procedure.s GetTempDir()
  TempDir$ = Space(#MAX_PATH+1)
  GetTempPath_(#MAX_PATH+1,TempDir$) 
  ProcedureReturn TempDir$
EndProcedure

Procedure DeleteMathParserDatabase()
  If FileSize(MathParserDatabase$ + ".mdb") > 0 : DeleteFile(MathParserDatabase$ + ".mdb") : EndIf
EndProcedure  

Procedure.l InitMathParser()
  
  If InitDatabase() 
    DeleteMathParserDatabase()
    If MDB_Create(MathParserDatabase$) 
      dbHandle=MDB_Connect(GetTempDir(),"MathParser","","") 
      If dbHandle
        If DatabaseQuery("Create Table tblMathParser (fldMathParser LONG)")
          If DatabaseQuery("Insert Into tblMathParser (fldMathParser) Values (1)")
            ProcedureReturn dbHandle
          Else ; Insertion of MathParser-Data failed
          EndIf
        Else ; Table-Creation failed
        EndIf
      Else ; MDB-Connection failed
      EndIf
    Else ; MDB-Creation failed
    EndIf
  Else ; Couldn't init database-system
  EndIf
  
EndProcedure    

Procedure.s GetExpressionResult(Expression$)
  
  If DatabaseQuery("Select (" + Expression$ + ") From tblMathParser Where fldMathParser = 1")
    NextDatabaseRow()
    ReturnValue$ = GetDatabaseString(0)
    If ReturnValue$ = "" : ReturnValue$ = "Couldn't calculate Formula" : EndIf
  Else
    ReturnValue$ = DatabaseError()
  EndIf
  
  ProcedureReturn ReturnValue$
  
EndProcedure

MathParserDatabase$ = GetTempDir() + "MathParser"

DatabaseID = InitMathParser()
    
If DatabaseID = 0
  MessageRequester("", "Couldn't init MathParser")
  DeleteMathParserDatabase()
  End
EndIf

Repeat
  Eingabe$=InputRequester("MathParser", "Enter your formula to calculate (ESC to exit):", Eingabe$)
  If Eingabe$ = "" : Break : EndIf
  MessageRequester("Result:", GetExpressionResult(Eingabe$))
ForEver
  
CloseDatabase(DatabaseID)

DeleteMathParserDatabase()

MDB_Disconnect("MathParser")

Noch 'ne kleine Anmerkung: In Grenzen kann auch SQLite mathematische
Ausdrücke parsen. Einfach mal ausprobieren!

Viel Spatz ... Kiffi