Mathematischen ausdruck parsen und speichern
-
ich habe grad nen durchhänger und brauch mal eure hilfe, ich habe einen mathematischen ausdruck in einer Datei ala
Var1 == 0
oder
Var1 == Var2
Die variablen habe ich in einer map<string, int> abgelegt um sie zu solchen referenzzwecken einsetzen zu können.
die frage ist wie parse ich diesen ausdruck, und speichere ihn?
ich hab es bisher folgender maßen gelöst:
der text wird in blöcke unterteilt, teiler sind ";{}" find ich ein "{" geh ich davon aus das der block vor "{" eine struktur ähnlich
if((var1 == 0)&&(var2 == var3)){
hat,
steht am anfang KEIN "if" wird es !NOCH! als fehler erkannt.alles folgende wird wie folgt unterteilt
wenn nach dem if unter ausschluss von whitespaces ein "(" auftaucht, rufe ich
processexpression(block.substr(klammerpos, rest))
auf dort soll der ausdruck ausgewertet werden, es sei denn es taucht ein weiteres "(" auf dann wird wiederum
processexpression(newblock.substr(newpos, rest))
rekursiv aufgerufen, bis mind. 1 processexpression bis zu einem ")" abgeschlossen werden kann, dann lös ich die rekursion langsam auf.meine frage, wie könnt ich processexpression aufbauen um mathematische ausdrücke zu parsen (vorerst nur == != < > >= <= && ||) diese speichern und dann unter zuhilfename der map mit werten zu füllen, auszuwerten und fallentscheidungen treffen zu können. (füllen und fallunterscheidung liegen noch in der zukunft es geht mir erstmal um das speichern in einer auswertbaren form)
ein umständlicher weg wäre es über 2 maps mit referenznamen und operatoren zu arbeiten die sich über eine gruppennummer zuordnen liessen.
map <int, string> refmap<gruppe, refname>
map <int, enum> opmap<gruppe, operator(als enum)>aber ich finde das ein wenig verschwenderisch, evtl. hat wer ne bessere idee?
Edit: ich könnte auch die bereits verwendete baumstruktur verwenden, ich mach mir n paar gedanken und meld mich dann nochmal, ausser jemand hat ne wirklich bessere idee

-
Ich würde mir erstmal klar werden, was ein "Ausdruck" ist - und daraus eine kontextfreie Grammatik zusammenbauen. Daraus kannst du (z.B. mit yacc oder spirit) einen Parser erzeugen, der deine Eingaben auswertet).
-
und genau DAS wollt ich eigentlich nicht machen, da an der aufgabe leider etwas mehr als nur stupides parsen hängt, iss leider nur die halbe wahrheit
-
Deine Idee mit dem Baum ist gut.
Ich würde ihn Syntaxbaum nennen. Als Grundlage eine kontextfreie Grammatik und zum erstellen hHilfsmittel wie die genannten Parser
-
Ceos schrieb:
und genau DAS wollt ich eigentlich nicht machen, da an der aufgabe leider etwas mehr als nur stupides parsen hängt, iss leider nur die halbe wahrheit
Aber genau darum wirst du nicht herum kommen.
Wenn du erstmal dich etwas mit Parsern beschäftigt hast, wirst du einsehen, das es mit einer
Lib wie z.B. Spirit wesentlich einfacher ist. Gerade wenn du komplexere Regeln hast.
Zumal kann man damit auch ein komfortables Errorreporting realisieren.
Im Übrigen realisiert z.b. das Spirittutorial einen Taschenrechner, wäre ja schon mal eine gute Grundlage für dich.
-
ich verfolge jetzt die idee mit dem baum, ich habe miene knoten um 2 eigenschaften und 3 variablen erweitert, sollte so jetzt funktionieren.
desweiteren gruselt es mir im moment einfach mich mit den grammatiken auseinanderzusetzen, ich hab nämlich ein problem formeln zu verstehen (ich kann sie nicht lesen, mir wird der zusammenhang nicht klar ... wie soll ich sagen, ich sehe formeln wie ein analphabet lateinische buchstaben, ich sehe sie aber kann mir keinen reim drauf machen wenn sie mir nicht erklärt werden)
-
Lässt sich ja kombinieren, du kannst auch mit Spirit einen Parsebaum erstellen, und
dann nach dem Parsen durch die jeweiligen Elemente iterieren.
Hängt halt auch davon ab, was du letztendlich machen willst.
-
Du kannst auch eine Scriptsprache einbinden. Z.B. ist LUA ganz gut für sowas geeignet. Wenn es keine hochkomplexen mathematischen Formelns sein müssen, würde ich das Rad nicht neu erfinden.
-
na dann schau ich mir des yacc nomma an, iss das an irgendwelche lizensen gebunden ??? weil da iss schon wieder schluss
-
boost::spirit ist unter der Boost Lizenz.
Bei yacc weiss ich es nicht.
-
damit fällt spirit schonmal flach
any distributed code contains source code .... ich geh mal davona us, wo ichs einsetze muss ich auch alles offenlegen ....
-
Ceos schrieb:
damit fällt spirit schonmal flach
any distributed code contains source code .... ich geh mal davona us, wo ichs einsetze muss ich auch alles offenlegen ....
How is the Boost license different from the GNU General Public License (GPL)?
The Boost license permits the creation of derivative works for commercial or non-commercial use with no legal requirement to release your source code. Other differences include Boost not requiring reproduction of copyright messages for object code redistribution, and the fact that the Boost license is not "viral": if you distribute your own code along with some Boost code, the Boost license applies only to the Boost code (and modified versions thereof); you are free to license your own code under any terms you like. The GPL is also much longer, and thus may be harder to understand.
Die Boost lizenz ist recht frei, solange du boost nicht selber veränderst.
-
mh ok ... trotzdem wird mir im moment nicht ganz klar was genau bei dem spirit hinten rauskommt, wenn ich ihn verwende???
wenn ich meinen text parse, was kommt am ende dabei raus .... ich hab zwar ne vermutung aber will nicht vorgreifen
nur um eventuelle missverständnissen vozubeugen, ich möchte zur runtime eine datei mit spezifikationen parsen (c ähnlicher code), diese in einer baumstruktur speichern und dann auf datenströme anwenden, dabei können je nach aus dem datensrom gelesenem wert unterschiedliche interpretationen des datenstrom folgen.
-
Traditionell liefert Spirit eine Information, ob der eingegebene Satz zur Grammatik passt (bzw. die Position des ersten "Syntax"-Fehlers). Aber du kannst an die Regeln auch Anweisungen anhängen, mit denen du z.B. deinen Syntaxbaum zusammenbasteln kannst (ist eine Weile her, daß ich das gemacht habe - aber es funktioniert).
-
Im Forummagazin ist ein sehr aufschlussreicher Artikel zu Spirit! Kann ich nur empfehlen für den Einstieg!

-
Also bei spirit kann so ziemlich alles rauskommen

Bei deiner Anwendung ists wohl am sinnvollsten einen parse_tree zu nutzen, und dann jeweils
für die Regeln eine eigene ID zu vergeben (enum z.b.).
Schau einfach mal im Magazin, da gibt es einen Artikel zu spirit.
-
vielen dank, ich denke das ich damit arbeiten kann, leider bin ich hiermit schon zu weit fortgeschritten, mal davon abgesehen das ich das problem schon gelöst hab .
ich hab nur meine bedingungen umgedreht, jetzt parst er richtigandere frage, wo find ich den boost::spirit eigentlich, verwende BDS2006 und demnächst auch VS.NET?
-
Du musst dir boost herunterladen, oder auf spirit.sourceforge.net gibts auch eine standalone Version von Spirit.
-
hier z.Bsp.
http://spirit.sourceforge.net/
Beim BCB mußt du evtl. eine ältere Version verwenden (1.6.3) da die Neuesten zu Borlandcompilern nicht kompatibel waren. Das war zumindest beim BCB5 und 6 so. Spirit habe ich mit dem BDS2006 noch nicht probiert.
-
wenns nich BDS kompatibel iss fällts flach, aber das system iss ja mal voll das was ich gesucht habe, auch wenn mir noch nicht ganz klar geworden ist wie ich geparste texte speichern kann XD aber wie gesagt da mach ich mir später gedanken zu
-
Also auf dem GCC und MS Compilern läuft es, BCB müsste auch unterstützt werden in den 1.6 Zweig.