![]() |
AW: Parser: Operatoren
Ja, er sucht mittels Pos(), also aktiv. Zudem gibt mir mein FindToken() den ersten Operator zurück, der nicht in Klammern steht, jap. Wird kein OP ausserhalb von Klammern gefunden, fällt meine If-Then-Wurst in einen Zweig
Delphi-Quellcode:
durch.
if (s[1] = '(') and (s[High(s)] = ')') then result := Parse(copy(s, 2, Length(s)-2));
Ich hab mit der Technik jetzt ziemlich alle trivialen Dinge abgedeckt: "Normale" Operatoren (^,*,/,+,-), Funktionen mit 1-3 Parametern (sin(), cos(), ...), logische Operatoren (and, or, not, ...) sowie das Vorzeichenminus, Klammerung und Operatorenrang wie in der Mathematik üblich, wobei ich logischen Operatoren noch Vorrang vor diesen gewähre. (Dort ist sogar der ternäre Operator in Form eines IfThen() dabei.) Unäre Operatoren wären leicht umzusetzen, wenn diese Zeichen dann von Variablen- und Konstantenbezeichnern als Bestandteil ausgeschlossen würden - fände man einen solchen, wird alles bis zum nächsten Operator als Argument aufgefasst, oder via Klammerung eindeutig gemacht. Ähnlich ließe sich mit unären Postfix-Operatoren verfahren, nur eben in die andere Richtung. Dass dieses Vorgehen nicht unbedingt einem reinen sprachtheoretischen Lexer entspricht stimmt, jedoch ist es schlank, übersichtlich, recht intuitiv und wartbar (auch nach 6-7 Jahren noch, ich hab nämlich die Boolschen OPs erst letzte Woche nachgerüstst, auf einem Stand, den ich zuletzt 2006 gesehen habe glaube ich). Schmankerl sind registrierbare Konstanten und Variablen, letztere als Pointer auf eine Delphi-Variable, so dass sie zur Laufzeit geändert werden können, ohne den String neu parsen zu müssen. Zudem werden alle konstanten Teile des Baumes vorab gelöst und als Konstanten-Blatt eingefügt, so dass diese in dem Fall auch nicht immer wieder erneut aufgelöst werden müssen. Ergo: Das Teil ist sogar richtig flott, gerade bei wiederholter Ausführung der gleichen Formel mit unterschiedlichen Variableninhalten. Für eine allgemeine, formale Grammatik mag das ggf. nicht taugen. Für logische und mathematische Terme war mir das bisher der angenehmste und universellste Ansatz, der zudem zu einer günstigen Datenstruktur führt. |
AW: Parser: Operatoren
Zitat:
a) int i=j++-++x; // geht b) int i=j+++++x; // geht nicht Bei A liefert der Tokenizer: id(int) id(i) symbol(assignment) id(j) symbol(plusplus) symbol(minus) symbol(plusplus) id(x) Bei B liefert der Tokenizer: id(int) id(i) symbol(assignment) id(j) symbol(plusplus) symbol(plusplus) symbol(plus) id(x) Würde der Parser das erkennen, wären beide Zeilen kompilierbar. Aber nur die erste Zeile funzt, eben weil der Scanner so blöd ist, und im Fall B die ersten zwei Plus-Paare erkennt. Probier's mal aus. Zitat:
Zitat:
Zitat:
Zitat:
|
AW: Parser: Operatoren
Zitat:
Zitat:
|
AW: Parser: Operatoren
In meinem Compiler habe ich rekursives parsen eingebaut. Undzwar wie folgt:
(von oberer zu unterer schicht, niedrigstes level bindet am stärksten): releation := expression (relop Expression) expression := Term (+- Term)* term := factor (*/ Factor)* factor := Var|Constant|Function call| '(' relation ')' wenn ich bei Factor vor meinem wert ein '-' finde, weiß ich es ist ein vorzeichen. Die funktionen liefern übrigens bei mir einen Datentyp zurück. So kann ich ich typensicherheit verfolgen :stupid: edit @idefix: ich glaib dieses operator gewurschtel ist von delphi erlaubt, finde ich perönlich nicht so schön |
AW: Parser: Operatoren
Zitat:
Delphi-Quellcode:
?
1+-+-+-+-+-2
Wenn man klammern setzt, dann läßt sich erkennen, daß es damit eigentlich keine Probleme geben sollte.
Delphi-Quellcode:
1+(-(+(-(+(-(+(-(+(-2)))))))))
Man könnte aber auch einfach die Plus/Minus zählen und entsprechend handeln. So mach ich das in meinem Billigparser. Das erste Plus Der erste Operator ist die Rechenoperator und die +/- danach sind das Vorzeichen. * alle Plus (Vorzeichen) werden stur ignoriert (da eh ohne Wirkung) * die Minus werden gezählt ... bei einer ungeraden Anzahl ist es ein "-" und bei einer geraden Anzahl ein ignorierbares "+".
Delphi-Quellcode:
ergibt dann ein
1+(-+-+-+-+-2)
Delphi-Quellcode:
, also
1+(-- -- -2)
Delphi-Quellcode:
:)
1+(-2)
|
AW: Parser: Operatoren
Zitat:
Delphi-Quellcode:
:P
1-2
Ja die operatoren schlange macht vielleicht 'sinn' aber sie ist extrem hässlich und zum glück vernab jeglicher praktischer verwendung. |
AW: Parser: Operatoren
Zitat:
Zitat:
|
AW: Parser: Operatoren
Zitat:
Bei Computern ist das in der Regel anders, aber das liegt daran, dass Informatiker halt manchmal ihre eigenen Regeln und Konventionen aufstellen und sich nicht an die aus der Mathematik halten. Z.B. ist ja auch der Ursprung des Koordinatensystems beim Computer meist links oben, während er sich in der Mathematik normalerweise links unten befindet. Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz