Deutsch
Forum

Parser

 
- Seite 1 -



Julian
Schmidt
Hallo,
ich habe mich mal an einem kleinen Parser probiert.
Evtl. sind in diesen allerdings noch ein paar kleinere Fehler drin.

Vlt. könnt ihr mir helfen.
KompilierenMarkierenSeparieren
WindowTitle "Simple Parser"
Windowstyle 24
Window (%maxx-280)\2,(%maxy-210)\2 - 280,210
Var ed_calc&=Create("Edit",%hwnd,"5+(30*10)",10,10,width(%hwnd)-20,20)
Var lb_calc&=Create("ListBox", %hwnd, 0, 10, 40, width(%hwnd)-20, 100)
Var bt_calc&=Create("Button",%hwnd,"Ausrechnen",10,150,width(%hwnd)-20,25)
Declare calc$,pos_z1%

WhileNot iskey(27)

    Waitinput 300

    If getfocus(bt_calc&) or iskey(13)

        ClearList lb_calc&
        calc$=Translate$(Translate$(GetText$(ed_calc&),",",".")," ","")
        Addstring(lb_calc&,calc$)

        If (InStr(")",calc$)<>0) and (InStr("(",calc$)<>0)

            while (InStr(")",calc$)<>0) and (InStr("(",calc$)<>0)

                whileloop InStr(")",calc$),1,-1

                    pos_z1%=&loop
                    case (Mid$(calc$,pos_z1%,1)="(") :  break

                Endwhile

                calc$=Init_Parse(Mid$(calc$,pos_z1%+1,InStr(")",calc$)-(pos_z1%+1)),Mid$(calc$,1,pos_z1%-1),Mid$(calc$,InStr(")",calc$)+1,Len(calc$)-InStr(")",calc$)))

            Endwhile

        Else

            calc$=Translate$(Translate$(calc$,")",""),"(","")

        Endif

        Init_Parse(calc$)
        Setfocus(ed_calc&)

    Endif

EndWhile

Proc Init_Parse

    Parameters math$, str1$, str2$

    WhileNot iskey(27)

        Case GetString$(lb_calc&,Getcount(lb_calc&)-1)<>str1$+math$+str2$ : Addstring(lb_calc&,str1$+math$+str2$)

        If (InStr("^",math$)<>0)

            Parse("^")

        ElseIf (InStr("*",math$)<>0)

            Parse("*")

        ElseIf (InStr("+",math$)<>0)

            Parse("+")

        ElseIf (InStr("-",math$)<>0)

            Parse("-")

        ElseIf (InStr("\",math$)<>0) or (InStr("/",math$)<>0)

            Parse("\")

        Else

            Settext ed_calc&,math$
            break

        EndIf

    EndWhile

    Return str1$+math$+str2$

EndProc

Proc Parse

    Parameters op$
    Declare pos_z2%, z1$,z2$
    Var pos_op%=InStr(op$,math$)

    Whileloop pos_op%-1,0,-1

        If (Mid$(math$,&loop,1)="+") or (Mid$(math$,&loop,1)="-") or (Mid$(math$,&loop,1)="\") or (Mid$(math$,&loop,1)="/") or (Mid$(math$,&loop,1)="*") or (Mid$(math$,&loop,1)="^") or (trim$(Mid$(math$,&loop,1))="")

            z1$=Mid$(math$,&loop+1,pos_op%-(&loop+1))
            pos_z1%=&loop+1
            break

        Endif

    EndWhile

    Whileloop pos_op%+1,Len(math$)+1,1

        If (Mid$(math$,&loop,1)="+") or (Mid$(math$,&loop,1)="-") or (Mid$(math$,&loop,1)="\") or (Mid$(math$,&loop,1)="/") or (Mid$(math$,&loop,1)="*") or (Mid$(math$,&loop,1)="^") or (trim$(Mid$(math$,&loop,1))="")

            z2$=Mid$(math$,pos_op%+1,&loop-(pos_op%+1))
            pos_z2%=&loop
            break

        Endif

    EndWhile

    If ((op$="\") and (z2$="0"))

        math$="Division durch NULL!"

    Else

        Var erg$=Str$(If(op$="+",Val(z1$)+Val(z2$),If(op$="-",Val(z1$)-Val(z2$),If(op$="*",Val(z1$)*Val(z2$),If(op$="\",Val(z1$)/Val(z2$),If(op$="^",Val(z1$)^Val(z2$),"Error"))))))
        math$=Mid$(math$,1,pos_z1%-1)+erg$+Mid$(math$,pos_z2%,(Len(math$)+1)-pos_z2%)
        Settext ed_calc&,math$

    Endif

EndProc


Scheint soweit allerdings zu funktionieren. Nur bei dem Klammern!?

LG

Julian
 
XProfan X2
Win7 Home Premium, SP1, AMD Athlon(tm) II Neo K125 Processor

˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗
Webseite [...] 
11.09.2012  
 



 
- Seite 1 -



Julian
Schmidt
Jo, schon gesehen. Hilft mir aber nicht wirklich!
Ich bin eher auf Fehlersuche und würde gerne einfach mal einige Fälle von euch hören wo mein Taschenrechner versagt und evtl. eine Strategie zur Lösung des Problems.

Evtl. habe ich ja sogar einige Rechenregeln außer Acht gelassen, welche wichtig wären!??
Evtl. auch Anregungen zum Programmier-Style, und wie man gewisse Dinge kürzen könnte.
 
XProfan X2
Win7 Home Premium, SP1, AMD Athlon(tm) II Neo K125 Processor

˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗
Webseite [...] 
11.09.2012  
 



Gibt ja erstmal nur Klammer vor Punkt und Punkt vor Strich umzusetzen.

Funktioniert das denn bereits fehlerfrei?

Tricky ist eher sowas wie -5 + -1
 
11.09.2012  
 




Julian
Schmidt
Klammer vor Potenz vor Punkt vor Strich funktioniert bereits zum Großenteil. Nur gibt es bei bestimmten Klammerabfolgen leider noch Probleme.
Etwa bei "5+(30*(4/2)+10)". Kann es momentan selbst mit TraceModus nicht ganz nachvollziehen. Scheint irgendwie mit dem Geteilt innerhalb der Klammer zusammenzuhängen. Mit Mal funktioniert es ganz hervorragend!

Wie würdest du, die Geschichte mit dem negativen Zahlen angehen?
 
XProfan X2
Win7 Home Premium, SP1, AMD Athlon(tm) II Neo K125 Processor

˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗
Webseite [...] 
11.09.2012  
 



Das hängt sehr davon ab was genau Dein Parser später mal alles können soll -

diese Information fehlt mir z.B. .

Ich würde wohl wie in xpse umgesetzt immer einen Parser herstellen der möglichst

flexibel ist und eben egal welche Argumente von links nach rechts parsen und auflösen

kann. Wenn Du nur bisl Matheformeln parsen möchtest dann kannst für das Minus-

Vorzeichen einfach Ausnahmen/ Erkennungen programmieren. Hat zwar nichts mit

dem Thema zu tun aber Du kannst auch XProfan selbst verwenden wie z.B. in

XP-Script [...]  (was aber nur bis XP vollständig korrekt funktioniert).
 
12.09.2012  
 




Julian
Schmidt
Kannst du nochmal konkret etwa zu, wie man am Besten einen flexiblen Parser baut und zur Ausnahme\Erkennung einer negativen Zahl sagen?
 
XProfan X2
Win7 Home Premium, SP1, AMD Athlon(tm) II Neo K125 Processor

˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗
Webseite [...] 
12.09.2012  
 



Ich schrieb ja bereits:

Das hängt sehr davon ab was genau Dein Parser später mal alles können soll -

diese Information fehlt mir z.B. .
 
12.09.2012  
 




Julian
Schmidt
Konkret +,-,*,\,^ und den richtigen Umgang mit Klammern, Minuszahlen. Evtl. Wurzel bzw. Wurzel_n und Logarithmus.
 
XProfan X2
Win7 Home Premium, SP1, AMD Athlon(tm) II Neo K125 Processor

˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗
Webseite [...] 
12.09.2012  
 




Julian
Schmidt
Wie würdest du den einen Parser möglichst flexibel schreiben?
Wie programmiert man am besten eine "Minus-Vorzeichen Ausnahmen/ Erkennungen"?
 
XProfan X2
Win7 Home Premium, SP1, AMD Athlon(tm) II Neo K125 Processor

˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗
Webseite [...] 
15.09.2012  
 



Erstmal brauchst paar Helferfunktionen.

Z.B. eine Funktion parse schreiben die z.B. 2 Longs als Param erhält:

SpeicherAddr,BytesToParse

und die Anzahl der geparsten Bytes zurückliefert.

Wenns ein Ansi-Parser werden soll dann ist BytesToParse ist ein 256 Byte großer

Speicher - einfach Dim nehmen. Darin sind alle Bytes auf True die die Funktion

parse mitnehmen soll. Quasi.

byte BytesToParse,65=1,1,1,1,1

womit die Chars A;B;C;D;E gemeint wären -

also die Funktion nur so lange ließt wie diese Chars auftreten.

Ist halt wohl das Schnellste da solch Funktion parse nur gezielte/ direkte Speicherzugriffe

braucht um zu ermitteln was los ist.

quasi while byte(BytesToParse,byte(SpeicherAddr,pos++)) statt 17 ifs und instrs -

also komplett ohne Instr und herumsucherei.

Wenn das erste Zeichen eine Klammer ist hat die Funktion z.B. auch die Eigenheit,

die aufgehenden Klammern zu zählen und auch dann die Anzahl gelesener Bytes

zurückzuliefern wenn, die Anzahl der Klammern von 1 auf 0 springt - so kannst

einfach die Klammern dann wegoperieren da immer das erste und das letzte

Zeichen Klammern sind wenn das erste Zeichen eine Klammer ist.

Dies ist dann meist 1 Argument das man in einer extra Liste ablegen

kann für späteres weiteres zerlegen.

Mache aus:

1+(10*20)+5

Listboxeinträge:


add 1
add 10*20
add 5

und in einem weitere Pass:


add 1
add tmp1,10
mul tmp1,20
add tmp1
add 5


quasi auflösen bis es nur noch Operationen gibt die Du in der Liste als "kann

ich ohne weitere OP ausrechnen" markiert hast.

Nach diesem Verfahren kannst beliebig-komplexe und mehrzeilige Argumente-

Ketten auflösen.
 
17.09.2012  
 




Julian
Schmidt
hmmmm...ich muss ich ehrlich gestehen ich habe nur Bahnhof verstanden.

Wie würdest du einen Parser möglichst flexibel, unter Verwendung von (Teil)string-Funktionen, schreiben?
 
XProfan X2
Win7 Home Premium, SP1, AMD Athlon(tm) II Neo K125 Processor

˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗
Webseite [...] 
17.09.2012  
 



 
- Seite 2 -



Andreas
Koch
Hallo Julian,

ich bin zwar nicht angesprochen worden, glaube aber zu wissen, was iF meint, da ich genau so einen Parser mal geschrieben habe.
Die Grundüberlegung ist, dass man auch die komplizierteste Formel in Bestandteile (substr) zerlegen kann, die nach dem Schema "Variable Operator Variable" aufgebaut sind. Beispiel: "a+b" oder "a*b" oder "a^b" usw. a und b funktionieren dabei als Platzhalter und können selbst beliebig kompliziert sein, eigentlich werden sie als komplett neue Formel behandelt. Wenn man die Formel lange und fein genug aufdröselt, erhält man irgendwann etwas, was man ausrechnen kann und setzt dann rückwärts ein. Ich will versuchen es an einem Beispiel deutlicher zu machen:

25+8*(6-3*(15-3))

1. Stufe: 25+a a=8*(6-3*(15-3))
2. Stufe: 8*b b=6-3*(15-3)
3. Stufe: 6-c c=3*(15-3)
4. Stufe: 3*d d=15-3

Nun kann ich d ausrechnen und muss nur wieder rückwärts einsetzen:
d=12
c=3*d=36
b=6-c=-30
a=8*b=-240
ans=25-240=-215

Anstatt a b c und d empfehlen sich natürlich Listboxeinträge und keine Buchstaben.

Schönen Gruß

Andreas
 
19.10.2012  
 




Julian
Schmidt
Danke, für deine Antwort.
Mir war imho schon klar was ein Parser ist, ich habe ja auch schon einen selbst geschrieben (siehe Ausgangsbeitrag).
Mir ging es viel mehr darum, wie man einen Parser möglichst flexibel programmiert um schnell weitere Rechengesetze wie zum Beispiel Klammerregeln etwa. Binomische Formeln oder weitere Rechenoperatoren wie Wurzel oder Logarithmus oder das korekte erkennen von negativen Zahlen einzufügen
IF hatte schon dargelegt wie er einen Parser in dem Byte für Byte geparst wird schreiben würde. Dies war für meinen Geschmack leider etwas zu kompliziert (oder einfach nur für den Laien unverständlich formuliert).....
Gruß
 
XProfan X2
Win7 Home Premium, SP1, AMD Athlon(tm) II Neo K125 Processor

˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗
Webseite [...] 
19.10.2012  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

11.788 Betrachtungen

Unbenanntvor 0 min.
RudiB.15.04.2020
Christof Neuß19.01.2020
Peter Max Müller18.05.2018
Matthias Arlt18.02.2016
Mehr...

Themeninformationen

Dieses Thema hat 3 Teilnehmer:

Julian Schmidt (8x)
iF (5x)
Andreas Koch (1x)


Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie