XML <-> Code Transformation

Algorithmen, Sprachunabhängige Diskussionen zu Konzepten, Programmiersprachen-Design
Antworten
MrTiger
Beiträge: 28
Registriert: Sa Aug 11, 2012 10:44 pm

XML <-> Code Transformation

Beitrag von MrTiger » Do Nov 08, 2012 10:09 am

Hallo

Ich habe hier XML Files, welche den Abstract Syntax Tree von Code darstellen. Die XML files habe ich erfolgreich in einen DOM-tree geparsed und kann diesen auch traversieren. Hier ist eine solche XML Datei:

http://img217.imageshack.us/img217/8365/xmlv.jpg

Diese XML Datei repräsentiert den folgenden Code (Eiffel):

Code: Alles auswählen

prune_first (n: INTEGER)
     do
          prune (n, l)
     end
Nun möchte ich zuerst das XML File wieder in Code zurückverwandeln. Das möchte ich machen, indem ich den Baum traversiere. Zudem gibt es noch eine Visitor Klasse (Visitor Pattern), bei der man Funktionen selber impelementieren kann, die man dann bei jedem Knoten aufrufen kann.

Mir ist nun aber nicht ganz klar, wie ich am besten vorgehen soll. Wie man im Beispiel sieht, sind alle Codestücke nur in Textelementen des XML Files vorhanden, ich könnte also alle Textelemente ausgeben, allerdings hätte ich da dann z.B. mit der Klammer () Probleme, da die Ausgabe dann prune()n,l anstatt von prune(n,l) wäre und zudem hätte ich dann alles auf einer Zeile und keine Einrückungen etc.

Wie würdet ihr da vorgehen? Die XML files werde ich übrigens später noch kürzen, so dass wirklich nur die wichtigen Nodes übrig bleiben.



Weiterhin würde ich auch gerne eine Transformation in die andere Richtung machen, also von Code (Feature = Methode oder Klasse) zu einem XML File. Man könnte da wohl einen parser generator verwenden.

Wie würdet ihr das aber ohne parser generator machen oder ist das zu aufwendig? Die erste Fragen oben (Umwandlung von XML nach Code) hat jetzt hier aber gerade Priorität. ;)

Edit by Xin: Code-Tags eingefügt

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: XML <-> Code Transformation

Beitrag von Xin » Do Nov 08, 2012 1:56 pm

MrTiger hat geschrieben:Mir ist nun aber nicht ganz klar, wie ich am besten vorgehen soll. Wie man im Beispiel sieht, sind alle Codestücke nur in Textelementen des XML Files vorhanden, ich könnte also alle Textelemente ausgeben, allerdings hätte ich da dann z.B. mit der Klammer () Probleme, da die Ausgabe dann prune()n,l anstatt von prune(n,l) wäre und zudem hätte ich dann alles auf einer Zeile und keine Einrückungen etc.
Wieso das? "(", dann kommt die list_of_expr, worin sich n und 1 befinden - also n,1 - dann erst kommt der String ")". Also ( n,1 ). Richtige Reihenfolge.
Einrückungen wirst Du Dir selbst bauen müssen, wozu sollte man die in den AST packen, der AST verkörpert seine (korrekte) Einrückung. Wie das ursprünglich aussah... wen interessiert das?

Wenn Du einen DOM hast, dürftest Du das so einlesen können und als Quelltext wegschreiben können.



Ich schreibe ja nun auch einen Compiler und ich gebe mir den DOM auch aus, um zu sehen, ob das was ich programmiert habe, einen Sinn ergibt. Aber das da... wozu sollte man das speichern oder sogar wieder einlesen!?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

MrTiger
Beiträge: 28
Registriert: Sa Aug 11, 2012 10:44 pm

Re: XML <-> Code Transformation

Beitrag von MrTiger » Fr Nov 09, 2012 2:20 pm

Wenn man alle Textelemente auf einer neuen Zeile ausgibt, kommt folgende Darstellung raus (Man beachte die enthaltenen Leerzeichen am Anfang gewisser Textelemente) :

Code: Alles auswählen

prune_first
        (
                n:
INTEGER
        )
                do
                        prune (
n
                        ,
l
                        )
        end 
Allerdings möchte ich eben folgendes erhalten:

Code: Alles auswählen

prune_first (n: INTEGER)
     do
          prune (n, l)
     end 
So sieht ein korrektes Feature (= Methode) in der Programmiersprache Eiffel aus. Mein Problem ist nun, wie ich vom DOM Tree eine solche Darstellung bekomme. Für den DOM Tree habe ich einen Parser. im DOM Tree sind alle Elemente des XML Files als Knoten vorhanden. Attribute und Textelemente gehören zu den jeweiligen Knoten (werden in Listen gehalten). Ich habe da v.a. folgende Probleme:

- Wie erkenne ich wann eine neue Zeile anfängt und wie kriege ich die Einrückungen korrekt hin. Deine Ausgabe oben ist ja von der Reihenfolge gleich wie meine Ausgabe, allerdings mit anderen Einrückungen und Zeilenumbrüchen.

- prune() ist das Textelement eines Knoten, wobei "prune(" das erste Textelement in der Liste ist und ")" das zweite. Würde ich nun einfach das Textelement des Knotens ausgeben hätte ich prune() etc. anstatt prune(n,l) etc.

Ich hoffe, dass du mir da vielleicht weiterhelfen kannst. :)

Der Hintergrund ist folgender: Ich habe erfolgreich einen Diff Algorithmus geschrieben, der auf den DOM Tree angewendet werden kann. Der Dom Tree soll nun in einem GUI als Code (wie oben) ausgegeben werden und die jeweiligen Differenzen markiert werden.

Das ergibt gleich noch eine kleine Frage: Ausgegeben werden ja nur Textelemente, allerdings hat es ja auch viele Elementknoten ohne Textelemente (z.B. <ast:feature_name>). Nun ist es ja z.B. möglich, dass nach Anwedung des diff Algorithmus ein Textelement z.B. als 'changed' markiert wird, das parent Element (welches keinen Text enthält) aber als 'added'. Soll dann nun der ausgegebene Text als 'changed' oder als 'added' markiert werden? Bzw. muss man da nur auf edit operationen bei Elementen mit Text schauen?


Ich möchte ja zudem noch unwichtige Knoten aus dem DOM Tree löschen (damit der diff alg schneller läuft). Da kann ich eigentlich alle internen Knoten löschen, welche kein Text enthalten und nur ein Kind haben, oder?

Wieso das? "(", dann kommt die list_of_expr, worin sich n und 1 befinden - also n,1 - dann erst kommt der String ")". Also ( n,1 ). Richtige Reihenfolge.
"prune()" ist ein einziger Text bzw. gehört zu einem einzigen Knoten, wobei "prune(" das erste Elemente und ")" das zweite Element in der Textliste des Knoten ist, allerdings ist es derselbe Knoten.
Einrückungen wirst Du Dir selbst bauen müssen, wozu sollte man die in den AST packen, der AST verkörpert seine (korrekte) Einrückung. Wie das ursprünglich aussah... wen interessiert das?
Die Textelemente enthalten bereits implizit Einrückungen, also z.B.

.....
<ast:body_as>
(
.....

Da ist das Textelement " (". Allerdings sind diese Einrückungen wohl nicht ganz korrekt, wenn man den Text einfach ausgibt.
Wenn Du einen DOM hast, dürftest Du das so einlesen können und als Quelltext wegschreiben können.
Da gibt es wieder die Probleme wie oben beschrieben. Ich habe erfolgreich das XML File in einen DOM Tree geparsed und kann den auch traversieren, wenn ich aber den Baum traversiere und einfach die Textelemente "wegschreibe" dann sieht der Code nicht gerade super aus.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: XML <-> Code Transformation

Beitrag von Xin » Sa Nov 10, 2012 12:30 am

Du schriebst, dass Du das DOM einlesen kannst. Entsprechend hast Du doch eine Baumdarstellung im Speicher?

Hier musst Du erstmal für die jeweiligen Nodes entsprechende Ausgaberoutinen schreiben, wobei die meisten einfach die der Kinder aufrufen, bzw. Text-Nodes eben ihren Text ausgeben. Jeder Ausgabe-Funktion übergibst Du mit, wie weit die Einrückung stattfinden soll. Für prune_first ist die Einrückung entsprechend 0.

Versuch Dich mal in der Richtung.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

MrTiger
Beiträge: 28
Registriert: Sa Aug 11, 2012 10:44 pm

Re: XML <-> Code Transformation

Beitrag von MrTiger » Sa Nov 10, 2012 10:48 am

Du schriebst, dass Du das DOM einlesen kannst. Entsprechend hast Du doch eine Baumdarstellung im Speicher?
Genau, ich habe eine Baumdarstellung im Speicher und kann diesen auch traversieren.
Hier musst Du erstmal für die jeweiligen Nodes entsprechende Ausgaberoutinen schreiben, wobei die meisten einfach die der Kinder aufrufen, bzw. Text-Nodes eben ihren Text ausgeben. Jeder Ausgabe-Funktion übergibst Du mit, wie weit die Einrückung stattfinden soll. Für prune_first ist die Einrückung entsprechend 0.
Ok, das heisst ich traversiere einfach den Baum (habe ja nur Elementknoten im Baum, also nur ein Typ von Knoten). Und wie soll ich die Grösse der Einrückung genau feststellen? Anhand des Elementnamens? Es gibt aber sehr viele verschiedene Elementnamen. Und wie genau kann man einen Zeilenumbruch feststellen?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: XML <-> Code Transformation

Beitrag von Xin » Sa Nov 10, 2012 11:03 am

MrTiger hat geschrieben:Ok, das heisst ich traversiere einfach den Baum (habe ja nur Elementknoten im Baum, also nur ein Typ von Knoten). Und wie soll ich die Grösse der Einrückung genau feststellen? Anhand des Elementnamens? Es gibt aber sehr viele verschiedene Elementnamen. Und wie genau kann man einen Zeilenumbruch feststellen?
Idealerweise weißt Du, welche Bedeutung der Knoten hat - die sind ja auch benannt.

Je nachdem, wie sich die Ausgabe verändern soll übergibst Du bei der Traversierung, wie weit eingerückt werden soll und wenn die gewünschte Einrückung != 0 ist fügst Du entsprechend Leerzeichen ein.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

MrTiger
Beiträge: 28
Registriert: Sa Aug 11, 2012 10:44 pm

Re: XML <-> Code Transformation

Beitrag von MrTiger » Sa Nov 10, 2012 5:11 pm

Idealerweise weißt Du, welche Bedeutung der Knoten hat - die sind ja auch benannt.
Das stimmt, allerdings gibt es extrem viele verschiedene Knoten. Wenn ich da bei jedem eine Fallunterscheidung machen muss, habe ich ja dann sehr viele if-elseif Abfragen.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: XML <-> Code Transformation

Beitrag von Xin » Sa Nov 10, 2012 7:37 pm

MrTiger hat geschrieben:
Idealerweise weißt Du, welche Bedeutung der Knoten hat - die sind ja auch benannt.
Das stimmt, allerdings gibt es extrem viele verschiedene Knoten. Wenn ich da bei jedem eine Fallunterscheidung machen muss, habe ich ja dann sehr viele if-elseif Abfragen.
Richtig - oder Du programmierst benutzt C++ und hast entsprechend viele Datentypen. In irgendeiner Weise musst Du die Knoten unterscheiden. Du benutzt aber Eiffel, richtig? Da weiß ich leider nicht, wie man virtual formuliert.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

MrTiger
Beiträge: 28
Registriert: Sa Aug 11, 2012 10:44 pm

Re: XML <-> Code Transformation

Beitrag von MrTiger » So Nov 11, 2012 8:54 pm

Genau, ich benutze Eiffel. Werde mal für alles eine Fallunterscheidung machen und bei Problemen mich wieder melden. ;)

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: XML <-> Code Transformation

Beitrag von Xin » So Nov 11, 2012 10:48 pm

MrTiger hat geschrieben:Genau, ich benutze Eiffel. Werde mal für alles eine Fallunterscheidung machen und bei Problemen mich wieder melden. ;)
Auch eine if-Abfrage oder ein switch - oder was auch immer ist Objektorientierte Programmierung.
Nur elegant ist das nicht, weil es unschön zu warten ist, wenn neue Typen hinzukommen. Ein Design Pattern (!), um elegant objektorientiert zu programmieren, sind virtuelle Funktionen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten