Subato

Resource Files

Eine kleine Skriptsprache

Studieren Sie das Aufgaben-Papier und lösen Sie die dort enthaltene Aufgabe.

 

In dieser Augfabe wird ein Parser, der durch das Tool ANTLR generiert wurde verwendet. Die generierten Klassen liegen der Augfabe bei, aber auch die Grammatik, aus der diese generiert wurde.

 

Man benötigt trotzdem die Runtimeklassen von ANTLR. Diese lassen sich über folgenden Link herunterladen:

https://www.antlr.org/download/antlr-4.9.3-complete.jar

 

Diese Jar-Datei ist dem Klassenpfad zur Compilierung und Ausführung des Programms hinzuzufügen.

 

Wenn alle Dateien (Quelltext und Jar) im Arbeitsordner liegen, können Sie mit folgender Anweisung das Projekt auf der Kommandozeile übersetzen:

javac -classpath antlr-4.9.3-complete.jar --enable-preview -source 17 -d . *.java

Wenn dann ein Beispielskript in der Datei t1.ms liegt, können Sie das mit folgender Anweisung auswerten lassen:

java -classpath antlr-4.9.3-complete.jar:. --enable-preview name.panitz.util.Expr t1.ms


package name.panitz.util; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; import java.util.List; import java.util.function.BinaryOperator; import java.io.Reader; import java.io.StringReader; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; public sealed interface Expr permits Expr.Var, Expr.Num, Expr.OpEx, Expr.IfEx, Expr.AssignEx, Expr.Seq, Expr.WhileEx { enum Op{ add((x,y)->x+y), sub((x,y)->x-y), mult((x,y)->x*y), div((x,y)->x/y), mod((x,y)->x%y); BinaryOperator<Long> f; Op(BinaryOperator<Long> f){this.f = f;} } record Var(String name) implements Expr{} record Num(long n) implements Expr{} record OpEx(Expr left,Op op,Expr right) implements Expr{} record IfEx(Expr cond,Expr alt1,Expr alt2) implements Expr{} record WhileEx(Expr cond,Expr body) implements Expr{} record AssignEx(String v, Expr e) implements Expr{} record Seq(List<Expr> es) implements Expr{} default void collectVars(Set<String> vs){ switch(this){ case Var ve -> {vs.add(ve.name);} case AssignEx ae -> { vs.add(ae.v); ae.e.collectVars(vs); } case OpEx oe -> { oe.left.collectVars(vs); oe.right.collectVars(vs); } case IfEx ie -> { ie.cond.collectVars(vs); ie.alt1.collectVars(vs); ie.alt2.collectVars(vs); } case WhileEx we -> { we.cond.collectVars(vs); we.body.collectVars(vs); } case Seq el -> {for (var e:el.es) e.collectVars(vs);} case Num ne -> {} } } default Set<String> collectVars(){ Set<String> result = new HashSet<String>(); collectVars(result); return result; } default long eval(Map<String,Long> env){ return switch(this){ case Num num -> num.n; case Var v -> { System.out.println("looking for variable: "+v.name); yield env.get(v.name); } default -> 0L; //TODO add all missing cases }; } static Map<String, Long> eval(String skript) { var result = new HashMap<String,Long>(); eval(new StringReader(skript),result); return result; } static void eval(Reader skript, Map<String, Long> env) { try { var lexer = new SimpleScriptLexer(CharStreams.fromReader(skript)); var parser = new SimpleScriptParser(new CommonTokenStream(lexer)); var antlrtree = parser.script(); var tree = new BuildTree().visit(antlrtree); tree.eval(env); } catch (Exception e) { System.out.println(e); } } public static void main(String... args){ for (var arg:args){ try { var env = new HashMap<String,Long>(); eval(new java.io.FileReader(arg),env); System.out.println(env); }catch(Exception e){ e.printStackTrace(); } } } }
java
You are not logged in and therefore you cannot submit a solution.