Attributgrammatik Werkzeuge

Werbung
Attributgrammatik Werkzeuge
-Das JastAdd Semantikspezifikationswerkzeug-
Hauptseminar WS06/07
„Methoden zur Spezifikation der Semantik von
Programmiersprachen“
Christoff Bürger
1
Inhalt




Einleitung

Attributgrammatiken – Formal

Mindestspezifikation in Werkzeugen – maschinelle Bearbeitung
durch impliziten Kontext
Werkzeuge für Attributgrammatiken

Warum / Wofür Werkzeuge

Werkzeugfunktionalitäten und Entwicklungsziele
Beispielwerkzeug : JastAdd

JastAdds Werkzeugfunktionalitäten und Entwicklungsziele

JastAdd Spezifikationen
✔ AST Spezifikationen
✔ Semantikmodul- / Aspektspezifikationen

Beispiele
Vergleich JastAdds mit anderen Werkzeugen (Eli)

Eli Werkzeugfunktionalitäten und Entwicklungsziele

Fazit
2
Einleitung – Attributgrammatiken - Formal
Formale Attributgrammatikspezifikationen beruhen auf einer
mathematischen Spezifikationssprache (mathematischen Notationen),
welche Typen, Wertebereiche, Berechnungsfunktionen, Attribute und
Auswertungsregeln festlegt. Sie sind daher vollständig und prüfbar,
jedoch umfangreich.


Eine Attributgrammatik AG basiert auf einer kontextfreien Grammatik
G = (N, T, Z, P) mit

N ... Nichtterminale

T ... Terminale

Z ... Startregel

P ... Produktionenen der Form A -> S1 S2 S3 ... Sn
AG = (G, D, B, R, C) mit

D = (K, , , , ) ... Semantischer Bereich

B = (S-Att, I-Att, Att, S, I, A, 0, W) ... Attributbeschreibung

R ... Semantische Regeln

C ... Semantische Bedingungen (Prädikative Regeln)
3
Einleitung – Attributgrammatiken - Formal

D = (K, , , , ) ... Semantischer Bereich

K ... endliche Menge von Sorten; Typen

 ... Wertemenge; ordnet jeder Sorte (Typ) alle möglichen Werte
zu

 ... Operationssymbole (vergleichbar C++ Funktionsdeklaration);
Abbildung von Argumenten auf Ergebnis, daher
✔ A
x A2 x A3 x ... x An -> E
1

 ... Prädikatssymbole (vergleichbar C++ Funktionsdeklaration
mit Rückgabewert boolean)

 ... Interpretationsfunktion; Implementierung der Funktionen aus
 und 
4
Einleitung – Attributgrammatiken - Formal
Bsp.: K = {String, Char}
(Char) = {a, b, c,...,z,A,...,Z}
(String) = {w|w = w1w2...wn mit n ≥ 0 und w1,w2,..,wn}
 = {concat(String x String -> String), ...}
(concat) : (String) x (String) -> (String) mit
concat(s1, s2) = w1w2...wiwi+1...wn
wenn s1 = w1w2...wi und s2 = wi+1...wn
5
Einleitung – Attributgrammatiken - Formal

B = (S-Att, I-Att, Att, S, I, A, 0, W) ... Attributbeschreibung

S-Att ... Menge der synthetischen Attribute

I-Att ... Menge der inheriten Attribute

Att = S-Att ∪ I-Att

S : N -> {s | sS-Att} ... Zuordnungsfunktion; Ordnet den
Nichtterminalen der kontextfreien Grammatik ihre synthetischen
Attribute zu.

I : N -> {i | iI-Att} ... Zuordnungsfunktion

A(X) = S(X) ∪ I(X) mit XN

0S(Z) ... Bedeutungsattribut; synthetische Attribut an der Wurzel
des Parsebaumes

W : Att -> K ... Zuordnungsfunktion; Ordnet jedem Attribut eine
Sorte / Typ zu
6
Einleitung – Attributgrammatiken - Formal
Für jede Produktion pP gibt es eine Menge von semantischen Regeln
R(p), so dass alle p zugeordneten innen Attribute Ai abhängig von
außen Attributen berechnet werden. |R(p)| = |Ai|.
Sei p : X0 -> w0X1w1X2...wn-1Xnwn+1 mit wiT* und XiN
Eine semantische Regel hat den Aufbau :
<a0, jo> = f (<a1, j1>, <a2, j2>,...,<an, jn>)
mit n  0 und für n > 0 ist <ai, ji>
außen Attribut
s
<aiA(Xi), i> ... i bezogen auf Indizes
von X bei Produktion
i
i
...
i
Für eine Produktion auszuwertende
synthetische und inherite Attribute
(innen Attribute).
f(W(a1),...,W(an), W(a0)) semantische
Operation
7
Einleitung – Mindestspezifikation in Werkzeugen –
impliziter Kontext
Werkzeuge für AG müssen in der Lage sein formale Spezifikationen
umzusetzen. Es ist jedoch schwierig die Mächtigkeit und damit
Einfachheit mathematischer Notationen bereitzustellen.
Formale Spezifikationen sind zu umfangreich :

Vereinfachung durch impliziten Kontext, welcher Vollständigkeit und
Prüfbarkeit von Werkzeugspezifikationen erlaubt, jedoch bestimmte
Spezifikationsteile aus anderen herleitet bzw. zusammenlegt bzw.
vorweg nimmt.
Impliziter Kontext : Vordefinierte und implementierte atomare
Operationen und Typen. Alle weiteren Operationen und Typen
beruhen auf diesen. Legt implizite Spezifikationssemantik und Syntax
fest.
Der implizite Kontext muss existieren, da nur er eine maschinelle
Implementierung und Auswertung erlaubt!
8
Einleitung – Mindestspezifikation in Werkzeugen –
impliziter Kontext
AG = (G, D, B, R, C) mit

D = (K, , , , ) ... Semantischer Bereich

B = (S-Att, I-Att, Att, S, I, A, 0, W) ... Attributbeschreibung

R ... Semantische Regeln

C ... Semantische Bedingungen (Prädikative Regeln)
Farblich hervorgehobene Teile sind explizit zu definieren in einer
Spezifikation für eine maschinelle Spezifikationssprache für AG. Ihre
Semantik wird durch die Sprache festgelegt (impliziter Kontext).
Farblich gleich markierte Teile sind zusammenfassbar um die
maschinelle Spezifikation zu vereinfachen.
Man beachte, dass atomare Typen und deren Wertebereich durch die
Sprache implizit festgelegt werden, daher K die Möglichkeit darstellt
eigene Typen aufbauend auf atomaren zu definieren. Dies muss nicht
möglich sein, ist aber Standard. Analoges gilt für Operationssymbole.
9
Einleitung – Mindestspezifikation in Werkzeugen –
impliziter Kontext
Durch die maschinelle Spezifikation kann sich eine AG Spezifikation
folgendermaßen vereinfachen :

AG = (G, K, , S, I, W, R) mit

G ... kontextfreie Grammatik

K ... Datentypen

 ... semantische Funktionen

S ... Zuordnung von synthetischen Attributen zu
Grammatiksymbolen

I ... Zuordnung von inheriten Attributen zu Grammatiksymbolen

W ... Zuordnung von Datentypen an Attribute

R ... Semantische Regeln
Der implizite Kontext (Spezifikationssprache) muss diese Teile definieren
und schränkt sie ein (insbesondere Datentypen).
Blau markierte Teile sinnvollerweise in einem Spezifikationsschritt
durchführbar, daher jedes deklarierte Attribut wird bei der Deklaration
gleichzeitig gebunden an Nichtterminal, Datentyp und Attributtyp :
AG = (G, K, , A, R).
10
Einleitung - Zusammenfassung
Fazit : Ein Werkzeug für AG steht und fällt mit seiner
Spezifikationssprache.
Zwei mögliche Sprachkonzepte :

Spezifikationen erstellt von Menschen per Hand

Maschinell erstellte Spezifikationen / Generatoren
Spezifikationssprache
impliziter Kontext
Formal
Maschinell
Spezifikation
Mathematik
Logik
proprietäre
Werkzeugsprache
Attributauswerter
11
Werkzeuge für Attributgrammatiken
Werkzeuge für AG ermöglichen die automatisierte Generierung von
Attributauswertern gemäß einer Spezifikation und die Prüfung
derselben.
Sie sind überall dort einsetzbar, wo Parsebäume kontextfreier
Grammatiken semantisch ausgewertet werden müssen.
Wichtige Qualitätskriterien sind :

Verständlichkeit, Mächtigkeit der Spezifikationssprache

Geschwindigkeit, Speicherverbrauch und Typ des Attributauswerters

Integrierbarkeit von Syntaxanalysewerkzeugen

Benutzerfreundlichkeit (GUI etc.)
12
Werkzeuge für Attributgrammatiken
Wesentliche Entwicklungsziele sind :

Möglichkeit Parsebäume der syntaktischen Analyse für die
semantische aufzubereiten

Möglichkeit semantische Spezifikationen (gängiger semantischer
Aufgaben) wiederverwenden zu können und kombinieren zu können

Bestehende semantische Spezifikationen leicht erweitern zu können
(z.B. wenn Syntax erweitert wird)

Leicht zu erlernende, aber mächtige Spezifikationssprache

Attributauswertungsregeln einfach umzusetzen, ähnlich einer
formalen Spezifikation auf dem Papier

Spezifikationssprache sollte bekannt erscheinen

Einfache Attributhandhabung (keine umständlichen Kopierregeln,
einfache Sammlung von Attributen)

Leicht integrierbarer Attributauswerter mit guten Schnittstellen
13
JastAdd - Entwicklungsziele
JastAdds wesentliche Entwicklungsziel ist es, die Wiederverwendung von
Semantikspezifikationen und deren Erweiterung zu ermöglichen (just
to add semantics).
Dabei wird ein objektorientiertes Entwicklungsmodell verwendet, sowie
eine deklarative Spezifikationssprache.
Orientierungspunkt ist die Java Sprachsyntax und Semantik.
JastAdd konzentriert sich nur auf die semantische Auswertung. Es bietet
Schnittstellen um Parser zu integrieren, welche die auszuwertenden
Parsebäume generieren.
Vom Parser bereitgestellte Parsebäume müssen einer abstrakten
Syntaxbaumspezifikation genügen (AST-specification).
14
JastAdd – Funktionalitäten und Entwicklungsziele
JastAdd ermöglicht die Spezifikation von AG wie von Knuth 1968
eingeführt und Generierung von Auswertern, erweitert diese
Basiskonzepte jedoch um :

Referenzierte Attribute (referenced attributes)

Parametrisierte Attribute (parameterized attributes)

Rekursive Attributauswertungsfunktionen (circular evaluation
functions)

Deklarative Spezifikationen (declarative specifications)

Objekt orientierter Ansatz (object oriented design)

Deklarative Parsebaumumschreibung (rewriting rules)

Semantikmodule (semantic aspect weaving)
15
JastAdd – Spezifikationen
Eine JastAdd Spezifikation besteht aus zwei wesentlichen Teilen :

AST-Spezifikation ... Spezifiziert die Struktur von Syntaxbäumen,
deren Semantik zu bestimmen ist (*.ast)

Aspekt-Spezifikationen ... Spezifiziert die Attribute, deren Typen und
Auswertungsregeln (*.jadd / *.jrag)
AST-Spezifikationen definieren eine Java Klassenhierarchie und
Aggregatabhängigkeiten. Sie spezifizieren eine abstrakte Grammatik.
Vom Parser generierte Parsebäume müssen der AST-Spezifikation
genügen, daher sie müssen eine Komposition aus Java Objekten
darstellen.
Aspekt-Spezifikationen sind Module, welche die Semantik (oder Teile
davon) einer abstrakten Grammatik mithilfe von AG definieren. Daher
spezifizieren sie Attribute, deren Typen (sowohl Daten- als auch
Attributtyp) und Auswertungsregeln.
16
JastAdd – Spezifikationen
Die AST-Spezifikationen werden in Java Klassen übersetzt, den ASTclasses. Die Übersetzung einer AST-Spezifikation resultiert in den ASTclass skeletons.
Die Aspekt-Spezifikationen werden ebenfalls in Java Code übersetzt und
anschließend auf Aspekt orientierte Art und Weise in die AST-class
skeletons eingewoben, so das die finalen AST-classes entstehen.
Die Semantik einer Sprache ist daher vollständig in den generierten ASTclasses spezifiziert.
Die Attributauswertung steckt implizit in den finalen AST-classes. Für
jedes Attribut gibt es eine gleichnamige Accessormethode. Wird diese
aufgerufen, so sichert JastAdd ab, dass der korrekte Attributendwert
geliefert wird.
17
JastAdd – AST-Spezifikationen
Die genaue Definition und der Übersetzungsprozess von kontextfreien
Grammatiken in AST-Spezifikationen stehen im zugehörigem paper.
Vorteile : Typsicherheit; Objekt orientiert
geg.: kontextfreie Grammatik
A -> t1B
ges.: AST-Spezifikation
A ::= <t1> B;
B -> t2 B
B -> C D
B -> D
abstract B;
B1 : B ::= <t2> B;
B2 : B ::= C D;
B3 : B ::= D;
C -> 
C -> E
C ::= [E];
D -> t4
D ::= t4;
E ::= ;
E -> 
18
JastAdd – Aspekt-Spezifikationen
Die genaue Definition von Aspekt-Spezifikationen steht im zugehörigem
paper.
Aspekt-Spezifikationen : Deklarative oder imperative Spezifikation von
Attributen, deren Typen, der Zuordnung zu den Nichtterminalen (ASTclasses) und Auswertungsregeln.
In den Aspekt-Spezifikationen steht die komplette Java-Syntax und
Semantik zur Verfügung, genauso wie die Möglichkeit beliebigen
weiteren Java Quellcode einzubinden.
Schlüsselwörter :
aspect
syn, inh, lazy, eq
refine
rewrite, when, to
19
JastAdd – Aspekt-Spezifikationen
Attributdeklaration :
ATyp lazy JavaTyp ASTClass.attributName(JavaParameterListe);
ATyp = {syn, inh}
lazy ... optional, zum cachen berechneter Werte
Attributauswertung (synthetische Attribute) :
eq ASTClass.attributName = JavaExpression;
eq ASTClass.attributName {
//JavaCode
return AttributOfASTClassType;
}
Attributauswertung (inherite Attribute) :
eq ASTClass.getSubComponent().attributName = JavaExpression;
eq ASTClass.getSubComponent().attributName {
//JavaCode
return AttributOfSubComponentASTClassType;
}
20
JastAdd – Beispiel
21
JastAdd – Aspekt-Spezifikationen
Aspekt-Spezifikationen sind unabhängig voneinander und es können
beliebig viele semantische Aspekte in die Semantik integriert werden.
Der Nutzer muss sich keine Gedanken darüber machen, in welcher
Reihenfolge Attributauswertungen und Parsebaumumschreibungen
vorgenommen werden, JastAdd regelt dies automatisch. Es ist
garantiert, dass immer wenn auf einen Attributwert mit dessen
Accessormethode zugegriffen wird, dieser berechnet wurde. Graph
rewrite Schritte werden immer sobald wie möglich durchgeführt.
Es ist möglich in einem Aspekt Attribute, welche in einem anderen
Aspekt spezifiziert wurden, zu benutzen.
Auswertungsfunktionen eines Aspektes können von einem anderen
Aspekt überschrieben werden (refine).
Der Objekt orientierte Ansatz erlaubt die Generalisierung und
Spezialisierung von Semantikbestandteilen.
22
JastAdd – Zusammenfassung
23
JastAdd – Zusammenfassung
Trotz aller Vorteile und der Einfachheit der Spezifikationssprache gibt es
gerade bei komplexen Spezifikationen einige Hürden :

Durch zirkulare Attributauswertungsfunktionen die Gefahr der
Nichtterminierung -> Semantisch gesehen korrekt, da unendliche
Rekursion keine Semantik besitzt.

Potenziell zirkulare graph rewriting Regeln.

Zirkularität durch eine Kombination der ersten beiden Typen (schwer
nachzuvollziehen).

Bindung von Attributen über Produktionen !!! Bug ? Feature ? Oder
einfach nur ein fieser Hack.

Eigener Aspektweber; Nutzung von AspectJ wäre besser.

Die Erweiterungen des Basiskonzeptes von AG sind sinnvoll, führen
jedoch zu einem größeren theoretischen Hintergrund -> Erhöhung der
Komplexität der semantischen Spezifikationen, jedoch NICHT deren
Größe (kleine Spezifikationen die viel machen).
24
Vergleich mit anderen Werkzeugen - Eli





Älteres Tool, welches alle Phasen der Compilerentwicklung umfasst
(Lexer, Parser, semantische Analyse).
Ausgehend von Spezifikationen wird C Code mit passenden Makefiles
generiert
Stellt Sammlung vieler einzelner Tools dar -> LIDO ist die
semantische Spezifikationssprache. Aus einer semantischen
Spezifikation wird ein LIGA C Attributauswerter generiert.
Viele Erweiterungsmodule (z.B. um Attributabhängigkeiten graphisch
darzustellen)
Attributdatentypen sind C Datentypen; Funktionen welche bei der
Attributauswertung benutzt werden sind C Funktionen. Für diese Teile
ist der Nutzer selbst zuständig. Sie werden in der Spezifikation nur
benutzt / erwähnt. -> yacc ähnlich
Der Ansatz der Spezifikationssprache LIDO ist derselbe wie der von yacc
Spezifikationen.
Es gibt eine externe graphische Benutzeroberfläche : LAMA
25
Vergleich mit anderen Werkzeugen - Eli





Spezifikation von vom Kontext unabhängiger Berechnungen (symbol
computations) -> in JastAdd möglich, indem Berechnungen an
abstrakte AST-classes gebunden werden.
Einsparen von copy rules möglich durch remote dependencies
Berechnungen während der Parsebaumkonstruktion -> in JastAdd
nicht möglich (nur über hacking ähnliche Umwege)
Auswertung zirkulärer Attributabhängigkeiten möglich, wenn man den
Test auf Zirkularität abstellt. Jedoch keine automatische Generierung
notwendiger Fallunterscheidungen um eine Rekursion abzubrechen ->
Abbruch (Fixpunkt) muss selbst kontrolliert werden -> imperativ
Semantikmodule werden unterstützt und eine Bibliothek mit gängigen
Semantikkonzepten liegt vor.
26
Vergleich mit anderen Werkzeugen - Fazit
JastAdd ist ein aktives Projekt mit guten Aussichten für die Zukunft.
Eli hat sich in der Vergangenheit bewährt, beruht jedoch auf überholten
Entwicklungszielen.
JastAdd kann alles was Eli kann, hat jedoch die intuitiver und
verbreitetere Spezifikationssprache (Java ähnlich). Der Einstieg in
JastAdd ist leichter, da der Objekt orientierte Ansatz verständlich ist.
Mit Eclipse gibt es eine gute Entwicklungsumgebung. Die Java
Klassenbibliothek erlaubt eine effiziente Implementierung
komplizierter Attributauswertungsfunktionen.
Die Ausnutzung natürlicher, durch die Java Spezifikation gegebener
Vorteile ist der große Vorteil JastAdds (referenced attribute grammars
in einer Sprache basierend auf Referenzen; Modularität und
Wiederverwendbarkeit einzelner Aspekte (Kapselung) in einer Objekt
orientierten Umgebung vs. Imperative).
27
Herunterladen