Parser für in einem String formulierte Aufgaben.

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Parser für in einem String formulierte Aufgaben.

Beitrag 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
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Parser für in einem String formulierte Aufgaben.

Beitrag von STARGÅTE »

Am einfachsten ist es eine SQL Anfrage zu stellen:
Expression as INPUT?

Ansonsten suche mal in den Foren nach "Eval"
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
berie
Beiträge: 75
Registriert: 17.01.2018 08:52
Computerausstattung: Windows 11 64 bit, i7, 16GB RAM
Wohnort: Wesertal in Nordhessen

Re: Parser für in einem String formulierte Aufgaben.

Beitrag 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.
formerly known as bizzl
berie
Beiträge: 75
Registriert: 17.01.2018 08:52
Computerausstattung: Windows 11 64 bit, i7, 16GB RAM
Wohnort: Wesertal in Nordhessen

Re: Parser für in einem String formulierte Aufgaben.

Beitrag 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).
formerly known as bizzl
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Parser für in einem String formulierte Aufgaben.

Beitrag von tft »

Hallo, das sieht gut aus.

Darf ich das verwenden ?

gruss TFT
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
berie
Beiträge: 75
Registriert: 17.01.2018 08:52
Computerausstattung: Windows 11 64 bit, i7, 16GB RAM
Wohnort: Wesertal in Nordhessen

Re: Parser für in einem String formulierte Aufgaben.

Beitrag 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 :D

Gruß berie
formerly known as bizzl
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Parser für in einem String formulierte Aufgaben.

Beitrag 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
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
berie
Beiträge: 75
Registriert: 17.01.2018 08:52
Computerausstattung: Windows 11 64 bit, i7, 16GB RAM
Wohnort: Wesertal in Nordhessen

Re: Parser für in einem String formulierte Aufgaben.

Beitrag 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 ?") :D

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 :D :D :D
formerly known as bizzl
Benutzeravatar
tft
Beiträge: 605
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Parser für in einem String formulierte Aufgaben.

Beitrag von tft »

die Sache mit dem Bier ... hört sich gut an ..... und ich werde 55 ....

Gruss TFT
TFT seid 1989 , Turgut Frank Temucin , Dachsen/Berlin/Antalya
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMAgic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
berie
Beiträge: 75
Registriert: 17.01.2018 08:52
Computerausstattung: Windows 11 64 bit, i7, 16GB RAM
Wohnort: Wesertal in Nordhessen

Re: Parser für in einem String formulierte Aufgaben.

Beitrag von berie »

Und ich werde in knapp 3 Wochen 56...

Gruß
berie
formerly known as bizzl
Antworten