C# Problem mit Expression Parser

lordfritte

Lieutenant
Dabei seit
Juli 2006
Beiträge
811
Hallo ich möchte gernen einen Expression Parser schreiben, jetzt möchte ich auch den ganzen Komfor von Funktionen und Klammern zum verschachteln nutzen.
Mein Problem ist jetzt folgendes: Wie unterscheide zwischen einer Klammer vom verschachteln und einer Funktionsklammer?

Also ich habe winwn Regex ausdruck: "([+\-*/%()]{1}|[=<>!]{1,2}|[&|]{2})" der Auch funktioniert, also er splittet mir einzelne Ausdrücke in einen string[] aber auch die Funktionsklammern werden gesplitet, lässt sich das verhindern?
 
Zuletzt bearbeitet:
1

1668mib

Gast
Wie unterscheidest du denn das selbst?
Weil du genau weißt, was das für eine Klammer sein muss. Dazu gibt's eine Grammatik. Nach einer Funktion kann eine Klammer ja nur genau eine Bedeutung haben, genauso auch sonst. Es ist immer eindeutig, was gemeint ist.

Ich glaube du wählst für deinen Parser einen falschen Ansatz, sonst hättest du das Problem gar nicht - zugegeben, der richtige Ansatz ist auch nicht ganz leicht...
 

lordfritte

Lieutenant
Ersteller dieses Themas
Dabei seit
Juli 2006
Beiträge
811
Ich müsste also überprüfen ob das vor der Klammer eine Funktion ist. Lässt sich das irgendwie auf den Regexausdruck übertragen, dass er alle ausdrücke trennt aus bei so was: Add(*)
 

Skuzzle

Lt. Junior Grade
Dabei seit
Apr. 2008
Beiträge
362
Hi,

mathematische Ausdrücke lassen sich nicht in einer regulären Grammatik darstellen, dafür benötigst du eine kontextfreie Grammatik.
Mit regulären Ausdrücken lässt sich aber sehr gut das Eingabe Alphabet für die kontextfreie Grammatik definieren.
Für einen Parser brauchst du grundsätzlich 2 Dinge:
1. Den Scanner
Der Scanner zerlegt die Eingabe anhand regulärer Ausdrücke in Tokens. Ein Token ist ein für den Parser verständliches Symbol. Betrachtet man folgende Eingabe (man nennt dies die Infix Notation):
5 * (10 + 3) würde der Scanner daraus folgendes machen:

Zahl (5)
Multiplikation
Klammer Auf
Zahl (10)
Addition
Zahl (3)
Klammer Zu

2. Parser
Jetzt kommt der Parser ins Spiel. Der erledigt in diesem Fall gleich 2 Aufgaben gleichzeitig.
1. Ist die Eingabe korrekt (entspricht sie der Grammatik)?
2. Er wandelt die Eingabe in die Postfix Notation um. Postfix hat den Vorteil, das sie ohne klammern auskommt. Der Parser muss die Formel also unter Berücksichtigung der Priorität von Operatoren (Punkt- vor Strichrechnung) sowie der Klammerung korrekt umstellen. Unsere Eingabe würde also so umgeformt werden:
10 3 + 5 *

Die Postfix Notation kann man sehr einfach mit Hilfe eines LiFo Stacks ausrechnen.

Relativ einfach kann man so einen Parser als "Top Down Parser" umsetzen. Die Umsetzung einer Kontextfreien Grammatik ist damit sehr einfach, das Prinzip muss allerdings erstmal verstanden werden.

So, das ist das grobe Konzept. Wenn dich das ganze interessiert, verfolg es weiter, such im Internet und frag für Einzelheiten nochmal nach (gern auch per pm). Ist im großen und ganzen nicht einfach das Thema. Wir bewegen uns hier übrigens im Themengebiet "Compilerbau" ;)
 
1

1668mib

Gast
Skuzzle hat den richtigen Ansatz skizziert. Vielleicht findest du auch noch nützliche Beispiele dazu... Oftmals wird hier von Tokens gesprochen, und in vielen Parsern gibt es dann eine Funktion "GetToken" (hilft evtl wenn du nach Beispielen suchst).

Hierbei brauchst du dann gar nicht prüfen, ob vor der Klammer ein Funktionsname steht, sondern es geht ja genau andersum: Er weiß, wenn auf - ich sag einfach mal - Variable Klammern folgen, ist es eine Funktion (wenn es überhaupt Variablen gibt, ansonsten muss es so oder so eine Funktion sein)... ansonsten sind Klammern immer zum Verschachteln (außer natürlich wenn man solche Schlüsselworte wie for, if, usw hat, welche direkt eine Klammer benötigen, aber das muss ebenfals ja nicht explizit geprüft werden...)
 
Top