Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Logik Problem beim MAthe Parser


Jerk - Mi 13.08.08 20:28
Titel: Logik Problem beim MAthe Parser
Ich habe einen MAthe Parser der als erstes aus einem String ein Array macht in dem alles ein eigenes Feld bekommt. So wird also aus
[11+22-33] -> [11][+][22][-][33].
Das klappt auch so weit ganz gut, also das Rechnen Funktioniert, auch mit Klammern. Was aber absoloute probleme bereitet sind die Doppelvorzeichen also z.b. 1--3 oder Vorzeichen vor Klammern.


Wie löse ich das Problem?


Ich dachte halt an eine weitere Prozedur die als erstes und nach jedem Rechenschritt genau auf diese Fälle hin überprüft und dann die Array felder zusammenfügt.
Jedoch bekomme ich es einfach nicht hin.


Edit Frage umformuliert.


GTA-Place - Mi 13.08.08 20:34

Vielleicht würde ja ein StringReplace mit -- -> + am Anfang reichen und aus -+ wird eben -.


EDIT: Gut, vor Klammern wird es schwieriger. Das hast du aber erst jetzt editiert :mrgreen:

EDIT2: Nicht so viel editieren, dann wirds einfacher für uns :lol:

Du kanns ja wirklich den Term durchgehen, bis ein - vor ( kommt. Dann gehst du von ( bis ) durch und drehst alle Vorzeichen um (und ein - vor die erste Zahl in der Klammer).


Jerk - Mi 13.08.08 20:37

Ja, sry hatte mich anfangs nen bissl doof ausgedrückt.

Mit den Klammern ist nicht direkt nen Problem da als erstes die Klammern aufgelöst werden, also der Ausdruck innerhalb der Klammer ausgerechnet und ersetzt. also aus 5+(7-3) wird erst 5+4


Das mit dem Stringreplace is ne Gute idee, das mach ich mal :p


letztes Edit.


Hidden - Mi 13.08.08 21:20

Hm.. Und '- - -'? Das fällt unter 'selbst schuld, wers drauf anlegt'? :mrgreen:

E: Ich würde ein minus gleich als '-1 * ' parsen, dann gibts keine Probleme.
E2: Aso, vergiss es :) Damit wird der Hauptzweck des '-' komplizierter, da musst du dann noch ein plus reinschmuggeln..


GTA-Place - Mi 13.08.08 21:41

--- = +- = - :gruebel: Dann geht StringReplace ja auch :think:


ssb-blume - Do 14.08.08 11:04

Hallo,
Die Klammern rekursiv für sich bearbeiten, das Ergebnis dann mit dem Vorzeichen versehen, fertig...
Die Operanden und Operatoren immer getrennt behandeln, Arrays sind da nicht ratsam, da begrenzt.
Also am Besten mit einem eigenen Stack arbeiten.
Auch mal nach "polnischer Notation" schauen!


BenBE - Do 14.08.08 13:11

Ich würde eher vorschlagen, du kaskadierst einfach das eine Vorzeichen in einer Extra Klammer.

Aus 0--(1+1) wird 0-(0-(1+1))


GTA-Place - Do 14.08.08 13:39

user profile iconBenBE hat folgendes geschrieben:
Aus 0--(1+1) wird 0-(0-(1+1))

Ich würd aber eher sagen, dass aus 0--(1+1) dann 0+(1+1) wird. Hat er doch weniger Arbeit.


BenBE - Do 14.08.08 13:54

user profile iconGTA-Place hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:
Aus 0--(1+1) wird 0-(0-(1+1))

Ich würd aber eher sagen, dass aus 0--(1+1) dann 0+(1+1) wird. Hat er doch weniger Arbeit.

Und was machst Du bei 23*-(6*7)???


GTA-Place - Do 14.08.08 14:02

Du hast ein -- Beispiel und kein *- Beispiel gebracht. Das ist ein anderer Fall :roll: Außerdem rechnert er ja zuerst 6*7 aus und dann steht da 23*-42. Damit kein Problem mehr.


BenBE - Do 14.08.08 14:13

Wollt mit diesem zweiten Beispiel auch nur zeigen, dass mein Vorgehen mit dem Klammern umschreiben universell auch für andere Operator-Verknüpfungen funktioniert.


Hidden - Do 14.08.08 14:32

user profile iconGTA-Place hat folgendes geschrieben:
--- = +- = - :gruebel: Dann geht StringReplace ja auch :think:

Aso, dann musstes aber rekursiv machen, bis du den originalstring bekommst.


Jerk - Fr 15.08.08 15:44

Ich wollte die Sachen alle in ein Array packen weil ich dachte das es später einfacher ist weitere Funktionen hinzuzufügen, z.B. Gleichungen Lösen.

Von Stacks habe ich einfach keine Ahnung.


Btw ich habe hier nen TI in der Hand. Die haben die Sache mit zwei Miustasten gelöst, eine nur für Vorzeichen und eine für Rechenoperationen.

http://einestages.spiegel.de/static/document/13288/ti_voyage_200.html?d=IMAGE%2CSPON_VIDEO%2CPDF&o=original_publicationdate-DESCENDING&s=3796&r=1&z=24&cp=158&c=1

Den haben wir in der Schule benutzt :p


delfiphan - Fr 15.08.08 16:41

Naja, das ist das Problem, wenn man einen Parser ad hoc von Hand programmiert. Normalerweise definiert man zuerst eine geeignete Grammatik und programmiert dann einen entsprechenden Parser dazu. Die explizite Auflösung von x-fachen Minuszeichen fällt dann weg.

Das mit dem Array ist eine gute Idee. So eine Prozedur heisst Tokenizer. Es ist aber nicht Aufgabe des Tokenizers doppelte Minus-Zeichen zu eliminieren sondern das sollte der Parser bei der Auflösung des Ausdrucks machen. Der Tokenizer sollte den Ausdruck nur in "Atome" aufteilen, mehr nicht.