close

Anmelden

Neues Passwort anfordern?

Anmeldung mit OpenID

Höhere Programmierkonzepte Praktikum I - Lab4Inf

EinbettenHerunterladen
H¨ohere Programmierkonzepte
Praktikum I
Prof. Dr. Nikolaus Wulff
28. Okt. – 6. Nov. 2014
WulffRunsBeta Service
1
Im Rahmen des Praktikums werden Sie den Service WulffRunsBeta entwickeln und St¨
uck f¨
ur St¨
uck inkrementell weiter ausbauen, bis Sie im Idealfall die Funktionalit¨at von WolframAlpha TM nachimplementiert1 haben. Als
einheitliche Schnittstelle f¨
ur die weiteren Praktia dient Sript.java, welche
in einem JAR Archive zur Verf¨
ugung gestellt wird. Es gilt diese Schnittstelle
zu implementieren – bei mir als Klasse WRBScript im selben Paket – und
mit geeigneten JUnit Klassen zu testen, die Implementierung wird f¨
ur die
weiteren Praktika ben¨otigt.
Aufgabe
1. Richten Sie die Eclipse so ein, dass Maven2, ANTLR 4 und JUnit
V4 lauff¨ahig sind und machen Sie sich mit der Verwendung dieser
Werkzeuge vertraut.
2. Erstellen Sie zwei Grammatikdefinition(en) (EBNF) f¨
ur eine Domain
Specific Language zum Auswerten mathematischer Formeln und Definitionen. Zur Erstellung des Lexers, Parsers dient ANTLR 4. Es ist
m¨oglich mit ANTLR 4 Observer und/oder Vistor Schnittstellen und
Klassen generieren zu lassen, die Sie als Ger¨
ust zum Travestieren des
Baumes ben¨otigen. Der Parser soll einen Syntaxbaum f¨
ur eingelesene
¨
mathematische Ausdr¨
ucke aufbauen, wie in der Ubung
I und Vorlesung
beschrieben. In diesem ersten Praktikum reicht es aus, wenn einfache
arithmetische Rechenregeln und Wertezuweisungen an Variablen erfolgen k¨onnen.
3. Entwickeln Sie parallel dazu einen JUnit Test, der die Funktionalit¨at
des Lexers und Parsers testet. Im Anhang finden Sie ein Beispiel f¨
ur
1
Sofern Sie die Site WolframAlpha TM noch nicht kennen, schauen Sie was auf der Site
http://www.wolframalpha.com alles m¨
oglich ist. Sicherlich mehr als Sie in einem Semester
im Praktikum erstellen k¨
onnen.
1
einen Test, der die Klasse WRBScript testet. Diese Klasse kapselt die
mit AntLR generierten Klassen WRBLexer, WRBParser und implementiert selbst die voergegebene Script Schnittstelle. WRBObserver implementiert die generierte Listener (oder Visitor) Schnittstelle, ist daher
selbst geschrieben und wertet den erstellten Syntaxbaum aus, berechnet die Zwischen- und Endergebnisse und weist sie Variablen zu. Die
Klasse WRBScript ist nicht generiert, sondern selbst programmiert und
dient als Fassade, die nach Außen die zugrundeliegende Komplexit¨at
der Anwendung versteckt und die WulffRunsBeta Funktionalit¨at mittels einer einfacher Schnittstelle anbietet.
Hinweise
Tips zur Installation der Eclipse Plugins finden Sie im ILIAS Forum zur
¨
Vorlesung und werden/wurden in den Ubungen
besprochen.
Beachten Sie bei der EBNF Erstellung die Regel Punkt- vor Strichrechnung und so m¨oglich auch Klammerrechnung.
Im Listing [1] sehen Sie eine Auszug aus der ANTLR Parser Definition
und das dazugeh¨orige Fragment [2] zur Erzeugung der Klasse WRBObserver.
Diese ist nach dem Observer-Design Muster implementiert und wird bei der
Travestierung des vom Parser generierten Syntaxbaum beim Betreten und
Verlassen von Knoten gerufen.
Zu jedem AST Knoten Typen, d.h. jeder EBNF Regel, ist hinterlegt, wie
sich der Ausdruck berechnet. F¨
ur mein Projekt wurden die EBNF Regeln
in zwei separaten Dateien WRBLexer.g4, WRBParser.g4, sowie in der selbst
erstellen Klasse WRBObserver.java modelliert – *.g4 ist die Standartdateiendung f¨
ur AntLR 4.
Entwickeln Sie ihre DSL und Grammtikregeln inkrementell und parallel
dazu die JUnit Tests, so dass Sie rechtzeitig merken wann der Parser Fehler
produziert und Ihre EBNF Sprachdefinition falsch ist. Im Anhang finden
Sie im Listing [3] ein erstes Ger¨
ust f¨
ur einen JUnit V4 Test, der bereits mit
Annotations arbeitet. Ein Konzept, dass Sie dieses Semester in HPK auch
noch kennenlernen werden.
parser grammar WRBParser;
options {
language = Java;
tokenVocab = WRBLexer;
}
/∗∗ id = expr
assign : ID ASSIGN expr;
/∗∗ expr = term ( (+|−) term )∗
expr: term ( operator=(ADD|SUB) term )∗ ;
∗/
∗/
Listing 1: WRBParser.g4: Einfache ANTLR Grammatik f¨
ur den Parser.
2
public class WRBObserver extends WRBParserBaseListener {
protected Map<ParseTree, Double> values = new IdentityHashMap<
ParseTree, Double>();
protected WRBScript script;
protected double lastValue;
public WRBObserver(final WRBScript script) {
this. script = script ;
if (null==script)
throw new IllegalArgumentException(”script is null”);
}
/∗∗
∗ id = expr
∗/
@Override
public void exitAssign(@NotNull WRBParser.AssignContext ctx) {
String id = ctx.ID().getSymbol().getText();
double value = getValue(ctx.expression());
script . setVariable(id , value) ;
setValue(ctx, value) ;
}
/∗∗
∗ expr = term ((+|−) term)∗
∗/
@Override
public void exitExpression(@NotNull WRBParser.ExpressionContext ctx) {
int k = 0;
double value = getValue(ctx.term(k));
Token op = ctx.operator;
ParseTree node = ctx.term(++k);
while (null!=node) {
if (WRBLexer.ADD==op.getType()) {
value += getValue(node);
} else {
value −= getValue(node);
}
node = ctx.term(++k);
op = ctx.operator;
}
setValue(ctx, value) ;
}
Listing 2: Fragment zur Travestierung des AST per Listener.
3
package de.lab4inf.wrb;
import org.junit.∗;
import static org.junit.Assert.∗;
/∗∗
∗ Test of the WulffRunsBeta−Script language.
∗/
public class WRBScriptTest {
final double eps = 1.E−8;
Script script ;
/∗∗
∗ @throws java.lang.Exception
∗/
@Before
public void setUp() throws Exception {
script = new WRBScript();
}
/∗∗
∗ Test method for {@link de.lab4inf .wrb.WRBScript#getVariable(...)}.
∗/
@Test(expected=IllegalArgumentException.class)
public void testGetUnknownVariable() throws Exception {
String key = ”dummy”;
script .getVariable(key);
}
/∗∗
∗ Test method for {@link de.lab4inf .wrb.WRBScript#setVariable(...)}.
∗ and {@link de.lab4inf .wrb.WRBScript#getVariable(...)}.
∗/
@Test
public void testSetGetVariable() throws Exception {
double y,x=2.78;
String key = ”XYZ”;
script . setVariable(key, x);
y = script .getVariable(key);
assertEquals(x,y,eps);
}
/∗∗
∗ Test method for {@link de.lab4inf .wrb.WRBScript#parse(...)}.
∗ Testing a very simple operation. More to come...
∗/
@Test
public void testParse() throws Exception {
String task = ”2+3”;
assertEquals (5.0, script .parse(task) , eps);
}
}
Listing 3: Grundger¨
ust eines JUnit Test.
4
Document
Kategorie
Technik
Seitenansichten
9
Dateigröße
45 KB
Tags
1/--Seiten
melden