From b9a145a6eeab7cec5f76b8b4cb9ad456b0aa7737 Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Mon, 29 Aug 2022 23:02:17 +0200
Subject: [PATCH] waiting feature

---
 src/main/jastadd/cleanup/Cleanup.jrag         |  15 --
 src/main/jastadd/cleanup/Cleanup.relast       |  15 +-
 src/main/jastadd/cleanup/RobotWorld.jadd      |  10 -
 src/main/jastadd/cleanup/SemanticActions.jadd |  10 -
 src/main/jastadd/select/Select.relast         |   9 +
 .../de/tudresden/inf/st/mg/RobotParser.java   | 182 +++---------------
 .../inf/st/mg/common/MotionGrammarParser.java |   7 +
 .../template-configs/ControlParser.yaml       |  51 +++++
 8 files changed, 94 insertions(+), 205 deletions(-)
 create mode 100644 src/main/jastadd/select/Select.relast
 create mode 100644 src/main/resources/template-configs/ControlParser.yaml

diff --git a/src/main/jastadd/cleanup/Cleanup.jrag b/src/main/jastadd/cleanup/Cleanup.jrag
index d521f73..7e44ce3 100644
--- a/src/main/jastadd/cleanup/Cleanup.jrag
+++ b/src/main/jastadd/cleanup/Cleanup.jrag
@@ -11,21 +11,6 @@ aspect CleanupAttributes {
     throw new UnsupportedOperationException("Invalid use of attribute object():String");
   }
 
-  syn double ASTNode.time(); // TODO can this be avoided?
-  eq RobotIsNotReadyToPick.time() = 1;
-  eq RobotIsNotReadyToDrop.time() = 1;
-  eq WaitForEmptyTable.time() = 1;
-  eq WaitForFullTable.time() = 1;
-  eq ASTNode.time() {
-    throw new UnsupportedOperationException("Invalid use of attribute time():double");
-  }
-
-  inh double Wait.time();
-  eq RobotIsNotReadyToPick.getWait().time() = time();
-  eq RobotIsNotReadyToDrop.getWait().time() = time();
-  eq WaitForEmptyTable.getWait().time() = time();
-  eq WaitForFullTable.getWait().time() = time();
-
   syn String ASTNode.place(); // TODO can this be avoided?
   eq DropObjectAtRightPlace.place() = getRightPlace().getPlace();
   eq ASTNode.place() {
diff --git a/src/main/jastadd/cleanup/Cleanup.relast b/src/main/jastadd/cleanup/Cleanup.relast
index 79abc76..3931815 100644
--- a/src/main/jastadd/cleanup/Cleanup.relast
+++ b/src/main/jastadd/cleanup/Cleanup.relast
@@ -1,15 +1,7 @@
-Tidy : MotionGrammarElement ::= WaitForFullTable* MoveObjectToCorrectPlace* WaitForEmptyTable* EmptyTable;
+Tidy : MotionGrammarElement ::= NotEmptyTable MoveObjectToCorrectPlace* EmptyTable;
 MoveObjectToCorrectPlace : MotionGrammarElement ::= ObjectAtWrongPlace/*provides object*/ PickUpObject/*uses object*/ DropObjectAtRightPlace/*uses object*/;
-PickUpObject/*requires object*/ : MotionGrammarElement ::= RobotIsReadyToPick;
-abstract RobotIsReadyToPick : MotionGrammarElement;
-RobotIsReallyReadyToPick : RobotIsReadyToPick ::= RobotIsReadyToPickToken;
-RobotIsNotReadyToPick    : RobotIsReadyToPick ::= RobotIsNotReadyToPickToken Wait/*uses const "1sec"*/ RobotIsReadyToPick;
-abstract RobotIsReadyToDrop : MotionGrammarElement;
-RobotIsReallyReadyToDrop : RobotIsReadyToDrop ::= RobotIsReadyToDropToken;
-RobotIsNotReadyToDrop    : RobotIsReadyToDrop ::= RobotIsNotReadyToDropToken Wait/*uses const "1sec"*/ RobotIsReadyToDrop;
-DropObjectAtRightPlace/*requires object*/ : MotionGrammarElement ::= RobotIsReadyToDrop RightPlace/*uses object, provides place*/;
-WaitForEmptyTable : MotionGrammarElement ::= NotEmptyTable Wait/*uses const "1sec"*/;
-WaitForFullTable : MotionGrammarElement ::= EmptyTable Wait/*uses const "1sec"*/;
+PickUpObject/*requires object*/ : MotionGrammarElement ::= RobotIsReadyToPickToken;
+DropObjectAtRightPlace/*requires object*/ : MotionGrammarElement ::= RobotIsReadyToDropToken RightPlace/*uses object, provides place*/;
 
 // Tokens
 EmptyTable                        : Token;
@@ -23,5 +15,4 @@ RobotIsIdle                       : Token;
 RobotIsNotIdle                    : Token; // TODO negated RobotIsIdle
 RobotHasItemAttached              : Token;
 RobotHasNoItemAttached            : Token; // TODO negated RobotHasItemAttached
-Wait/*requires time*/             : Token; // artificial token, which parsing takes a specified amount of time
 RightPlace/*requires object*/     : Token ::= <Place:String>;
diff --git a/src/main/jastadd/cleanup/RobotWorld.jadd b/src/main/jastadd/cleanup/RobotWorld.jadd
index e2625a2..edadbe3 100644
--- a/src/main/jastadd/cleanup/RobotWorld.jadd
+++ b/src/main/jastadd/cleanup/RobotWorld.jadd
@@ -37,7 +37,6 @@ aspect RobotWorld {
   public static TokenType RobotIsNotIdle.type()             { return TokenType.of("ROBOT_IS_NOT_IDLE"); }
   public static TokenType RobotHasItemAttached.type()       { return TokenType.of("ROBOT_HAS_ITEM_ATTACHED"); }
   public static TokenType RobotHasNoItemAttached.type()     { return TokenType.of("ROBOT_HAS_NO_ITEM_ATTACHED"); }
-  public static TokenType Wait.type()                       { return TokenType.of("WAIT"); }
   public static TokenType RightPlace.type()                 { return TokenType.of("RIGHT_PLACE"); }
 
   public static Pose Pose.of(double x, double y, double z) {
@@ -217,15 +216,6 @@ aspect RobotWorld {
     }
   }
 
-  public Wait World.parseWait(double time) {
-    return null;
-  }
-  public Wait RobotWorld.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) {
     return null;
   }
diff --git a/src/main/jastadd/cleanup/SemanticActions.jadd b/src/main/jastadd/cleanup/SemanticActions.jadd
index bbb808d..0de4551 100644
--- a/src/main/jastadd/cleanup/SemanticActions.jadd
+++ b/src/main/jastadd/cleanup/SemanticActions.jadd
@@ -73,14 +73,4 @@ aspect SemanticActions {
         }
     }
 
-    public void Wait.action(World world) {
-        RobotWorld container = world.asRobotWorld();
-        System.out.println("performing semantic action for element Wait");
-        try {
-            Thread.sleep((long) (time() * 1000));
-        } catch (InterruptedException e) {
-            // ignore
-        }
-    }
-
 }
diff --git a/src/main/jastadd/select/Select.relast b/src/main/jastadd/select/Select.relast
new file mode 100644
index 0000000..7600879
--- /dev/null
+++ b/src/main/jastadd/select/Select.relast
@@ -0,0 +1,9 @@
+Task : MotionGrammarElement ::= Assignment;
+Assignment : MotionGrammarElement ::= Selection/*any type, any id*/ RestAssignment;
+abstract RestAssignment : MotionGrammarElement;
+SelectionChange : RestAssignment ::= Selection/*type == last type, id  != last id*/ ObjectAssignment;
+Unselect : RestAssignment ::= Selection/*type == last type, id  == last id*/ Assignment;
+CompleteAssignment : RestAssignment ::= Selection/*type != last type, id != last id*/;
+
+// Tokens
+Selection : Token;
\ No newline at end of file
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 b59cf42..8cbe2fc 100644
--- a/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
+++ b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
@@ -48,7 +48,7 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
     printAST("parseEmptyTable", result);
   }
 
-  private NotEmptyTable peekedNotEmptyTable_ = null;
+  private volatile NotEmptyTable peekedNotEmptyTable_ = null;
 
   private boolean peekNotEmptyTable() {
     peekedNotEmptyTable_ = getWorld().parseNotEmptyTable();
@@ -318,21 +318,6 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
     printAST("parseRobotHasNoItemAttached", result);
   }
 
-  private void parseWait(ASTNode<?> parent, int index) throws ParseException {
-    Wait result;
-
-    result = getWorld().parseWait(parent.time());
-    if (result == null) {
-      throw new ParseException(Wait.type());
-    }
-
-    parent.setChild(result, index);
-
-    // semantic action for Wait
-    result.action(getWorld());
-    printAST("parseWait", result);
-  }
-
   private void parseRightPlace(ASTNode<?> parent, int index) throws ParseException {
     RightPlace result;
 
@@ -353,16 +338,11 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
     result.parser = this;
     parent.setChild(result, index);
 
-    while (true) {
-      peekEmptyTable();
-      if (peekedEmptyTable_ != null) {
-        int i = result.getNumWaitForFullTable();
-        result.addWaitForFullTable(null);
-        parseWaitForFullTable(result.getWaitForFullTableList(), i);
-      } else {
-        break;
-      }
+    peekNotEmptyTable();
+    while (peekedNotEmptyTable_ == null) {
+      waitSomeTime();
     }
+    parseNotEmptyTable(result, 0);
 
     while (true) {
       peekObjectAtWrongPlace(result);
@@ -371,22 +351,16 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
         result.addMoveObjectToCorrectPlace(null);
         parseMoveObjectToCorrectPlace(result.getMoveObjectToCorrectPlaceList(), i);
       } else {
-        break;
+        peekEmptyTable();
+        if (peekedEmptyTable_ != null) {
+          break;
+        } else {
+          waitSomeTime();
+        }
       }
     }
 
-    while (true) {
-      peekNotEmptyTable();
-      if (peekedNotEmptyTable_ != null) {
-        int i = result.getNumWaitForEmptyTable();
-        result.addWaitForEmptyTable(null);
-        parseWaitForEmptyTable(result.getWaitForEmptyTableList(), i);
-      } else {
-        break;
-      }
-    }
-
-    parseEmptyTable(result, 3);
+    parseEmptyTable(result, 2);
 
     // semantic action for Tidy
     result.action(getWorld());
@@ -407,38 +381,18 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
     printAST("parseMoveObjectToCorrectPlace", result);
   }
 
-  private void parseWaitForFullTable(ASTNode<?> parent, int index) throws ParseException {
-    WaitForFullTable result = new WaitForFullTable();
-    result.parser = this;
-    parent.setChild(result, index);
-
-    parseEmptyTable(result, 0);
-    parseWait(result, 1);
-
-    // semantic action for WaitForFullTable
-    result.action(getWorld());
-    printAST("parseWaitForFullTable", result);
-  }
-
-  private void parseWaitForEmptyTable(ASTNode<?> parent, int index) throws ParseException {
-    WaitForEmptyTable result = new WaitForEmptyTable();
-    result.parser = this;
-    parent.setChild(result, index);
-
-    parseNotEmptyTable(result, 0);
-    parseWait(result, 1);
-
-    // semantic action for WaitForEmptyTable
-    result.action(getWorld());
-    printAST("parseWaitForEmptyTable", result);
-  }
-
   private void parseDropObjectAtRightPlace(ASTNode<?> parent, int index) throws ParseException {
     DropObjectAtRightPlace result = new DropObjectAtRightPlace();
     result.parser = this;
     parent.setChild(result, index);
 
-    parseRobotIsReadyToDrop(result, 0);
+
+    peekRobotIsReadyToDropToken();
+    while (peekedRobotIsReadyToDropToken_ == null) {
+      waitSomeTime();
+    }
+    parseRobotIsReadyToDropToken(result, 0);
+
     parseRightPlace(result, 1);
 
     // semantic action for DropObjectAtRightPlace
@@ -451,103 +405,15 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
     result.parser = this;
     parent.setChild(result, index);
 
-    parseRobotIsReadyToPick(result, 0);
-
-    // semantic action for PickUpObject
-    result.action(getWorld());
-    printAST("parsePickUpObject", result);
-  }
-
-  private void parseRobotIsReadyToPick(ASTNode<?> parent, int index) throws ParseException {
-    RobotIsReadyToPick result;
-
-    // try the different types of RobotIsReadyToPick
-    if (peekRobotIsReadyToPickToken()) {
-      result = new RobotIsReallyReadyToPick();
-      result.parser = this;
-      parent.setChild(result, index);
-      parseRobotIsReallyReadyToPick(parent, index);
-    } else if (peekRobotIsNotReadyToPickToken()) {
-      result = new RobotIsNotReadyToPick();
-      result.parser = this;
-      parent.setChild(result, index);
-      parseRobotIsNotReadyToPick(parent, index);
-    } else {
-      throw new ParseException("RobotIsReadyToPick", RobotIsReadyToPickToken.type(), RobotIsNotReadyToPickToken.type());
+    peekRobotIsReadyToPickToken();
+    while (peekedRobotIsReadyToPickToken_ == null) {
+      waitSomeTime();
     }
-
-
-    // semantic action for RobotIsReadyToPick
-    result.action(getWorld());
-    printAST("parseRobotIsReadyToPick", result);
-  }
-
-  private void parseRobotIsReallyReadyToPick(ASTNode<?> parent, int index) throws ParseException {
-    RobotIsReallyReadyToPick result = (RobotIsReallyReadyToPick) parent.getChild(index);
-
     parseRobotIsReadyToPickToken(result, 0);
 
-    // semantic action for RobotIsReallyReadyToPick
-    result.action(getWorld());
-    printAST("parseRobotIsReallyReadyToPick", result);
-  }
-
-  private void parseRobotIsNotReadyToPick(ASTNode<?> parent, int index) throws ParseException {
-    RobotIsNotReadyToPick result = (RobotIsNotReadyToPick) parent.getChild(index);
-
-    parseRobotIsNotReadyToPickToken(result, 0);
-    parseWait(result, 1);
-    parseRobotIsReadyToPick(result, 2);
-
-    // semantic action for RobotIsNotReadyToPick
-    result.action(getWorld());
-    printAST("parseRobotIsNotReadyToPick", result);
-  }
-
-  private void parseRobotIsReadyToDrop(ASTNode<?> parent, int index) throws ParseException {
-    RobotIsReadyToDrop result;
-
-    // try the different types of RobotIsReadyToDrop
-    if (peekRobotIsReadyToDropToken()) {
-      result = new RobotIsReallyReadyToDrop();
-      result.parser = this;
-      parent.setChild(result, index);
-      parseRobotIsReallyReadyToDrop(parent, index);
-    } else if (peekRobotIsNotReadyToDropToken()) {
-      result = new RobotIsNotReadyToDrop();
-      result.parser = this;
-      parent.setChild(result, index);
-      parseRobotIsNotReadyToDrop(parent, index);
-    } else {
-      throw new ParseException("RobotIsReadyToDrop", RobotIsReadyToDropToken.type(), RobotIsNotReadyToDropToken.type());
-    }
-
-
-    // semantic action for RobotIsReadyToDrop
-    result.action(getWorld());
-    printAST("parseRobotIsReadyToDrop", result);
-  }
-
-  private void parseRobotIsReallyReadyToDrop(ASTNode<?> parent, int index) throws ParseException {
-    RobotIsReallyReadyToDrop result = (RobotIsReallyReadyToDrop) parent.getChild(index);
-
-    parseRobotIsReadyToDropToken(result, 0);
-
-    // semantic action for RobotIsReallyReadyToDrop
-    result.action(getWorld());
-    printAST("parseRobotIsReallyReadyToDrop", result);
-  }
-
-  private void parseRobotIsNotReadyToDrop(ASTNode<?> parent, int index) throws ParseException {
-    RobotIsNotReadyToDrop result = (RobotIsNotReadyToDrop) parent.getChild(index);
-
-    parseRobotIsNotReadyToDropToken(result, 0);
-    parseWait(result, 1);
-    parseRobotIsReadyToDrop(result, 2);
-
-    // semantic action for RobotIsNotReadyToDrop
+    // semantic action for PickUpObject
     result.action(getWorld());
-    printAST("parseRobotIsNotReadyToDrop", result);
+    printAST("parsePickUpObject", result);
   }
 
 }
diff --git a/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java b/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java
index 1f22d5f..1122a4a 100644
--- a/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java
+++ b/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java
@@ -20,6 +20,13 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> {
   protected ASTNode<T> rootContainer_;
   private int timeStep_;
 
+  protected static void waitSomeTime() {
+    try {
+      Thread.sleep(100/*ms*/);
+    } catch(InterruptedException ignored) {
+    }
+  }
+
   public void setDebugDiagramDir(Path p) {
     MotionGrammarConfig.astDiagramDir = p;
   }
diff --git a/src/main/resources/template-configs/ControlParser.yaml b/src/main/resources/template-configs/ControlParser.yaml
new file mode 100644
index 0000000..577841f
--- /dev/null
+++ b/src/main/resources/template-configs/ControlParser.yaml
@@ -0,0 +1,51 @@
+name: "ControlParser"
+package: "de.tudresden.inf.st.mg"
+genPackage: "de.tudresden.inf.st.mg.jastadd.model"
+targetType: "Task"
+
+tokenContext:
+  context: false            # default value
+  peek: true                # default value
+  worldParserArguments: [ ] # default value
+  tokens:
+    - name: "Bin"
+      peek: false
+    - name: "Box"
+      peek: false
+
+ruleContext:
+  constructObject: false # default value
+  peekForType: false     # default value
+  token: false           # default value
+  first: false           # default value
+  last: false            # default value
+  list: false            # default value
+  additionalArgs: ""     # default value
+  peekContext: ""        # default value
+  rules:
+    - ruleName: "T"
+      peekForType: true
+      types:
+        - type: "T2"
+          token: "Full"
+          first: true
+        - type: "T1"
+          token: "Load"
+          last: true
+      components: []
+    - ruleName: "T1"
+      components:
+        - componentName: "Load"
+          token: true
+          index: 0
+        - componentName: "T"
+          token: true
+          index: 1
+        - componentName: "Unload"
+          token: true
+          index: 2
+    - ruleName: "T2"
+      components:
+        - componentName: "Full"
+          token: true
+          index: 0
-- 
GitLab