Ich implementiere derzeit einen Ausdrucksauswerter (einzeilige Ausdrücke wie Formeln), der auf Folgendem basiert:
- Der eingegebene Ausdruck wird tokenisiert, um Literal-Boolesche Werte, Ganzzahlen, Dezimalstellen, Zeichenfolgen, Funktionen und Bezeichner (Variablen) zu trennen.
- Ich habe den Shunting-Yard-Algorithmus implementiert (leicht modifiziert, um Funktionen mit variabler Anzahl von Argumenten zu handhaben), um Klammern zu entfernen und die Operatoren mit einer anständigen Priorität in einer nachfixierten Reihenfolge zu ordnen
- Mein Rangierplatz erzeugt einfach eine (simulierte) Warteschlange von Token (mithilfe eines Arrays kann meine Powerbuilder Classic-Sprache Objekte definieren, verfügt jedoch nur über dynamische Arrays als nativen Speicher - keine echte Liste, kein Wörterbuch), die ich nacheinander mit a auswerte einfache Stapelmaschine
Mein Evaluator arbeitet gut, aber ich vermisse immer noch einen if()
und frage mich, wie ich vorgehen soll.
Wenn ich bei meiner nachträglichen und stapelbasierten Rangierauswertung if()
als weitere Funktion mit einem wahren und einem falschen Teil hinzufüge , zeigt eine einzelne if(true, msgbox("ok"), msgbox("not ok"))
beide Nachrichten an, während ich nur eine anzeigen möchte. Dies liegt daran, dass beim Auswerten einer Funktion bereits alle Argumente ausgewertet und auf den Stapel gelegt wurden.
Könnten Sie mir eine Möglichkeit geben, if()
faul zu implementieren ?
Ich habe überlegt, diese als eine Art Makro zu verarbeiten, aber zu einem frühen Zeitpunkt habe ich noch keine Zustandsbewertung. Vielleicht muss ich eine andere Art von Struktur als eine Warteschlange verwenden, um die Bedingung und die wahren / falschen Ausdrücke getrennt zu halten? Im Moment wird der Ausdruck vor der Auswertung analysiert, aber ich plane auch, die Zwischendarstellung als eine Art vorkompilierten Ausdruck für die zukünftige Auswertung zu speichern.
Bearbeiten : Nach einigem Nachdenken über das Problem denke ich, ich könnte eine Baumdarstellung meines Ausdrucks erstellen (ein AST anstelle eines linearen Token-Streams), aus der ich den einen oder anderen Zweig von mir leicht ignorieren könnte if()
.