From e7fd4453e28f8de9fe7bca57d92057262159c75b Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Wed, 6 Apr 2022 08:15:59 +0200
Subject: [PATCH] WIP

---
 build.gradle                                  |   2 +-
 src/main/jastadd/SemanticActions.jadd         |   4 +-
 src/main/jastadd/World.jadd                   | 170 ------------------
 src/main/jastadd/World.jrag                   |  47 -----
 src/main/jastadd/World.relast                 |  15 --
 src/main/jastadd/common/MotionGrammar.relast  |   2 +
 .../java/de/tudresden/inf/st/mg/Main.java     |  31 +---
 .../de/tudresden/inf/st/mg/RobotParser.java   |  44 ++++-
 .../de/tudresden/inf/st/mg/ParserTest.java    |  40 +++--
 9 files changed, 74 insertions(+), 281 deletions(-)
 delete mode 100644 src/main/jastadd/World.jadd
 delete mode 100644 src/main/jastadd/World.jrag
 delete mode 100644 src/main/jastadd/World.relast

diff --git a/build.gradle b/build.gradle
index 8855bbd..1f62d3f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -84,7 +84,7 @@ jar {
     duplicatesStrategy = DuplicatesStrategy.FAIL
 }
 
-def relastFiles = ['./src/main/jastadd/common/MotionGrammar.relast', './src/main/jastadd/World.relast', './src/main/jastadd/LoadUnload.relast', './src/main/jastadd/Cleanup.relast']
+def relastFiles = ['./src/main/jastadd/common/MotionGrammar.relast', './src/main/jastadd/LoadWorld.relast', './src/main/jastadd/RobotWorld.relast', './src/main/jastadd/LoadUnload.relast', './src/main/jastadd/Cleanup.relast']
 def grammarPrefix = './src/gen/jastadd/MotionGrammar'
 def grammarDiagramFile = './src/gen/resources/diagrams/grammar/uml.png'
 def jastAddListName = 'JastAddList'
diff --git a/src/main/jastadd/SemanticActions.jadd b/src/main/jastadd/SemanticActions.jadd
index 16c727b..a3edb74 100644
--- a/src/main/jastadd/SemanticActions.jadd
+++ b/src/main/jastadd/SemanticActions.jadd
@@ -4,7 +4,7 @@ aspect SemanticActions {
   public void Load.action(World world) {
     System.out.println("performing semantic action for element Load");
     System.out.print("  " + world);
-    world.getContainer().setElementCount(world.getContainer().getElementCount() + 1);
+    world.setElementCount(world.getElementCount() + 1);
     System.out.println(" -> " + world);
   }
 
@@ -12,7 +12,7 @@ aspect SemanticActions {
   public void Unload.action(World world) {
     System.out.println("performing semantic action for element Unload");
     System.out.print("  " + world);
-    world.getContainer().setElementCount(world.getContainer().getElementCount() - 1);
+    world.setElementCount(world.getElementCount() - 1);
     System.out.println(" -> " + world);
   }
 }
\ No newline at end of file
diff --git a/src/main/jastadd/World.jadd b/src/main/jastadd/World.jadd
deleted file mode 100644
index e1a676a..0000000
--- a/src/main/jastadd/World.jadd
+++ /dev/null
@@ -1,170 +0,0 @@
-aspect World {
-
-  public static final int World.MAX_CAPACITY = 10;
-
-  public static World World.initialWorld(java.util.Random r) {
-    Container c = new Container();
-    c.setCapacity(r.nextInt(MAX_CAPACITY - 1) + 1);
-    c.setElementCount(r.nextInt(c.getCapacity()));
-    Table t = new Table();
-    t.addBin(new Bin("binRed", Pose.of(-10, -10, 0), "red"));
-    t.addBin(new Bin("binGreen", Pose.of(-10, 0, 0), "green"));
-    t.addBin(new Bin("binBlue", Pose.of(-10, 10, 0), "blue"));
-    t.addMovableObject(new MovableObject("boxRed", Pose.of(-5, -10, 0), "red"));
-    t.addMovableObject(new MovableObject("boxGreen", Pose.of(-5, 0, 0), "green"));
-    t.addMovableObject(new MovableObject("boxBlue", Pose.of(-5, 10, 0), "blue"));
-    Robot b = new Robot();
-    return new World(c, t, b);
-  }
-
-  public static Pose Pose.of(double x, double y, double z) {
-    return new Pose(x,y,z,0,0,0,1);
-  }
-
-  @Override
-  public String World.toString() {
-    return print();
-  }
-
-  public enum TokenType {UNDEFINED,FULL,LOAD,UNLOAD; }
-  public static TokenType Token.type() {return TokenType.UNDEFINED; }
-  public static TokenType Full.type() {return TokenType.FULL; }
-  public static TokenType Load.type() {return TokenType.LOAD; }
-  public static TokenType Unload.type() {return TokenType.UNLOAD; }
-
-  public Full World.parseFull() {
-    System.out.print("Trying to parse token <Full>... ");
-    if (getContainer().getCapacity() <= getContainer().getElementCount()) {
-      System.out.println("success");
-      return new Full();
-    } else {
-      System.out.println("failure");
-      return null;
-    }
-  }
-
-  public Load World.parseLoad() {
-    System.out.print("Trying to parse token <Load>... ");
-    // TODO should we check if loading is possible?
-    System.out.println("success");
-    return new Load();
-  }
-
-  public Unload World.parseUnload() {
-    System.out.print("Trying to parse token <Unload>... ");
-    // TODO should we check if unloading is possible?
-    System.out.println("success");
-    return new Unload();
-  }
-
-  public EmptyTable World.parseEmptyTable() {
-    System.out.print("Trying to parse token <EmptyTable>... ");
-    if (getTable().isEmpty()) {
-      System.out.println("success");
-      return new EmptyTable();
-    } else {
-      System.out.println("failure");
-      return null;
-    }
-  }
-
-  public ObjectAtWrongPlace World.parseObjectAtWrongPlace() {
-    System.out.print("Trying to parse token <ObjectAtWrongPlace>... ");
-    // TODO get a *random* object?
-    for (MovableObject o : getTable().getMovableObjectList()) {
-      if (!o.isInBin()) {
-        System.out.println("success");
-        return new ObjectAtWrongPlace(o.getName());
-      }
-    }
-    System.out.println("failure");
-    return null;
-  }
-
-  public Pick World.parsePick(String objectName) {
-    System.out.print("Trying to parse token <Pick> for Object \"" + objectName + "\"... ");
-    MovableObject o = getTable().getMovableObjectByName(objectName);
-
-    if (o != null) {
-      System.out.println("success");
-      return new Pick();
-    } else {
-      System.out.println("failure");
-      return null;
-    }
-  }
-
-  public RobotIsFree World.parseRobotIsFree() {
-    System.out.print("Trying to parse token <RobotIsFree>... ");
-    RobotIsIdle idle = parseRobotIsIdle();
-    RobotHasNoItemAttached noItem = parseRobotHasNoItemAttached();
-    if (idle != null && noItem != null) {
-      System.out.println("success");
-      return new RobotIsFree(idle, noItem);
-    } else {
-      System.out.println("failure");
-      return null;
-    }
-  }
-
-  public RobotIsIdle World.parseRobotIsIdle() {
-    System.out.print("Trying to parse token <RobotIsIdle>... ");
-    if (getRobot().getIsIdle()) {
-      System.out.println("success");
-      return new RobotIsIdle();
-    } else {
-      System.out.println("failure");
-      return null;
-    }
-  }
-
-  public RobotHasNoItemAttached World.parseRobotHasNoItemAttached() {
-    System.out.print("Trying to parse token <RobotHasNoItemAttached>... ");
-    if (!getRobot().hasAttachedItem()) {
-      System.out.println("success");
-      return new RobotHasNoItemAttached();
-    } else {
-      System.out.println("failure");
-      return null;
-    }
-  }
-
-  public Wait World.parseWait(double time) {
-    System.out.print("Trying to parse token <Wait> for " + time + " seconds... ");
-    System.out.println("success");
-    return new Wait();
-  }
-
-  public RightPlace World.parseRightPlace(String objectName) {
-    System.out.print("Trying to parse token <RightPlace> for Object \"" + objectName + "\"... ");
-    MovableObject o = getTable().getMovableObjectByName(objectName);
-
-    if (o != null) {
-      for (Bin b : getTable().getBinList()) {
-        if (o.fitsIn(b)) {
-          System.out.println("success");
-          return new RightPlace(b.getName());
-        }
-      }
-      System.out.println("failure (no matching bin found)");
-      return null;
-    } else {
-      System.out.println("failure (object does not exist)");
-      return null;
-    }
-  }
-
-  public Drop World.parseDrop(String objectName, String placeName) {
-    System.out.print("Trying to parse token <Drop> for Object \"" + objectName + "\" and Bin \"" + placeName + "\"... ");
-    MovableObject o = getTable().getMovableObjectByName(objectName);
-    Bin b = getTable().getBinByName(placeName);
-
-    if (o != null && b != null) {
-      System.out.println("success");
-      return new Drop();
-    } else {
-      System.out.println("failure");
-      return null;
-    }
-  }
-}
\ No newline at end of file
diff --git a/src/main/jastadd/World.jrag b/src/main/jastadd/World.jrag
deleted file mode 100644
index c0558b4..0000000
--- a/src/main/jastadd/World.jrag
+++ /dev/null
@@ -1,47 +0,0 @@
-aspect World {
-  syn String World.print() = "[World " + getContainer().print() + "]";
-  syn String Container.print() = "[Container " + getElementCount() + "/" + getCapacity() + "]";
-
-  inh Table PhysicalObject.containingTable();
-  eq Table.getChild().containingTable() = this;
-
-  syn boolean MovableObject.isInBin() {
-    for (Bin b : containingTable().getBinList()) {
-      if (getPose().getX() == b.getPose().getX() && getPose().getY() == b.getPose().getY() && getPose().getZ() == b.getPose().getZ()) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  syn boolean Table.isEmpty() {
-    for (MovableObject o : getMovableObjectList()) {
-      if (!o.isInBin()) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  syn MovableObject Table.getMovableObjectByName(String name) {
-    for (MovableObject o : getMovableObjectList()) {
-      if (o.getName().equals(name)) {
-        return o;
-      }
-    }
-    return null;
-  }
-
-  syn Bin Table.getBinByName(String name) {
-    for (Bin b : getBinList()) {
-      if (b.getName().equals(name)) {
-        return b;
-      }
-    }
-    return null;
-  }
-
-  syn boolean MovableObject.fitsIn(Bin b) {
-    return getColor().equals(b.getColor());
-  }
-}
\ No newline at end of file
diff --git a/src/main/jastadd/World.relast b/src/main/jastadd/World.relast
deleted file mode 100644
index 946dd81..0000000
--- a/src/main/jastadd/World.relast
+++ /dev/null
@@ -1,15 +0,0 @@
-// World Model of the Motion Grammar
-// The world contains one container with a maximum capacity and a current number of contained elements
-
-World ::= Container Table Robot;
-Container ::= <Capacity:int> <ElementCount:int>;
-
-Table ::= MovableObject* Bin*;
-abstract PhysicalObject ::= <Name> Pose <Color>;
-MovableObject : PhysicalObject;
-Bin : PhysicalObject;
-
-Pose ::= <X:double> <Y:double> <Z:double> <QX:double> <QY:double> <QZ:double> <QW:double>;
-
-Robot ::= <IsIdle:boolean>;
-rel Robot.attachedItem? <-> MovableObject.attachedRobot?;
diff --git a/src/main/jastadd/common/MotionGrammar.relast b/src/main/jastadd/common/MotionGrammar.relast
index 7b55408..06d63b8 100644
--- a/src/main/jastadd/common/MotionGrammar.relast
+++ b/src/main/jastadd/common/MotionGrammar.relast
@@ -1,3 +1,5 @@
 // Generic AST elements for every motion grammar
 abstract MotionGrammarElement;
 abstract Token : MotionGrammarElement;
+
+abstract World;
diff --git a/src/main/java/de/tudresden/inf/st/mg/Main.java b/src/main/java/de/tudresden/inf/st/mg/Main.java
index 905b280..8f4dadc 100644
--- a/src/main/java/de/tudresden/inf/st/mg/Main.java
+++ b/src/main/java/de/tudresden/inf/st/mg/Main.java
@@ -10,37 +10,8 @@ import java.util.Comparator;
 import java.util.Random;
 
 public class Main {
-
-  public static final Path AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing");
-
   public static void main(String[] args) {
-
-    // for some reason, the best random seed value here is 1 and not 0???
-    World world = World.initialWorld(new Random(1));
-
-    WorldParser parser = new WorldParser(world);
-    parser.setDebugDiagramDir(AST_DIAGRAM_DIR);
-
-    try {
-      Files.walk(AST_DIAGRAM_DIR)
-              .sorted(Comparator.reverseOrder())
-              .map(Path::toFile)
-              .forEach(File::delete);
-    } catch (IOException ignored) {
-    }
-
-    try {
-      Files.createDirectories(AST_DIAGRAM_DIR);
-    } catch (IOException e) {
-      System.err.println("Unable to create AST diagram directory " + AST_DIAGRAM_DIR);
-      e.printStackTrace();
-    }
-    try {
-      parser.parse();
-    } catch (WorldParser.ParseException e) {
-      e.printStackTrace();
-    }
-
+    throw new RuntimeException("Main method not implemented. Run tests.");
   }
 
 }
diff --git a/src/main/java/de/tudresden/inf/st/mg/RobotParser.java b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
index 30b8726..6b227c6 100644
--- a/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
+++ b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
@@ -8,9 +8,7 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
 
   private static final String WORLD = "World";
 
-  private Load peekedLoad_ = null;
-  private Unload peekedUnload_ = null;
-  private Full peekedFull_ = null;
+  private ObjectAtWrongPlace peekedObjectAtWrongPlace_ = null;
 
   public RobotParser(World world) {
     context_.put(WORLD, world);
@@ -23,14 +21,48 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
 
   @Override
   protected void parse(ASTNode<?> parent, int index) throws ParseException {
-    Tidy result;
+    Tidy result = new Tidy();
+    parent.setChild(result, index);
 
-    if (true) {
-      throw new ParseException("T", Load.type(), Full.type());
+    while (true) {
+      peekObjectAtWrongPlace();
+      if (peekedObjectAtWrongPlace_ != null) {
+        parseObjectAtWrongPlace(result.getMoveObjectToCorrectPlaceList(), result.getNumMoveObjectToCorrectPlace());
+      } else {
+        break;
+      }
     }
 
+    // TODO implement
+    // parseEmptyTable(result, 1);
+
     // semantic action for T
     result.action(getWorld());
     printAST("parseTidy", result);
   }
+
+  private boolean peekObjectAtWrongPlace() {
+    peekedObjectAtWrongPlace_ = getWorld().parseObjectAtWrongPlace();
+    return peekedObjectAtWrongPlace_ != null;
+  }
+
+  private void parseObjectAtWrongPlace(ASTNode<?> parent, int index) throws ParseException {
+    ObjectAtWrongPlace result;
+
+    if (peekedObjectAtWrongPlace_ != null) {
+      result = peekedObjectAtWrongPlace_;
+      peekedObjectAtWrongPlace_ = null; // TODO check if all peeked values are actually parsed afterwards
+    } else {
+      result = getWorld().parseObjectAtWrongPlace();
+      if (result == null) {
+        throw new ParseException(ObjectAtWrongPlace.type());
+      }
+    }
+
+    parent.setChild(result, index);
+
+    // semantic action for Unload
+    result.action(getWorld());
+    printAST("parseObjectAtWrongPlace", result);
+  }
 }
diff --git a/src/test/java/de/tudresden/inf/st/mg/ParserTest.java b/src/test/java/de/tudresden/inf/st/mg/ParserTest.java
index efb5b28..6dce667 100644
--- a/src/test/java/de/tudresden/inf/st/mg/ParserTest.java
+++ b/src/test/java/de/tudresden/inf/st/mg/ParserTest.java
@@ -1,6 +1,8 @@
 package de.tudresden.inf.st.mg;
 
 import de.tudresden.inf.st.mg.common.MotionGrammarParser;
+import de.tudresden.inf.st.mg.jastadd.model.Container;
+import de.tudresden.inf.st.mg.jastadd.model.RobotScene;
 import de.tudresden.inf.st.mg.jastadd.model.T1;
 import de.tudresden.inf.st.mg.jastadd.model.World;
 import org.junit.jupiter.api.BeforeAll;
@@ -17,29 +19,47 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class ParserTest {
 
-  public static final Path AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing");
+  public static final Path LOAD_AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing", "load");
+  public static final Path TIDY_AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing", "tidy");
 
   @BeforeAll
   static void prepareOutputPath() throws IOException {
     try {
-      Files.walk(AST_DIAGRAM_DIR)
-              .sorted(Comparator.reverseOrder())
-              .map(Path::toFile)
-              .forEach(File::delete);
+      Files.walk(LOAD_AST_DIAGRAM_DIR).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
     } catch (IOException e) {
       // do nothing
     }
-    Files.createDirectories(AST_DIAGRAM_DIR);
+    try {
+      Files.walk(TIDY_AST_DIAGRAM_DIR).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
+    } catch (IOException e) {
+      // do nothing
+    }
+    Files.createDirectories(LOAD_AST_DIAGRAM_DIR);
+    Files.createDirectories(TIDY_AST_DIAGRAM_DIR);
+  }
+
+  @Test
+  void runLodUnloadParser() throws MotionGrammarParser.ParseException {
+
+    // for some reason, the best random seed value here is 1 and not 0???
+    Container containerWorld = Container.initialWorld(new Random(1));
+
+    WorldParser parser = new WorldParser(containerWorld);
+    parser.setDebugDiagramDir(LOAD_AST_DIAGRAM_DIR);
+
+    var result = parser.parse();
+
+    assertThat(result).isNotNull().isInstanceOf(T1.class);
   }
 
   @Test
-  void runParser() throws MotionGrammarParser.ParseException {
+  void runTidyParser() throws MotionGrammarParser.ParseException {
 
     // for some reason, the best random seed value here is 1 and not 0???
-    World world = World.initialWorld(new Random(1));
+    World world = RobotScene.initialWorld(new Random(1));
 
-    WorldParser parser = new WorldParser(world);
-    parser.setDebugDiagramDir(AST_DIAGRAM_DIR);
+    RobotParser parser = new RobotParser(world);
+    parser.setDebugDiagramDir(TIDY_AST_DIAGRAM_DIR);
 
     var result = parser.parse();
 
-- 
GitLab