Seite 1 von 2
Parser für in einem String formulierte Aufgaben.
Verfasst: 23.09.2020 17:11
von tft
Hallo,
ich suche ein Modul oder eine Funktion, die eine Matematische Aufgabe ausführt. Zum Beispiel ergebniss.i = Rechne("13+26/4") . Hat jemand sowas schon gemacht ?
Gruss TFT
Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 23.09.2020 17:37
von STARGÅTE
Am einfachsten ist es eine SQL Anfrage zu stellen:
Expression as INPUT?
Ansonsten suche mal in den Foren nach "Eval"
Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 23.09.2020 17:54
von berie
Ich habe vor einigen Jahren mal was gebastelt:
Code: Alles auswählen
EnableExplicit
Enumeration 1
#_plus
#_minus
#_mal
#_teil
#_sin
#_cos
#_tan
#_sqr
#_sqrt
#_cube
EndEnumeration
Structure sTermListe ;hier wird der übergebene Ausdruck gespeichert
pri.i
StructureUnion
operand.d
operator.i
EndStructureUnion
;In der StructureUnion steht entweder ein Operator (#_plus,#_minus usw.),
; dann steht in "pri" seine Priorität,
;oder ein Operand, dann steht in "pri" -1
EndStructure
Procedure.d Rechnen(Ausdruck.s)
Protected NewList TermListe.sTermListe() ;hier stehen die zerlegten Teilausdrücke
Protected c,pri,index
Protected.s m,term
Protected.d l,r
;"Ausdruck" "normalisieren"
Ausdruck=LCase(Ausdruck) ;in Kleinbuchstaben wandeln
Ausdruck=RemoveString(Ausdruck," ") ;Leerzeichen und...
Ausdruck=RemoveString(Ausdruck,Chr(9)) ;... Tabs löschen
Ausdruck=ReplaceString(Ausdruck,",",".") ;Kommata in Dezimalpunkte umwandeln
;In "Ausdruck" steht jetzt der "normalisierte" "Ausdruck"
;"Ausdruck" zerlegen
With TermListe()
For c=1 To Len(Ausdruck)
m=Mid(Ausdruck,c,1) ;Zeichen für Zeichen holen
If m="(":pri+100:Continue:EndIf ;runde Klammer auf -> Priorität rauf
If m=")":pri-100:Continue:EndIf ;runde Klammer zu -> Priorität wieder runter
If m="-" And term="":term="-":Continue:EndIf ;negative Zahl?
If (m>="0" And m<="9") Or m="." ;Ziffer oder Dezimalpunkt ?
term+m ;Zahl "zusammenbauen"
Else ;Rechenzeichen ?
AddElement(TermListe())
\operand=ValD(term)
\pri=-1
term=""
AddElement(TermListe()) ;Operatoren eintragen
Select m
Case "+":\pri=pri+10:\operator=#_plus
Case "-":\pri=pri+10:\operator=#_minus
Case "*":\pri=pri+11:\operator=#_mal
Case "/":\pri=pri+11:\operator=#_teil
Default
If FindString(Ausdruck,"sin",c)=c:\pri=pri+20:\operator=#_sin:c+2
ElseIf FindString(Ausdruck,"cos",c)=c:\pri=pri+20:\operator=#_cos:c+2
ElseIf FindString(Ausdruck,"tan",c)=c:\pri=pri+20:\operator=#_tan:c+2
ElseIf FindString(Ausdruck,"sqrt",c)=c:\pri=pri+20:\operator=#_sqrt:c+3
ElseIf FindString(Ausdruck,"sqr",c)=c:\pri=pri+20:\operator=#_sqr:c+2
ElseIf FindString(Ausdruck,"cube",c)=c:\pri=pri+20:\operator=#_cube:c+3
Else
MessageRequester("Unbekannter Ausdruck:",Right(ausdruck,Len(Ausdruck)-c+1))
End
EndIf
EndSelect
EndIf
Next
;letzten Operanden anhängen
AddElement(TermListe())
\operand=ValD(term)
\pri=-1
term=""
;Liste gültig ?
If ListSize(TermListe())=1
FirstElement(TermListe())
ProcedureReturn \operand
EndIf
;Liste nach der jeweils höchsten Priorität durchsuchen und Teilausdruck berechnen
Repeat
pri=0
ForEach TermListe()
If \pri>pri
pri=\pri
index=ListIndex(TermListe())
EndIf
Next
SelectElement(TermListe(),index) ;<- Der Teilausdruck mit der höchsten Priorität
PreviousElement(TermListe()) ;linken Operanden holen...
l=\operand
DeleteElement(TermListe()) ;... und aus der Liste löschen
NextElement(TermListe()):NextElement(TermListe()) ;rechten Operanden holen...
r=\operand
DeleteElement(TermListe()) ;... und aus der Liste löschen
\pri=-1
Select \operator ;Ergebnis des Teilausdrucks berechnen und anstelle des Operators speichern
Case #_plus:\operand=l+r
Case #_minus:\operand=l-r
Case #_mal:\operand=l*r
Case #_teil
If r=0:MessageRequester("Fehler !","Division durch 0 !"):ProcedureReturn NaN() :EndIf
\operand=l/r
Case #_sin:\operand=Sin(Radian(r))
Case #_cos:\operand=Cos(Radian(r))
Case #_tan:\operand=Tan(Radian(r))
Case #_sqr:\operand=Pow(r,2) ; SQuaRe
Case #_sqrt
If r<0:MessageRequester("Fehler !","Quadratwurzel einer negativen Zahl !"):ProcedureReturn NaN() :EndIf
\operand=Sqr(r) ; SQuareRooT
Case #_cube:\operand=Pow(r,3)
EndSelect
Until ListSize(TermListe())=1
ProcedureReturn \operand
EndWith
EndProcedure
Debug Rechnen("3 +4*1 2, 5* s i N(45)+456") ;sollte 494.35533905932738 rauskommen
Debug Rechnen("33*12+9") ;=405
Debug Rechnen("33*(12+9)") ;=693
Debug Rechnen("1/2") ;=0.5
Debug Rechnen("sqr(4)+sqrt(16)") ;=20
Debug Rechnen("sqrt(4)+sqr(16)") ;=258
Debug Rechnen("sqrt(9,56") ;=3.0919249667480613
Debug Rechnen("sqr(122.789") ;=15077.138521000001
Debug Rechnen("sqrt(16+9)") ;=5
Debug Rechnen("cube(9)") ;=729
Einige Zeit später habe ich auch eine Version mit Eingabemöglichkeit und Variablen programmiert.
Man konnte also schreiben
"a=3*4"
"b=59.5-3"
"a*b" <- Hier keine Variable und kein "=" angegeben, weil ich das Ergebnis nicht speichern will.
Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 23.09.2020 18:32
von berie
Habe den urspünglichen Beitrag wiedergefunden:
viewtopic.php?f=8&t=26632&hilit=formelparser
Das ist sieben (!!!) Jahre her - Mein Gott, wie schnell vergeht die Zeit...
Werde ich jetzt wegen Doppelpost gesperrt ? (Hoffentlich nicht).
Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 24.09.2020 15:18
von tft
Hallo, das sieht gut aus.
Darf ich das verwenden ?
gruss TFT
Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 24.09.2020 16:48
von berie
tft hat geschrieben:Hallo, das sieht gut aus.
Darf ich das verwenden ?
gruss TFT
Hallo tft,
du kannst damit machen, was du willst.
Wenn du Geld damit verdienst, würde ich mich über einen kleinen Obolus freuen
Gruß berie
Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 24.09.2020 18:24
von tft
Hallo,
ich werde dir das Ergebniss schicken .... und sollte ich damit Geld verdiene ...... werde ich dich sicher vergessen

aber nicht aus gehässigkeit. Sondern weil ich schon so alt bin.
Gruss TFT
Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 24.09.2020 19:07
von berie
tft hat geschrieben:Hallo,
ich werde dir das Ergebniss schicken .... und sollte ich damit Geld verdiene ...... werde ich dich sicher vergessen

aber nicht aus gehässigkeit. Sondern weil ich schon so alt bin.
Gruss TFT
Wenn ich das fragen darf: Wie alt bist Du denn ? (Oder sollte ich lieber fragen "Wie alt sind Sie denn ?")
Mit "Obolus" meinte ich nun keine tausende Euros (oder Franken), sondern eine kleine Anerkennung in Form von
einem Päckchen MonCherie, Toffifee, Toblerone, eine Flasche Wein oder eine Kiste Weizenbier

Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 25.09.2020 21:25
von tft
die Sache mit dem Bier ... hört sich gut an ..... und ich werde 55 ....
Gruss TFT
Re: Parser für in einem String formulierte Aufgaben.
Verfasst: 25.09.2020 22:03
von berie
Und ich werde in knapp 3 Wochen 56...
Gruß
berie