Guten Abend,
Grober Kontext: Ich sollte objektorientiert ein Turtle Programm schreiben, welches die Turtle über ein Feld laufen lässt.
Problem: Wir bekommen Strings mit ganz vielen Objektaufrufen, z.B.:
Diesen sollen wir in eine ausführbare Sequence umwandeln. Eine Sequence ist eine Abfolge von beliebig vielen Befehlen(realisiert durch unterschiedliche Klassen)
Repeat(int n, Sequence seq) <--- seq wird n mal ausgeführt.
Subroutine(String name, Sequence seq) <--- seq wird ausgeführt, wenn ihr name aufgerufen wird.
Call(String name) <--- ruft eine Subroutine mit Namen auf / führt diese aus
So soll meine Zielvariable am Ende aussehen:
Ich hab das ganze jetzt mit RegEx probiert, aber ich struggle, die Repeat und Subroutine Klassen gescheit zu implementieren:
Ich wäre über jeden Hinweis dankbar
MfG
Grober Kontext: Ich sollte objektorientiert ein Turtle Programm schreiben, welches die Turtle über ein Feld laufen lässt.
Problem: Wir bekommen Strings mit ganz vielen Objektaufrufen, z.B.:
Java:
public static final String PROG_2 = "Subroutine(arc Repeat(10 Go(5) Turn(-5)))" + LS +
"Subroutine(petal Call(arc) Turn(-130) Call(arc))" + LS +
"Subroutine(flower Turn(90) PenDown() Repeat(10 Go(30) Turn(-5)) Repeat(9 Call(petal) Turn(30)) PenUp() Turn(208) Go(290) Turn(112))" + LS +
"Repeat(5 Call(flower) Go(100))";
Repeat(int n, Sequence seq) <--- seq wird n mal ausgeführt.
Subroutine(String name, Sequence seq) <--- seq wird ausgeführt, wenn ihr name aufgerufen wird.
Call(String name) <--- ruft eine Subroutine mit Namen auf / führt diese aus
So soll meine Zielvariable am Ende aussehen:
Java:
final Stmt meadow = new Sequence(new Subroutine("arc",
new Repeat(10, new Go(5), new Turn(-5))),
new Subroutine("petal",
new Call("arc"),
new Turn(-130),
new Call("arc")),
new Subroutine("flower",
new Turn(90),
new PenDown(),
new Repeat(10, new Go(30), new Turn(-5)),
new Repeat(9, new Call("petal"), new Turn(30)),
new PenUp(),
new Turn(208),
new Go(290),
new Turn(112)),
new Repeat(5, new Call("flower"), new Go(100)));
Ich hab das ganze jetzt mit RegEx probiert, aber ich struggle, die Repeat und Subroutine Klassen gescheit zu implementieren:
Java:
package turtle.parser;
import turtle.stmt.Go;
import turtle.stmt.PenDown;
import turtle.stmt.PenUp;
import turtle.stmt.Repeat;
import turtle.stmt.Sequence;
import turtle.stmt.Turn;
import turtle.stmt.Subroutine;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;
public class LogoParser{
String program;
List<Object> seq= new ArrayList<>();
String[] l1;
public LogoParser(String program){
this.program = program;
l1 = program == null ? null : program.split("\s");
}
public Sequence run() throws ParseException {
checkProgram();
return seq==null ? null: new Sequence(seq.toArray());
}
private void checkProgram() throws ParseException{
Pattern turnPattern = Pattern.compile("Turn\\( \\d+\\)");
String turn = "Turn\\( \\d+\\)";
Pattern goPattern = Pattern.compile("Go\\(\\d+\\)"); //unlimited amount of digits
Pattern repeatPattern = Pattern.compile("Repeat\\(\\d+\s([A-Za-z]+|\s| \\( | \\d+ \\))+ \\)\\) ");
Pattern subroutinePattern = Pattern.compile("Subroutine\\([A-Za-z]+\s.+\\)");
Pattern callPattern = Pattern.compile("Call\\(.+\\)");
Pattern penUpPattern = Pattern.compile("PenUp\\(\\)");
Pattern penDownPattern = Pattern.compile("PenDown\\(\\)");
Pattern repeatEnd = Pattern.compile(".+\\)\\)");
for (int i = 0; i < l1.length; i++) {
Matcher goMatcher = goPattern.matcher(l1[i]);
Matcher turnMatcher = turnPattern.matcher(l1[i]);
Matcher repeatMatcher = repeatPattern.matcher(l1[i]);
Matcher subroutineMatcher = subroutinePattern.matcher(l1[i]);
Matcher callMatcher = callPattern.matcher(l1[i]);
Matcher penUpMatcher = penUpPattern.matcher(l1[i]);
Matcher penDownMatcher = penDownPattern.matcher(l1[i]);
Matcher repeatEndMatcher = repeatEnd.matcher(l1[i]);
if (goMatcher.find()){
seq.add(new Go(Integer.parseInt(l1[i].replaceAll("[^0-9]", ""))));
//deletes programm which is already in Sequence
l1[i].replaceAll(goPattern.toString(), "");
}
else if (turnMatcher.find()){
seq.add(new Turn(Integer.parseInt(l1[i].replaceAll("^\\d", ""))));
}
else if (penUpMatcher.find()){
seq.add(new PenUp());
}
else if (penDownMatcher.find()){
seq.add(new PenDown());
}
else if (subroutineMatcher.find()){
//leider noch kein Ansatz
}
else if (repeatMatcher.find()){
List<Object> subList = new ArrayList<>();
int index = Integer.parseInt(l1[i].replaceAll("^\\d", ""));
//wie füge ich alle elemente in meine subList ?
seq.add(new Repeat(index, subList.toArray()));
}
else throw new ParseException("wrong sequence, try again");
}
}
}
Ich wäre über jeden Hinweis dankbar
MfG