Tag Archives: emftext

DSL Tutorial Teil 2


Flattr this

Um was geht es?

Dies ist der letzte Teil meines 2 teiligen DSL Tutorials. Ziel des Tutorials ist das Erstellen einer DSL zur Beschreibung von Vektorgrafiken und der Bereistellung eines Generators um daraus svg Dateien zu erzeugen. Die DSL wird in [DSL-1] erstellt. Dieser 2. Teil befasst sich aufbauend auf Teil 1 mit der Erstellung eines Generators.

Einrichten der Arbeitsumgebung

Vor Beginn dieses Teils müssen Sie alles unter [DSL-1] beschriebene durcharbeiten. Ich setze die funktionierende DSL mit der im Teil 1 vorgenommenen Definition voraus.

Los gehts

Die folgend dargestellten Projekte sollten im Eclipse Arbeitsbereich zu sehen sein.

015 ProjektUebersicht

Als Erstes fügen wir dem DSL Projekt die Acceleo Nature hinzu und aktualisieren die Ansicht.

016 AddNature

Nun weisst unser DSL Projekt ein Overlay Icon von Acceleo auf und wir können über das Kontextmenü das Generatorprojekt erzeugen.

017 GeneratorProjektErzeugen

Es erscheint ein geführter Dialog per Wizard. Hier passen wir den Projektnamen so an, dass er statt auf ui auf generator endet. Außerdem nehmen wir Änderungen an den Settings (letzte Tab) vor. Die nachfolgenden Bilder verdeutlichen dies.

018 Dialog 019 Einstellungen

Wichtig der Filter der Dateinamen! Er entscheidet darüber für welche Dateien der Generator zur Verfügung stehen wird. Außerdem habe ich mich für einen eigenen Target Pfad entschieden (target/generated-sources), damit nicht ausversehen Projektdateien überschrieben werden.

Zum Abschluss bitte mit Finish bestätigen.

Im neuen Projekt setzen wir als Erstes den Java Output Build Pfad auf target/classes, da ohne diesen Schritte manchmal keine Templates angelegt werden können. Nun müssen wir auch dem neuen Generator Projekt zunächst manuell die Acceleo Nature zuweisen (leider nimmt Acceleo diese Zuweisung nicht automatisch vor). Nun stehen auch hier weitere Kontextmenüeinträge zur Verfügung. Somit können wir nun im Package org.emftext.language.svgd.generator ein Main Template anlegen. Dazu bitte auf dem Package Ordner über das Kontextmenü den Neu Dialog aufrufen und Acceleo Main Module File auswählen. Dann einfach Next und Finish – der Rest ist bereits korrekt vorbelegt.

020 MainTemplateAnlegen

Jetzt sind 2 neue Dateien im Package entstanden: eine Main.java (interessiert uns nicht weiter) und eine main.mtl. Letztere sollte auch geöffnet wurden sein und wird von uns nun mit folgendem Inhalt gefüllt:

[comment encoding = UTF-8 /][module main(‚http://www.emftext.org/language/svgd‘)/][template public main(model : SVGModel)][comment @main /][for (element : Form | model.elements)] [file (element.name.concat(‚.java‘), false, ‚UTF-8‘)] Testfile [/file][/for][/template]

Im common Package in der Klasse GenerateAll ersetzen wir die doGenerateMethode mit folgendem Code:

Code der doGenerate Methode in GenerateAll.java

Wenn wir unsere DSL jetzt wieder als Eclipse Anwendung starten, können wir dort zu unserem Beispiel bereits Code generieren. Achtung die verschiedenen Formen sollten auch verschiedene Namen bekommen damit nicht alle die gleiche Java Klasse generieren 🙂

021 BeispielInstanz

So sieht ein erstes Beispiel aus. Damit ist der Generator prinzipiell arbeitsfähig und wir können uns dem Implementieren der Fachlichkeit zuwenden.

Den vollständigen Umfang der Acceleo Sprache zu erklären möchte ich hier gar nicht erst versuchen (dazu gibt es eine sehr schöne Hilfe in Eclipse selber). Aber damit das Tutorial am Ende auch eine SVG Datei generiert, habe ich folgende Änderung an der main.mtl durchgeführt. Bitte den Inhalt der Datei komplett ersetzen mit dieser main.mtl (odt) oder dieser main.mtl (doc) .

Leider lies sich der Code hier im Blog nur schlecht formatieren. Auf jeden Fall muss die <?xml Zeile ganz links anfangen da sonst der Browser das Bild nicht interpretieren kann. Und so kann ein funktionierendes Beispiel in Eclipse aussehen.

022 FinalesBeispiel

Ich hoffe das Tutorial konnte einen Einblick in die Praxis des Generatorbaus geben. Ziel war den Leser schrittweise zu einem funktionierenden Beispiel zu verhelfen. Der Aufwand zur Erstellung des Tutorials hat dann doch mehr als ein Wochenende in Anspruch genommen. Daher habe ich auch auf die Erklärung vieler Details verzichtet.

Falls jemand weitere Fragen dazu hat oder Details wissen möchte, bitte kommentieren dann liefere ich diese noch nach.

Vielen Dank fürs Lesen und viel Spass beim Generieren 🙂

[DSL-1]

DSL Tutorial Teil 1
Advertisements

DSL Tutorial – Teil 1


Flattr this

Motivation

Nachdem ich letztens in [EMFText einsetzen] einen Blick auf EMFText geworfen hatte möchte ich nun die Erfahrungen welche ich inzwischen mit dem Framework sammeln durfte in einem kleinen Tutorial zusammenfassen. Dieses werde ich an einem kleinen Beispiel durchführen, in welchem eine primitive DSL für die Erstellung von svg Grafiken erstellt werden soll. Wer tatsächlich Bedarf an einer solchen DSL hat, kann die DSL dann selbständig erweitern. Es würde mich freuen, wenn solche Projekte unter dem Artikel kurz kommentiert werden – es genügt ein Link auf das Projekt 🙂

Vor dem Einstieg in mein Tutorial empfehle ich die Abarbeitung des Original ScreenCast hier: http://www.emftext.org/index.php/EMFText_Getting_Started_Screencast
So sind die wesentlichen Grundbegriffe schon bekannt und ich kann auf spezielle Punkte eingehen.

Das Tutorial wird in 2 Teilen realisiert:

  1. Teil: Erstellen und Anpassen einer DSL in Iterationen auf Basis von Eclipse und den EMFText Plugins

  2. Teil: Erstellen eines Generators für die DSL auf Basis von Eclipse und den Acceleo Plugins

Aufsetzen der Arbeitsumgebung

 

1) Download Eclipse Classic Version von:
http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.7.1-201109091335/eclipse-SDK-3.7.1-win32.zip

In der eclipse.ini setzen wir folgende Werte:

-vmargs
-XX:MaxPermSize=256m
-Xms128m
-Xmx512m

2) Start der Eclipse und Einrichten folgender Update Sites:

  1. EMFText Updates Site – http://www.emftext.org/update_trunk
  2. Eclipse Indigo Updates – http://download.eclipse.org/releases/indigo (sollte bereits eingerichtet sein)

3) Installieren der aktuellen Versionen von:

  • EMFText über den 1. URL und dann Auswahl Paket EMFText.
  • Acceleo und EcoreTools über den 2. URL und dann Auswahl Modeling/Acceleo SDK und Modeling/Ecore Tools

Beispielprojekt

 

Als Beispiel werde ich in diesem Artikel zeigen wie wir ein DSL Projekt aufsetzen, was alles benötigt wird und wie wir die DSL nach und nach erweitern können. Die Realisierung eines XMI Builders und die Erstellung eines Generator Projektes mittels Acceleo werden dann in späteren Artikeln beschrieben.

Los geht’s

1) DSL Projekt anlegen

  1. Neu/Projekt/EMFText/EMFText Projekt
  2. Felder im Dialog befüllen

001 NewEMFTextProject

 

Weiter mit Finish

2) Ecore Diagramm aus dem Model erstellen

Dazu suchen wir im DSL Projekt den Ordner metamodel, selektieren dort das Ecore Model svgd.ecore und dann über das Kontextmenü den Punkt Initialisiere Ecore Diagramm File auswählen.

003 EcoreDiagram

Den anschließenden Dialog mit Finish bestätigen. Als Ergebnis finden wir eine neue Datei svgd.ecorediag . Diese wird auch gleich geöffnet und das aktuelle Ecore Model als Grafik angezeigt. Der Wizard war zu uns nett und hat schon ein paar Modelelemente für ein ER Model angelegt. Diese nutzen wir gleich weiter, passen sie aber unseren Bedürfnissen an:

  1. Type benennen wir in Form um (selektieren und in der Properties View den Namen ändern).
  2. DataType wird in Rechteck umbenannt (nach jedem Schritt am besten speichern – Obacht! Das Fenster muss als gespeichert markiert werden – also kein * mehr)
  3. EntityModel wird zu SVGModel und
  4. Entity wird zu Kreis
  5. Die Kante von Kreis zu Feature wird entfernt
  6. Das Attribut abstract in Kreis wird entfernt
  7. Die Kante von Feature zu Form wird entfernt
  8. Feature wird in Linie umbenannt
  9. FeatureKind wird in Linienart umbenannt
  10. attribute in Linienart wird zu durchgezogen, reference zu gestrichelt und containment zu gepunktet umbenannt (Bitte stets Name = Literal setzen)
  11. Alles Speichern und das ecore Model svgd.ecore öffnen und prüfen ob die Änderungen auch hier korrekt durchgeführt wurden.

An dieser Stelle sehen wir, dass es nicht ganz geklappt hat. Kreis enthält noch eine Verbindung features zu Linie – die muss natürlich weg. Ein wichtiger Schritt beim iterativen Vorgehen immer Diagramm gegen Ecore Model vergleichen! Letztlich ist das Ecore Model der Master für alle Modellierungswerkzeuge.

 

Also jetzt erstmal im Ecore Model aufräumen:

  1. features unter Kreis entfernen
  2. type unter Linie entfernen
  3. kind unter Linie umbenennen in stil
  4. Super von Linie (NamedElement) wechseln und dafür Form auswählen
  5. types unter SVGModel umbenennen in elements

004 FertigesEcoreModell

 

Nun alles Speichern und ins Ecore Diagramm zurück wechseln. Nach dem Wechseln in das Ecore Diagramm, stellen wir fest, dass einige Änderungen nicht korrekt dargestellt werden. Bei umfangreichen Änderungen im Ecore Model passiert dies leider immer wieder. An dieser Stelle empfielt es sich das Diagram zu löschen und wie oben bereits durchgeführt erneut aus dem Ecore Model zu erzeugen. Einen effizienteren Weg habe ich hierfür leider nicht gefunden. So schaut das neu erstellte Diagramm aus.

005 FertigesEcoreDiagram

Da die Anpassungen auch für das GeneratorModell und die HUTN Syntax zu umfangreich waren, werden wir auch diese beiden Dateien neu erzeugen (Später werden wir diese Schritte teilweise automatisch ausführen lassen).

Zunächst aktualisieren wir das Generator Model. Also Rechtsklick auf svgd.genmodel und Reload auswählen. Im Wizard dann Ecore Model auswählen. Auf der nächsten Tab das konkrete Modell auswählen (Der korrekte Pfad sollte bereits hinterlegt sein). Kurzer Klick auf Load und dann geht es auf Weiter . Zum Abschluss Finish und es ist geschafft.

006 ReloadGenModel

Nun löschen wir das Syntax File svgd.cs und erzeugen uns ein Neues. Also nach dem Löschen bitte einen Rechtsklick auf svgd.genmodel und den Eintrag generateSyntax/HUTN-Syntax ausgewählt. Erledigt.

007 GeneriereHutnSyntax

Jetzt schauen wir uns die Syntax an. Die entstandene Datei sollte wie folgt aussehen.

008 FertigeHUTNSyntax

Die Syntaxdefinition ist recht rudimentär und wir müssen sie zunächst ein wenig an das Metamodell anpassen bzw. ein paar erleichternde Optionen einfügen.

Fangen wir mit den Optionen an welche uns die iterative Arbeit künftig erleichtern werden – dazu folgenden Abschnitt vor TOKENS einfügen.

OPTIONS{
reloadGeneratorModel=“true“;
generateCodeFromGeneratorModel=“true“; //wichtig um Fehler im Generat zu vermeiden
disableLaunchSupport=“false“;
usePredefinedTokens=“true“;
}

Anschließend generieren wir die TextResourcen.

 

009 GeneriereTextResourcen

Nun müssen wir noch die alten, vom NewWizard erzeugten Klassen entfernen:

  • DataTypeImpl

  • EntityImpl

  • EntityModelImpl

  • FeatureImpl

  • TypeImpl

010 KlassenEntfernen

 

Alles rot markierten Klassen sind zu entfernen – das sind Rückstände aus früheren Iterationen oder vom Neu Anlegen Dialog.

Starten wir nun das Projekt über Run As Eclipse Application können wir in der sich öffnenden Runtime-Eclipse über den Neu Wizard ein Projekt vom Typ svgd anlegen. Das gleich mit angelegte File new_file.svgd unterstützt bereits unsere HUTN Syntax mit einem leistungsfähigen Editor inklusive automatischer Syntaxvorschläge und farblicher Syntaxauszeichnung.

011 SimpleModelInstanz

Allerdings ist die Syntax nicht wirklich tauglich eine Vectorgrafik zu beschreiben. Damit sich dies ändert, werden wir nachfolgend die Syntax und falls notwendig auch das Ecore Modell nach und nach erweitern und anpassen.

Bis hierher eine kleine Zusammenfassung als Video

SVG – die fachliche Domain

Wenn man eine DSL erstellt, sollte man sich auch in der fachlichen Domain auskennen. Einen guter Einstieg für den Bau einer DSL findet sich auf Wikipedia unter [SVG]. Für uns ist wichtig welche Grundelemente der Sprache es gibt und welche Attribute diese besitzen müssen. Da SVG nur wenige Elemente definiert werden diese im Folgenden kurz aufgezählt:

  • Pfad …
  • Kreis definiert über Mittelpunkt und Radius
  • Ellipse definiert über Mittelpunkt und Radius1 sowie Radius2
  • Rechteck definiert über Position der linken oberen Ecke sowie Breite und Höhe
  • Linie definiert über die Positionen der beiden Endpunkte
  • Polygonzug definiert über eine Liste von Positionen der Punkte
  • Polygon definiert über eine Liste von Positionen der Punkte
  • Text …
  • Image …

Zu jedem Element lassen sich noch Style und Transformationsangaben hinterlegen. Für unsere DSL sollen die 3 Grundelemente (oben in fett) ohne Style und Transformationen genügen.

 

DSL erweitern

Die Grundelement Kreis, Rechteck und Linie sind in unserer DSL bereits definiert. Was fehlt sind Attribute der Grundformen. Also gleich ins Ecore Diagram und die benötigten Attribute wie folgt definiert.

  • Kreis um die Attribute x und y sowie radius ergänzt. Alle vom Datentyp EFloat.
  • Rechteck um die Attribute x und y sowie hoehe und breite ergänzt. Alle vom Datentyp EFloat.
  • Linie um die Attribute x1 und y1 sowie x2 und y2 ergänzt und auch diese alle vom Datentyp EFloat .

Das finale Ecore Diagramm sollte wie folgt aussehen.

 

012 FinalesEcoreDiagram

Da diesmal nur Objekte hinzugefügt wurden, sollte kein Unterschied zum Ecore Modell entstanden sein. Vorsichtshalber aber ruhig vergleichen ob das Ecore Modell dem Ecore Diagramm entspricht. Gegebenenfalls natürlich anpassen.

Auf jeden Fall sollten wir jetzt eine Syntax definieren in welcher eine sinnvolle Beschreibung der Grafik möglich ist. Dazu öffnen wir die Syntaxdefinition sgvd.cs und führen folgende Anpassungen durch.

  • Zunächst entfernen wir die extra definierten Token. Diese benötigen wir nicht! Wir beschränken uns auf die von EMFText vordefinierten Standardtoken (siehe Option: usePredefinedTokens)
  • Nun passen wir die Syntax-Regel für das Rechteck an:
    Rechteck ::= „Rechteck“ „{“ „name=“ name[‚“‚,'“‚] „x=“ x[‚“‚,'“‚] „y=“ y[‚“‚,'“‚] „höhe=“ hoehe[‚“‚,'“‚] „breite=“ breite[‚“‚,'“‚] „}“;
  • Weiterhin ist die Syntax-Regel für Kreis wie folgt anzupassen:
    Kreis ::= „Kreis“ „{“ „name=“ name[‚“‚,'“‚] „x=“ x[‚“‚,'“‚] „y=“ y[‚“‚,'“‚] „radius=“ radius[‚“‚,'“‚] „}“;
  • Die Zeichenkette „elements“ im SVG Modell ist auch überflüssig also die Regel für SVGModel angepasst:
    SVGModel ::= „SVGModel“ „{“ (elements)* „}“;
  • Schlussendlich muss auch Linie noch angepasst werden:
    Linie ::= „Linie“ „{“ „name=“ name[‚“‚,'“‚] „x1=“ x1[‚“‚,'“‚] „y1=“ y1[‚“‚,'“‚] „x2=“ x2[‚“‚,'“‚] „y2=“ y2[‚“‚,'“‚] „stil“ „:“ stil[durchgezogen:“durchgezogen“, gestrichelt:“gestrichelt“, gepunktet:“gepunktet“] „}“;

Zum Schluss nehmen wir noch den angebotenen Quickfix in Anspruch und lassen den ungenutzten Resolver entfernen. Schon steht die neue Syntax. Die finale Syntaxdefinition sollte wie folgt aussehen.

 

013 FinaleSyntax

Über einen Start des DSL Projektes als Eclipse Application lässt sich nun bereits eine SVG Grafikbeschreibung wie die Folgende formulieren.

014 FinaleSyntaxInstanz

Anbei noch die letzten Schritte als Video zusammengefasst.

Damit ist der erste Teil des Tutorials beendet. Ich hoffe es hat Spaß gemacht zu sehen wie einfach eine eigene DSL geschrieben werden kann. Nun wünsche ich viel Freude beim Ausprobieren und Schreiben Eurer eigenen DSLs. Falls Ihr zu dem Thema Open Source Projekte im Internet startet würde ich mich über einen Kommentar mit Link zum Projekt freuen.

Im nächsten Teil des Tutorials [DSL-2] werden wir mittels Acceleo für die hier definierte DSL einen Generator bauen. Mit dem Generator sind wir dann in der Lage aus einer Grafikbeschreibung in unserer DSL per Rechtsklick eine svg Datei zu erzeugen. Richtig Sinn macht dieses Vorgehen natürlich erst, wenn die DSL leistungsfähiger als ein herkömmlicher SVG Editor ist. Eine solche Erweiterung ist aber zu groß für dieses Tutorial. Von daher probiert doch einfach selbst aus die DSL um Konstrukte zu erweitern, mit denen Grafikobjekte zu neuen Objekten gruppiert werden können. Wird eine entsprechende große Bibliothek aufgebaut, ist es dann auf diese Weise recht einfach komplexe Grafiken in SVG zu erstellen.

Weiter geht es mit [DSL-2].

Quellennachweise

 

[DSL-2]
https://funthomas424242.wordpress.com/2011/10/16/dsl-tutorial-teil-2/
[EMFText einsetzen]
Entwickler Blog auf www.funthomas424242.wordpress.com
[SVG]
href=“http://de.wikipedia.org/wiki/Scalable_Vector_Graphics&#8220;
[EMFText Screencast]
http://www.emftext.org/index.php/EMFText_Getting_Started_Screencast

EMFText einsetzen


Flattr this

Motivation

Auf der Suche nach geeigneten Technologien zur Softwareproduktion am Fließband bin ich über Xtext nun auf EMFTText gestossen. EMFTText scheint eine weitere Integration von Xtext in die Eclipse Umgebung zu sein. Grund genug einmal damit zu spielen und ein Gefühl für das neue Werkzeug zu entwickeln.

Erster Eindruck

Nachdem ich meinen uralt Eclipsestand (Helios mit EMF 2.5.0) manuell recht umständlich aktualisiert hatte, bin ich nun im Besitz einer Eclipse Indigo mit EMFTText 1.4.0. Das hätte ich auch einfacher haben können wenn ich EMFTText gekannt hätte und einfach nach Anleitung vorgegangen wäre.

 

Nachdem ich das Tutorial durchgearbeitet hatte, war ich beeindruckt und würde die für mich wichtigen Features wie folgt beschreiben:


  • Kernpunkt der Modellierung stellt ein ecore Modell dar
  • Alles was zur Modellierung benötigt wird stellen zusätzliche Plugins bereit (Ecore Tools). So kann auf der Grundlage von Diagrammen und DSLs gearbeitet werden ohne direkt im ecore Modell hantieren zu müssen.
  • Für jeden Schritt in der Modellierung gibt es passende Generatoren und Werkzeuge.
  • Es gibt neue EMFTText Projektarten. Wie das Tutorial beweist, kommt man aber auch zu Fuß über normale Java Projekte ans Ziel (auch sehr einfach).
  • Die Beschreibung der DSLs erfolgt bei EMFTText wieder deutlich mehr an den Grundlagen der Compilertechnik orientiert als bei Xtext. Hier sieht man wieder Tokendefinitionen und Grammatikregeln. Wer mit lex und yacc angefangen hat und sich über LIGA, LIDO, GAG und Eli freuen konnte, der fühlt sich sofort wieder heimisch.
  • Auch dieses Eclipse Tool hat sich wieder nicht an der Standard Maven Directory Struktur orientiert. Packages werden wieder unter ${base}/src und ${base}/metamodell angelegt obgleich ${base}/src/main/java genauso super wäre.
  • Eine Anpassung an Maven ist aber mit der aktuellsten Version von EMFTText möglich. Dazu kann man in der Sprachdefinitionsdatei (*.cs) beispielsweise folgende Optionen setzen:

    OPTIONS{
    srcFolder = "src/main/java";
    srcGenFolder = "target/generated-sources/java";
    uiSrcFolder = "src/main/java";
    uiSrcGenFolder = "target/generated-sources/java";
    }

    Die aktuellste Version von EMFTText  bekommt man durch Einbinden der folgenden Update Site in Eclipse: http://www.emftext.org/update_trunk
  • Eine generell gute Idee scheint es zu sein in folgender Reihenfolge (wie im Tutorial) vorzugehen:

    1. Erstellen eines ecore Modells über den Ecore Diagram Editor
    2. Erstellen eines Ecore GeneratorModels aus dem Ecore Modell
    3. Generierung einer HUTN Syntax aus dem GeneratorModel
    4. Anpassen der HUTN Syntax um komplett konform zum Ecore Modell zu sein
    5. Nutzung des entstandenen DSL Editor Plugins um Texte in der neuen DSL zu schreiben.

Details am Beispiel zur Arbeit mit EMFText

Für das Spielen und zum Sammeln von Erfahrungen habe ich das ERM-DSL Projekt auf sourceforge.net verwendet. Die Quellen sind für jeden zugänglich und können unter svn://svn.code.sf.net/p/ddd-tools/erm-dsl/svn/trunk mittels subversion ausgescheckt werden.

Auswirkung der Namensvergabe

Für mich ist es in speziellen Fällen nicht leicht nach zu vollziehen wie sich die im ecore Modell verwendeten Bezeichner genau auf die Generierung auswirken. Anbei die Auflistung der beim Spielen beobachteten Auswirkungen:

 

Im verlinkten Kommentar gibt es einige Details zu diesem Thema: https://funthomas424242.wordpress.com/2011/08/16/emftext-einsetzen/#comment-28. Persönlich bevorzuge ich das Setzen der Namen über die Sprachdefinitionsdatei (*.cs). Dafür eignen sich folgende Optionen:


  • basePackage
  • uiBasePackage
  • resourcePluginID
  • resourceUIPluginID

Iteratives Arbeiten

Ich habe mit Hilfe des EMF Diagram Editors zunächst eine sehr simple Sprache mit wenigen Sprachelementen entworfen. Anschließend auf der Basis des ecore Modells ein EMF Generator Model erstellt und daraus ein HUTN Syntax File erzeugen lassen. Die Syntax habe ich noch ein bischen auf das ecore Modell abgestimmt und dann daraus die Projekte generieren lassen. Scheinbar wird der selbe Generator gestartet wenn ich auf das Generator Modell gehe und per Rechtsklick „Alles Generieren“ wähle. Anschließend die Runtime Eclipse gestartet und das DSL Editor Plugin getestet -> funktioniert 🙂

 

Jetzt soll die Sprache natürlich erweitert werden. Also wieder ins EMF Diagram, dort ein paar Änderungen durchgeführt und abgespeichert. Dann Rechtsklick auf das EMF Generator Modell „Reload“ von dem bestehenden ecore Modell durchführen. Schon ist das aktualisiert. Jetzt ins Syntax File und die Regeln für die neuen Konstrukte eingefügt – fertig. Wieder alles generieren lassen und? Einiges ist rot. Löschen und neu generieren hilft – komisch. Kurzer Test in der Runtime Eclipse – Editor funzt.

Ergo, nach Syntaxänderungen wird nicht alles was vorher erzeugt wurde wieder gelöscht. Macht Sinn, da manche Dinge nur einmal generiert werden sollen. Dennoch händisch weg löschen ist störend. Hier such ich noch nach einem Automatismus. Eine anderswo gesehene Lösung bestand darin, die Folder Struktur anzupassen. Also in 3 Arten zu unterteilen:


  • src Folder – alles handgeschrieben, nichts generiertes
  • src-gen Folder – alles wird vor der Generierung gelöscht und dann neu generiert
  • src-gen-one Folder – alles wird generiert aber nichts überschrieben und nichts gelöscht (also jedes Artefakt wird beim ersten Mal generiert und dann nie wieder)

Ob das Sinn ergibt wird sich zeigen. Hier bin ich noch am Ausprobieren. Was auf jeden Fall Sinn macht, wenn die DSL noch stark unter Entwicklung ist, sind folgende Optionen in der Sprachdefinitionsdatei (*.cs):

OPTIONS{
reloadGeneratorModel="true";
generateCodeFromGeneratorModel="true";
}

Damit wird das GeneratorModel vor dem Erzeugen der Text Ressourcen neu aus dem ecore Modell erstellt und es wird aus dem GeneratorModel heraus generiert.

Kodegenerierung

Die Kodegenerierung funktioniert über Builder. Bei der Generierung der DSL Ressourcen werden bereits Stubs für diese Builder mit erzeugt. Das Überschreiben dieser Stubs kann mittels folgender Optionen in der Sprachdefnitionsdatei (*.cs) abgeschaltet werden:

OPTIONSÂ {
overrideBuilder = "false";
}

Dadurch kann man die Logik der Builder implementieren ohne das ein neuer Generatorlauf diese Änderungen überschreibt.

 

Persönlich finde ich es allerdings eleganter ein separates Plugin Projekt für den Generator zu erstellen und dort von diesen Buildern abzuleiten. So kann sichergestellt werden, dass die Implementierung der Stubs immer zur DSL passt. Außerdem lässt sich so auch die Generator Entwicklung von der DSL Entwicklung trennen. Dies ist nützlich wenn die Arbeit auf mehrere Teams verteilt werden soll. Dann können die neuen Sprachfeatures in einem Sprint vom Team A implementiert werden und der Generator wird im nachfolgenden Sprint vom Team B überarbeitet.

Sehr erfreulich finde ich in diesem Zusammenhang die Tatsache, dass ein solches Generator Projekt im Handumdrehen aufgesetzt werden kann, da es sich um eine Ankopplung an den Standard Extension Point org.eclipse.core.resources.builders handelt. Die Erstellung eines solchen Projektes ist per Wizard über Eclipse Bordmittel möglich. Dabei werden der Builder, eine Nature, eine MenuAction und ein Marker erstellt. Benötigt wird eigentlich nur die Nature und der Builder. Die MenuAction für ToggleNature kann einfach in der Checkbox des Wizards abgewählt werden. Allerdings ist es ohne diesen Menüeintrag nicht mehr so einfach den Builder an ein bestimmtes Projekt zu binden. Letzlich muss man den Marker Extension Point einfach in der Plugin.xml löschen. Jetzt noch die zugehörigen Klassen entfernen und schon steht das Grundgerüst für den Builder. Anschließend noch die eigene Builder Klasse von [DSL]BuilderAdapter.java ableiten und schon kann der Generatorbau beginnen.

Um nicht alles manuell implementieren zu müssen, macht es Sinn den Generator selbst als Xtend oder Acceleo Projekt zu implementieren. Hier sind 2 Aspekte zu beachten:


  1. Erstellung des Generatorprojektes. Dies kann auf Grundlage des ecore Model (Metamodell der neuen DSL) statisch sowohl über Xtend als auch Acceleo erfolgen. Vermutlich lohnt sich hier die Generierung, da das Grundgerüst für ein Generatorprojekt vermutlich sehr stabil gehalten werden kann und nur die Templates von DSL zu DSL verändert werden müssen. Diese Templates könnte man in einem separaten Ordner ablegen der nicht generiert wird.
  2. Generierung der Zielartefakte aus einer Modellinstanz der DSL. Hier reden wir über die Laufzeitumgebung unseres DSL Editors. Also einen Zeitpunkt in dem wir mit dem Editor Texte in der von uns definierten Sprache erstellen können, mit Syntaxauszeichnung und Eingabeassistenten – das konkrete Model aber nur im Speicher vorliegt. Die einzige zu dieser Zeit existierende externe Repräsentation des konkreten Modells ist die Textdatei verfasst in unserer DSL.
    Ein Generator muss also an die Extension Points des DSL Editors andocken um das konkrete Modell auszulesen oder die ganze DSL Datei selbst parsen und transformieren. Hierfür dient uns der Builder welcher vom EMFText Framework generiert wurde. Zusätzlich müssen wir hier entweder mit Xtend oder mit Acceleo einen konkreten Generatorprozess implementieren. Wichtig ist, es geht stets um InMemory Modelle aus denen generiert werden soll. Letzteres ist ein Punkt der nicht immer sofort ins Auge fällt, da die Beispiele der Frameworks stets auf eine vorhandene ecore oder UML Datei basieren. Doch zur Laufzeit ist eben keine ecore Datei mehr vorhanden, da diese ja nur das Metamodell unserer DSL enthält und sämtliche Informationen in Plugin Kode überführt wurden.
    Nachdem ich es mal mit Acceleo probiert habe, bin ich der Meinung das es nicht so geeignet ist. Acceleo benötigt ein MetaModel (ecore geht) und ein Model in xmi (unsere DSL in XMI). Letzteres geht natürlich, dürfte aber aufwendig sein. Also Acceleo doch nur für Punkt 1 einfach einsetzbar.

Bewertung

Insgesamt macht das Framework einen sehr guten und durchdachten Eindruck. Die Lernkurve erschien mir recht steil. Das liegt nach meinem Empfinden aber weniger am Framework als mehr an der DSL Technologie allgemein. Wenn man die DSL Technologie allerdings mit den klassischen Methoden der Compilertechnik vergleicht, dann stellen Frameworks wie EMFText oder Xtext praktisch ein Paradies an Werkzeugen bereit.

 

Hinsichtlich einer Werkzeugstraße für industrielle Softwareentwicklung vom Fließband stellt EMFText eindeutig einen Grundbaustein dar. Vor allem auch weil durchweg bereits bestehende Quasi-Standards genutzt und nicht neu erschaffen werden.

Weiterführende Links

Ähnliche Technologien

Ganz nett fand ich auch folgenden Artikel Elinson, S.; Hanns, M. & Kronseder, S. (2010), ‚Für die Sprachenvielfalt – Xtext 1.0: Tiefere Integration in Eclipse‘, Java Magazin (10) , 76 – 78 .