Skip to content
Snippets Groups Projects
Commit 7efd54ca authored by Johannes Mey's avatar Johannes Mey
Browse files

generate parsers from template

parent 930d1bdd
No related branches found
No related tags found
1 merge request!1festival updatesfestival updatesfestival updatesfestival updatesfestival
Pipeline #14518 passed
...@@ -4,15 +4,10 @@ import de.tudresden.inf.st.mg.common.MotionGrammarParser; ...@@ -4,15 +4,10 @@ import de.tudresden.inf.st.mg.common.MotionGrammarParser;
import de.tudresden.inf.st.mg.jastadd.model.*; import de.tudresden.inf.st.mg.jastadd.model.*;
public final class LoadWorldParser extends MotionGrammarParser<T> { public final class LoadWorldParser extends MotionGrammarParser<T> {
private static final String WORLD = "World"; private static final String WORLD = "World";
private Load peekedLoad_ = null;
private Unload peekedUnload_ = null;
private Full peekedFull_ = null;
public LoadWorldParser(World world) { public LoadWorldParser(World world) {
contexts_.put(WORLD, world); contexts_.put(WORLD, world);
} }
...@@ -23,49 +18,10 @@ public final class LoadWorldParser extends MotionGrammarParser<T> { ...@@ -23,49 +18,10 @@ public final class LoadWorldParser extends MotionGrammarParser<T> {
@Override @Override
protected void parse(ASTNode<?> parent, int index) throws ParseException { protected void parse(ASTNode<?> parent, int index) throws ParseException {
T result; parseT(parent, index);
// try to parse a T
if (peekFull()) {
result = new T2();
result.parser = this;
parent.setChild(result, index);
parseT2(parent, index);
} else if (peekLoad()) {
result = new T1();
result.parser = this;
parent.setChild(result, index);
parseT1(parent, index);
} else {
throw new ParseException("T", Load.type(), Full.type());
}
// semantic action for T
result.action(getWorld());
printAST("parseT", result);
} }
private void parseT1(ASTNode<?> parent, int index) throws ParseException { private Load peekedLoad_ = null;
T1 result = (T1) parent.getChild(index);
parseLoad(result, 0);
parse(result, 1);
parseUnload(result, 2);
// semantic action for T1
result.action(getWorld());
printAST("parseT1", result);
}
private void parseT2(ASTNode<?> parent, int index) throws ParseException {
T2 result = (T2) parent.getChild(index);
parseFull(result, 0);
// semantic action for T2
result.action(getWorld());
printAST("parseT2", result);
}
private boolean peekLoad() { private boolean peekLoad() {
peekedLoad_ = getWorld().parseLoad(); peekedLoad_ = getWorld().parseLoad();
...@@ -87,11 +43,13 @@ public final class LoadWorldParser extends MotionGrammarParser<T> { ...@@ -87,11 +43,13 @@ public final class LoadWorldParser extends MotionGrammarParser<T> {
parent.setChild(result, index); parent.setChild(result, index);
// semantic action for Unload // semantic action for Load
result.action(getWorld()); result.action(getWorld());
printAST("parseLoad", result); printAST("parseLoad", result);
} }
private Unload peekedUnload_ = null;
private boolean peekUnload() { private boolean peekUnload() {
peekedUnload_ = getWorld().parseUnload(); peekedUnload_ = getWorld().parseUnload();
return peekedUnload_ != null; return peekedUnload_ != null;
...@@ -117,12 +75,14 @@ public final class LoadWorldParser extends MotionGrammarParser<T> { ...@@ -117,12 +75,14 @@ public final class LoadWorldParser extends MotionGrammarParser<T> {
printAST("parseUnload", result); printAST("parseUnload", result);
} }
private Full peekedFull_ = null;
private boolean peekFull() { private boolean peekFull() {
peekedFull_ = getWorld().parseFull(); peekedFull_ = getWorld().parseFull();
return peekedFull_ != null; return peekedFull_ != null;
} }
void parseFull(ASTNode<?> parent, int index) throws ParseException { private void parseFull(ASTNode<?> parent, int index) throws ParseException {
Full result; Full result;
if (peekedFull_ != null) { if (peekedFull_ != null) {
...@@ -137,8 +97,55 @@ public final class LoadWorldParser extends MotionGrammarParser<T> { ...@@ -137,8 +97,55 @@ public final class LoadWorldParser extends MotionGrammarParser<T> {
parent.setChild(result, index); parent.setChild(result, index);
// semantic action for Unload // semantic action for Full
result.action(getWorld()); result.action(getWorld());
printAST("parseFull", result); printAST("parseFull", result);
} }
private void parseT(ASTNode<?> parent, int index) throws ParseException {
T result;
// try the different types of T
if (peekFull()) {
result = new T2();
result.parser = this;
parent.setChild(result, index);
parseT2(parent, index);
} else if (peekLoad()) {
result = new T1();
result.parser = this;
parent.setChild(result, index);
parseT1(parent, index);
} else {
throw new ParseException("T", Full.type(), Load.type());
}
// semantic action for T
result.action(getWorld());
printAST("parseT", result);
}
private void parseT1(ASTNode<?> parent, int index) throws ParseException {
T1 result = (T1) parent.getChild(index);
parseLoad(result, 0);
parseT(result, 1);
parseUnload(result, 2);
// semantic action for T1
result.action(getWorld());
printAST("parseT1", result);
}
private void parseT2(ASTNode<?> parent, int index) throws ParseException {
T2 result = (T2) parent.getChild(index);
parseFull(result, 0);
// semantic action for T2
result.action(getWorld());
printAST("parseT2", result);
}
} }
...@@ -3,20 +3,15 @@ package de.tudresden.inf.st.mg; ...@@ -3,20 +3,15 @@ package de.tudresden.inf.st.mg;
import de.tudresden.inf.st.mg.common.MotionGrammarConfig; import de.tudresden.inf.st.mg.common.MotionGrammarConfig;
import de.tudresden.inf.st.mg.common.MotionGrammarParser; import de.tudresden.inf.st.mg.common.MotionGrammarParser;
import de.tudresden.inf.st.mg.jastadd.model.RobotWorld; import de.tudresden.inf.st.mg.jastadd.model.RobotWorld;
import de.tudresden.inf.st.mg.jastadd.model.Tidy;
import de.tudresden.inf.st.mg.jastadd.model.World;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Comparator;
import java.util.Random;
public class Main { public class Main {
public static final Path TIDY_AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing", "tidy"); public static final Path TIDY_AST_DIAGRAM_DIR = Path.of("src", "gen", "resources", "diagrams", "parsing", "tidy");
/** /**
* Runs the parser on the actual robot. For this to work, a robot controller must be connected to an MQTT server running * Runs the parser on the actual robot. For this to work, a robot controller must be connected to an MQTT server running
* on localhost:1883 * on localhost:1883
...@@ -67,7 +62,7 @@ public class Main { ...@@ -67,7 +62,7 @@ public class Main {
} }
try { try {
Thread.sleep(100000*1000); Thread.sleep(100000 * 1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
This diff is collapsed.
package de.tudresden.inf.st.mg.common; package de.tudresden.inf.st.mg.common;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.tudresden.inf.st.mg.common.DiagramProvider.AST;
import io.javalin.Javalin; import io.javalin.Javalin;
import io.javalin.http.ContentType;
import io.javalin.websocket.WsContext; import io.javalin.websocket.WsContext;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
...@@ -22,7 +16,7 @@ public class DiagramProvider { ...@@ -22,7 +16,7 @@ public class DiagramProvider {
private static DiagramProvider INSTANCE; private static DiagramProvider INSTANCE;
private static Map<WsContext, String> clients = new ConcurrentHashMap<>(); private static final Map<WsContext, String> clients = new ConcurrentHashMap<>();
public static DiagramProvider getInstance() { public static DiagramProvider getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
...@@ -31,7 +25,7 @@ public class DiagramProvider { ...@@ -31,7 +25,7 @@ public class DiagramProvider {
return INSTANCE; return INSTANCE;
} }
private List<AST> asts; private final List<AST> asts;
private DiagramProvider() { private DiagramProvider() {
asts = new ArrayList<>(); asts = new ArrayList<>();
...@@ -45,7 +39,7 @@ public class DiagramProvider { ...@@ -45,7 +39,7 @@ public class DiagramProvider {
app.ws("ast-events", ws -> { app.ws("ast-events", ws -> {
ws.onConnect(ctx -> { ws.onConnect(ctx -> {
System.err.println("somebody connected " +ctx.host()); System.err.println("somebody connected " + ctx.host());
clients.put(ctx, ctx.host()); clients.put(ctx, ctx.host());
}); });
ws.onClose(ctx -> { ws.onClose(ctx -> {
...@@ -64,7 +58,7 @@ public class DiagramProvider { ...@@ -64,7 +58,7 @@ public class DiagramProvider {
asts.add(new AST(timestamp, step, parseRule, Files.readString(diagramPath))); asts.add(new AST(timestamp, step, parseRule, Files.readString(diagramPath)));
clients.keySet().forEach(session -> { clients.keySet().forEach(session -> {
System.err.println("sending"); System.err.println("sending");
session.send(asts.get(asts.size()-1)); session.send(asts.get(asts.size() - 1));
}); });
} catch (IOException e) { } catch (IOException e) {
System.err.println("Unable to read AST diagram file " + diagramPath); System.err.println("Unable to read AST diagram file " + diagramPath);
......
name: "LoadWorldParser"
package: "de.tudresden.inf.st.mg"
genPackage: "de.tudresden.inf.st.mg.jastadd.model"
targetType: "T"
tokenContext:
context: false # default value
peek: true # default value
worldParserArguments: [ ] # default value
tokens:
- name: "Load"
- name: "Unload"
- name: "Full"
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
name: "RobotParser"
package: "de.tudresden.inf.st.mg"
genPackage: "de.tudresden.inf.st.mg.jastadd.model"
targetType: "Tidy"
tokenContext:
context: false # default value
peek: true # default value
worldParserArguments: [ ] # default value
tokens:
- name: "EmptyTable"
- name: "NotEmptyTable"
- name: "ObjectAtWrongPlace"
context: "Tidy"
- name: "RobotIsReadyToPickToken"
- name: "RobotIsNotReadyToPickToken"
- name: "RobotIsReadyToDropToken"
- name: "RobotIsNotReadyToDropToken"
- name: "RobotIsIdle"
- name: "RobotIsNotIdle"
- name: "RobotHasItemAttached"
- name: "RobotHasNoItemAttached"
- name: "Wait"
worldParserArguments:
- argument: "time()"
peek: false
- name: "RightPlace"
worldParserArguments:
- argument: "object()"
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: "Tidy"
constructObject: true
components:
- componentName: "WaitForFullTable"
list: true
peekToken: "EmptyTable"
- componentName: "MoveObjectToCorrectPlace"
list: true
peekToken: "ObjectAtWrongPlace"
peekContext: "result"
- componentName: "WaitForEmptyTable"
list: true
peekToken: "NotEmptyTable"
- componentName: "EmptyTable"
index: 3
- ruleName: "MoveObjectToCorrectPlace"
constructObject: true
components:
- componentName: "ObjectAtWrongPlace"
token: true
index: 0
additionalArgs: ", parent.containingTidy()"
- componentName: "PickUpObject"
index: 1
- componentName: "DropObjectAtRightPlace"
index: 2
- ruleName: "WaitForFullTable"
constructObject: true
components:
- componentName: "EmptyTable"
token: true
index: 0
- componentName: "Wait"
token: true
index: 1
- ruleName: "WaitForEmptyTable"
constructObject: true
components:
- componentName: "NotEmptyTable"
token: true
index: 0
- componentName: "Wait"
token: true
index: 1
- ruleName: "DropObjectAtRightPlace"
constructObject: true
components:
- componentName: "RobotIsReadyToDrop"
index: 0
- componentName: "RightPlace"
token: true
index: 1
- ruleName: "PickUpObject"
constructObject: true
components:
- componentName: "RobotIsReadyToPick"
index: 0
- ruleName: "RobotIsReadyToPick"
peekForType: true
types:
- type: "RobotIsReallyReadyToPick"
token: "RobotIsReadyToPickToken"
first: true
- type: "RobotIsNotReadyToPick"
token: "RobotIsNotReadyToPickToken"
last: true
components: []
- ruleName: "RobotIsReallyReadyToPick"
components:
- componentName: "RobotIsReadyToPickToken"
token: true
index: 0
- ruleName: "RobotIsNotReadyToPick"
components:
- componentName: "RobotIsNotReadyToPickToken"
token: true
index: 0
- componentName: "Wait"
token: true
index: 1
- componentName: "RobotIsReadyToPick"
index: 2
- ruleName: "RobotIsReadyToDrop"
peekForType: true
types:
- type: "RobotIsReallyReadyToDrop"
token: "RobotIsReadyToDropToken"
first: true
- type: "RobotIsNotReadyToDrop"
token: "RobotIsNotReadyToDropToken"
last: true
components: []
- ruleName: "RobotIsReallyReadyToDrop"
components:
- componentName: "RobotIsReadyToDropToken"
token: true
index: 0
- ruleName: "RobotIsNotReadyToDrop"
components:
- componentName: "RobotIsNotReadyToDropToken"
token: true
index: 0
- componentName: "Wait"
token: true
index: 1
- componentName: "RobotIsReadyToDrop"
index: 2
package {{{package}}};
import de.tudresden.inf.st.mg.common.MotionGrammarParser;
import {{{genPackage}}}.*;
public final class {{{name}}} extends MotionGrammarParser<{{{targetType}}}> {
private static final String WORLD = "World";
public {{{name}}}(World world) {
contexts_.put(WORLD, world);
}
private World getWorld() {
return (World) contexts_.get(WORLD);
}
@Override
protected void parse(ASTNode<?> parent, int index) throws ParseException {
parse{{{targetType}}}(parent, index);
}
{{#tokenContext}}
{{#tokens}}
{{#peek}}
private {{{name}}} peeked{{{name}}}_ = null;
private boolean peek{{{name}}}({{#context}}{{{context}}} context{{/context}}) {
peeked{{{name}}}_ = getWorld().parse{{{name}}}({{#context}}context{{/context}}{{#worldParserArguments}}parent.{{{argument}}}{{/worldParserArguments}});
return peeked{{{name}}}_ != null;
}
{{/peek}}
private void parse{{{name}}}(ASTNode<?> parent, int index{{#context}}, {{{context}}} context{{/context}}) throws ParseException {
{{{name}}} result;
{{#peek}}
if (peeked{{{name}}}_ != null) {
result = peeked{{{name}}}_;
peeked{{{name}}}_ = null; // TODO check if all peeked values are actually parsed afterwards
} else {
result = getWorld().parse{{{name}}}({{#context}}context{{/context}}{{#worldParserArguments}}parent.{{{argument}}}{{/worldParserArguments}});
if (result == null) {
throw new ParseException({{{name}}}.type());
}
}
{{/peek}}
{{^peek}}
result = getWorld().parse{{{name}}}({{#context}}context{{/context}}{{#worldParserArguments}}parent.{{{argument}}}{{/worldParserArguments}});
if (result == null) {
throw new ParseException({{{name}}}.type());
}
{{/peek}}
parent.setChild(result, index);
// semantic action for {{{name}}}
result.action(getWorld());
printAST("parse{{{name}}}", result);
}
{{/tokens}}
{{/tokenContext}}
{{#ruleContext}}
{{#rules}}
private void parse{{{ruleName}}}(ASTNode<?> parent, int index) throws ParseException {
{{#constructObject}}
{{{ruleName}}} result = new {{{ruleName}}}();
result.parser = this;
parent.setChild(result, index);
{{/constructObject}}
{{^constructObject}}
{{#peekForType}}
{{{ruleName}}} result;
// try the different types of {{{ruleName}}}
{{#types}}
{{#first}}
if (peek{{{token}}}()) {
{{/first}}
{{^first}}
} else if (peek{{{token}}}()) {
{{/first}}
result = new {{{type}}}();
result.parser = this;
parent.setChild(result, index);
parse{{{type}}}(parent, index);
{{#last}}
} else {
throw new ParseException("{{{ruleName}}}"{{#types}}, {{{token}}}.type(){{/types}});
}
{{/last}}
{{/types}}
{{/peekForType}}
{{^peekForType}}
{{{ruleName}}} result = ({{{ruleName}}}) parent.getChild(index);
{{/peekForType}}
{{/constructObject}}
{{#components}}
{{#list}}
while (true) {
peek{{{peekToken}}}({{{peekContext}}});
if (peeked{{{peekToken}}}_ != null) {
int i = result.getNum{{{componentName}}}();
result.add{{{componentName}}}(null);
parse{{{componentName}}}(result.get{{{componentName}}}List(), i);
} else {
break;
}
}
{{/list}}
{{^list}}
parse{{{componentName}}}(result, {{{index}}}{{{additionalArgs}}});
{{/list}}
{{/components}}
// semantic action for {{{ruleName}}}
result.action(getWorld());
printAST("parse{{{ruleName}}}", result);
}
{{/rules}}
{{/ruleContext}}
}
package de.tudresden.inf.st.mg; package de.tudresden.inf.st.mg;
import de.tudresden.inf.st.mg.common.MotionGrammarConfig;
import de.tudresden.inf.st.mg.common.MotionGrammarParser; import de.tudresden.inf.st.mg.common.MotionGrammarParser;
import de.tudresden.inf.st.mg.jastadd.model.*; import de.tudresden.inf.st.mg.jastadd.model.Container;
import de.tudresden.inf.st.mg.jastadd.model.RobotWorld;
import de.tudresden.inf.st.mg.jastadd.model.T1;
import de.tudresden.inf.st.mg.jastadd.model.Tidy;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Comparator; import java.util.Comparator;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
...@@ -69,12 +68,4 @@ public class ParserTest { ...@@ -69,12 +68,4 @@ public class ParserTest {
assertThat(result).isNotNull().isInstanceOf(Tidy.class); assertThat(result).isNotNull().isInstanceOf(Tidy.class);
} }
@Test
@Disabled
void runRealTidyParser() throws MotionGrammarParser.ParseException {
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment