In den letzten Jahren gibt es ein zunehmendes Interesse an neuen Programmiersprachen, die auf bestimmte Problemdomänen spezialisiert sind, so genannte domänenspezifische Sprachen (engl. domain-specific languages, DSLs). DSLs stellen eine spezielle Syntax und Semantik zur Lösung einer bestimmten Klasse von Problemen zur Verfügung. Wenn Programme mit einer DSL entwickelt werden, erlaubt ihre konkrete Syntax eine höhere Produktivität des Endanwenders, da ihre Syntax näher an der Problemdomäne ist als die Syntax einer allgemeinen Sprache (engl. general-purpose language, GPL). Jedoch ist die Implementierung einer neuen Programmiersprache kostenintensiv, da Sprachentwickler eine Syntax und Semantik entwerfen und umsetzen müssen. Wegen dieser hohen initialen Kosten sehen viele davon ab eine neue DSL zu implementieren und einzusetzen. Um die initialen Kosten für DSLs zu minimieren, gibt es den Ansatz eine DSL in eine vorhandene Sprache einzubetten. Dabei wird die Syntax und Semantik der eingebetteten Sprache in Form einer Bibliothek in dieser Sprache beschrieben. Die vorhandene Sprache fungiert dabei als eine Wirtssprache für die DSL, die als Gastsprache in die Wirtssprache eingebettet wird. Durch die Einbettung können Gastsprachen die allgemeinen Sprachkonstrukte der Wirtssprache wieder verwenden, was Entwicklungskosten einspart. Zusätzlich erlaubt die Einbettung die Wiederverwendung der bestehenden Sprachinfrastruktur, wie z.B. den Entwicklungswerkzeugen, dem Parser, dem Compiler und der virtuellen Laufzeitumgebung. Neue Sprachkonstrukte können bei Bedarf durch Erweiterungen der entsprechenden Bibliotheken hinzugefügt werden. Eine vergleichende Studie zeigt, dass durch Einbettung die Entwicklungskosten für die Implementierung neuer Sprachen, im Vergleich zu traditionellen nicht eingebetten Sprachentwicklungsansätzen, signifikant reduziert werden können. Trotz dieser Vorteile gibt es für bestehende Ansätze zur Spracheneinbettung wichtige Einschränkungen bezüglich der Unterstützung für Spracheigenschaften, die normalerweise von nicht eingebetten Ansätzen unterstützt werden. In erster Linie gibt es bei bestehenden Ansätzen zur Einbettung in den meisten verwendeten Wirtssprachen keine Unterstützung für die freie Gestaltung der konkreten Syntax für die eingebettete Gastsprache. Beim Einbetten der Gastsprache in die Wirtssprache müssen die Ausdrücke der Gastsprache mit der Syntax der Wirtssprache übereinstimmen. Zweitens ist die Sprachsemantik, die eine Gastsprache haben kann, durch die vorgegebene Sprachsemantik der Wirtssprache eingeschränkt. Drittens gibt es keine Unterstützung für spezielle Kompositionen von mehreren DSLs, die Interaktionen in ihrer Syntax und Semantik haben. Diese Einschränkungen sind vorallem auf die mangelnde Anpassbarkeit von Konstrukten in eingebetteten Sprachen und Hostsprachen zurückzuführen. Um diese Probleme anzugehen, schlägt die vorliegende Arbeit die Reflective Embedding Architecture vor, die es ermöglicht Gastsprachen in reflexive Wirtssprachen einzubetten. Reflexive Sprachen sind Programmiersprachen, die spezielle Sprachkonstrukte besitzen, um die Struktur und das Verhalten von Programmen während ihrer Auswertung zu verändern. Die Verwendung einer reflexiven Sprache ermöglicht es die obigen Einschränkungen zu überwinden, da eingebettete Sprachen durch Analyse und Transformation ihrer Sprachbibliotheken angepasst werden können. Die Reflective Embedding Architecture definiert eine neue Vorgehensweise zum Einbetten von DSLs und beschreibt wie man für eine neue DSL die Syntax und Semantik als eine Menge von Artefakten einbetten kann. Jede Sprache ist eine eingekapselte Komponente, die eine Menge von wohldefinierter Schnittstellen festlegt. Die Klassen der Einbettung realisieren diese Schnittstellen, um die Einzelheiten der Ausführungssemantik für die Sprachkomponente festzulegen. Weiterhin unterstützt die Architektur das Einbetten von Sprachkompositionen, Scoping-Strategien, domänenspezifischen Analysen und Transformationen. Das Besondere an der Architektur zur Einbettung ist, dass jede Sprache automatisch eine Meta-Ebene besitzt, die Entwickler benutzen können, um die Einbettung anzupassen. Anpassungen auf der Meta-Ebene haben folgende Vorteile: Erstens ermöglicht die Reflective Embedding Architecture die Unterstützung von konkreter Syntax für eingebettete Sprachen. Für jede eingebettete Sprache können die Entwickler die zugehörige Bibliothek mit Annotationen versehen, um Meta-Daten für das Umwandeln von DSL Programmen mit konkreter Syntax in eine entsprechende ausführbare Form zu beschreiben. Durch die Verwendung einer speziellen Form von Agilen Grammatiken, die Insel-Grammatiken genannt werden, müssen nur die Teile der eingebetteten Sprache in einer Grammatik spezifiziert werden, die tatsächlich von der Grammatik der Wirtssprache abweichen. Insel-Grammatiken helfen dabei die initialen Kosten signifikant im Vergleich zu anderen eingebetteten Ansätzen zu reduzieren, wobei die volle Unterstützung für kontextfreie Sprachen gewährleistet bleibt. Zweitens ermöglicht die Meta-Ebene Unterstützung für Sprachkompositionen, deren Teilsprachen Interaktionen in ihrer Syntax und Semantik haben. Auf der einen Seite ermöglicht es die Meta-Ebene die Syntax mehrerer Teilsprachen zu analysieren und zu einer zusammengesetzten Sprachsyntax zu komponieren. Auf der anderen Seite ist es ermöglicht die eingebetteten Teilsprachen so anzupassen, dass sie an wohl definierten Punkten innerhalb ihrer Auswertungslogik miteinander interagieren können. In dem Sprachkompositionen mit Interaktionen unterstützt werden, ermöglicht die Architektur die Einbettung von speziellen Sprachabstraktionen, die es dem Endanwender erleichtern, modulare Programme zu entwickeln. Drittens ermöglicht die Meta-Ebene das Einbetten von Sprachen, die mit ihrer Wirtssprache interagieren, in dem sie reflexive Mechanismen verwenden, um die Auswertung der Sprachkonstrukte des Wirts zu beeinflussen. Nur wenn die Auswertung von Konstrukte der Wirtssprache geändert werden kann, können DSLs mit speziellen Modularisierungskonzepten eingebettet werden. Zur Evaluation der Reflective Embedding Architecture werden die in dieser Arbeit vorgeschlagenenKonzepte qualitativ und quantitativ überprüft. Zum einen wird eine Bewertung für die Unterstützung der Reflective Embedding Architecture für wünschenswerte Spracheigenschaften erstellt und mit verwandten Arbeiten verglichen, um die Konzepte qualitativ zu bewerten. Zum anderen wird eine Sprachimplementierung auf Basis der Reflective Embedding Architecture mit Implementierungen der selben Sprache quantitativ verglichen, die auf eingebetteten Ansätze und nicht eingebetten Ansätze aus den verwandten Arbeiten basieren. Die Evaluation zeigt im Vergleich, dass die Reflective Embedding Architecture für einbettete Sprachen erstmals eine umfassende Unterstützung der wünschenswerten Eigenschaften für eingebettete Sprachen ermöglicht und dass es dabei lediglich zu moderat erhöhten Laufzeitkosten kommt. | Deutsch |