Goodbye XML – Befreiungsakt mit Xtext

Gute Defaults sind ein weiteres wichtiges Mittel, um eine Sprache von unnötigem Ballast zu befreien. Wenn die überwiegende Mehrheit der Projekte z. B. als jar gepackt wird, dann sollte man nur für die verbleibende Minderheit das packaging angeben müssen. Alle anderen werden dann per Default zu einem jar verschnürt.

Wir sehen also, dass eine spezifische Sprache mit eigener Syntax viele wichtige Vorteile gegenüber einer generischen XML-Sprache hat. Die entscheidende Frage ist, ob wir in der Lage sind, so eine Sprache zu bauen – und das mit sinnvollem Aufwand. Maven ist für diesen Aspekt eigentlich ein schlechtes Beispiel, da es enorm viele User besitzt. Summiert man die Zeit, die Entwickler mit dem Lesen und Editieren von pom.xml-Dateien verbracht haben und auch zukünftig verbringen werden, würde sich hierfür wahrscheinlich sogar ein handgeschriebener, in Assembler programmierter Parser lohnen. Tatsächlich ist die Definition der in Listing 2 abgebildeten Sprache aber einfacher und kürzer als die XML-Schema-Variante.

Compiler-Bauer? Das sind doch die von der Uni!

In Listing 3 sehen sie den Ausschnitt aus der originalen XML-Schema-Datei für Mavens POM, der notwendig ist, um die in Listing 1 gezeigte XML-Datei zu validieren. Demgegenüber zeigt Listing 4 die Xtext-Definition der in Listing 2 benutzten, stark vereinfachten Sprache. Wenn Sie XML und besonders XSD kennen, werden Sie sich im gekürzten Maven-Schema wahrscheinlich auf den ersten Blick ganz gut zurechtfinden. Die Xtext-Variante hingegen wird Ihnen höchstens vertraut vorkommen, wenn Sie in der Vorlesung „Compiler-Bau“ gut aufgepasst haben. Die theoretischen Untiefen, die Sie möglicherweise während dieser Veranstaltung kennengelernt haben, können Sie allerdings ruhigen Gewissens zur Seite legen.

Listing 3: SubSet der XSD für Maven POMs
Listing 4: Xtext-Grammatik für vereinfachte POMs
grammar org.xtext.simplemaven.SimpleMaven with org.eclipse.xtext.common.Terminals
generate simpleMaven "http://www.xtext.org/simplemaven/SimpleMaven"

Project:
  'project' (description=STRING url=PARENTHESIZED?)?
     'id' name=QualifiedName version=Version
    ('packaging' kind=PackageKind)?
    ('depends on' dependencies+=Dependency 
                           (',' dependencies+=Dependency)+)?;
Dependency:
  name=[Project|QualifiedName] version=Version ('for' scope=Scope)?;
enum Scope:
  compile | provided | runtime | test | system;
enum PackageKind:
  pom | jar | mavenPlugin="maven-plugin" | ejb | war | ear | rar | par;
QualifiedName:
  ID ('.' ID)*;
Version:
  INT ('.' INT ('.' INT)?)? '-SNAPSHOT'?;
terminal PARENTHESIZED:
  '('->')';

Einen Parser zu programmieren, ist nicht trivial. Aber einen Parser-Generator mit einer funktionierenden Grammatik zu füttern, ist absolut keine Zauberei. Die Grammatiksprache in Xtext ist in sich selbst definiert, und das in nur 173 Zeilen. Im Gegensatz dazu fällt das XML Schema für Maven mit knapp 3000 Zeilen recht üppig aus. Wir wollen im Rahmen dieses Artikels nicht die ganze Xtext-Grammatiksprache erklären, jedoch auf die Menge und die Art der Informationen verweisen, die diese enthält.

Die XSD-Datei für unsere minimalen POMs ist mehr als doppelt so groß wie die Xtext-Grammatik und enthält lediglich Informationen über die Struktur der XML-Sprache. Diese Struktur wird üblicherweise die abstrakte Syntax genannt. In der Xtext-Grammatik wird zusätzlich auch die konkrete Syntax definiert, d. h. die konkrete textuelle Form, in der Konzepte der Sprache geschrieben werden sollen. Weiterhin können hier Literale für Datentypen, Enumerationen und sogar beliebige Querverweise deklariert werden. In unserer Xtext-basierten Maven-Sprache sind beispielsweise die Namen der Dependencies echte Querverweise auf Projektdeklarationen in anderen Dateien. Hat man sich im Namen einer Dependency vertippt (z. B. nunit statt junit), wird einem der Linker schon beim Laden der Datei sagen, dass die angegebene Dependency nicht existiert (Abb. 1). XML Schema unterstützt zwar auch eine einfache Form von Querverweisen, diese sind aber so stark limitiert, dass sie z. B. für den beschriebenen Fall gar nicht anwendbar wären.

Abb. 1: Echte Querverweise

Wir haben nun also die Sprache mit der kompakten Syntax definiert und festgestellt, dass das gar nicht so viel zu tippen war. Manch einer mag jetzt Folgendes denken: Ja, aber das Tolle an XML ist nicht nur, dass man keinen Parser bauen muss, sondern dass es aufgrund der generischen Syntax auch schon tausende tolle Werkzeuge gibt, die damit zusammenspielen. Darauf will man nicht verzichten, und eine IDE für die eigene Sprache zu entwickeln, ist viel zu aufwändig. Glücklicherweise ist das mit Xtext nicht nötig.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.