diff --git a/trainbenchmark/trainbenchmark-generator-relast/.editorconfig b/trainbenchmark/trainbenchmark-generator-relast/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..39bb2e3acab079d09cca4ccca554ab8f7e90c408
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-generator-relast/.editorconfig
@@ -0,0 +1,10 @@
+root = true
+
+[*.java]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+max_line_length = 140
+trim_trailing_whitespace = true
\ No newline at end of file
diff --git a/trainbenchmark/trainbenchmark-generator-relast/build.gradle b/trainbenchmark/trainbenchmark-generator-relast/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..b32ce8a4848c2ceece863a7a56b9df28d64cc0e4
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-generator-relast/build.gradle
@@ -0,0 +1,17 @@
+plugins {
+  id "com.github.johnrengelman.shadow" version "1.2.3"
+}
+
+shadowJar {
+  classifier = 'fat'
+  manifest {
+    attributes 'Main-Class': 'de.tudresden.inf.st.trainbenchmark.generator.relast.RelASTGeneratorMain'
+  }
+}
+
+dependencies {
+  compile project(':trainbenchmark-tool')
+  compile project(':trainbenchmark-generator')
+  compile project(':trainbenchmark-tool-jastadd-relast')
+  compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8.1'
+}
diff --git a/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/RelASTGeneratorMain.java b/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/RelASTGeneratorMain.java
new file mode 100644
index 0000000000000000000000000000000000000000..476e780020e8dc18647bfacb26121784f60bebf6
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/RelASTGeneratorMain.java
@@ -0,0 +1,15 @@
+package de.tudresden.inf.st.trainbenchmark.generator.relast;
+
+import de.tudresden.inf.st.trainbenchmark.generator.relast.config.RelASTGeneratorConfig;
+import hu.bme.mit.trainbenchmark.generator.ModelGenerator;
+import hu.bme.mit.trainbenchmark.generator.ScalableGeneratorFactory;
+import hu.bme.mit.trainbenchmark.generator.config.GeneratorConfig;
+
+public class RelASTGeneratorMain {
+  public static void main(String[] args) throws Exception {
+    final RelASTGeneratorConfig gc = GeneratorConfig.fromFile(args[0], RelASTGeneratorConfig.class);
+    final RelASTSerializer serializer = new RelASTSerializer(gc);
+    final ModelGenerator generator = ScalableGeneratorFactory.createGenerator(serializer, gc);
+    generator.generateModel();
+  }
+}
diff --git a/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/RelASTSerializer.java b/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/RelASTSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..56608affc0ae924af87cf3777e2d1b0bff408441
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/RelASTSerializer.java
@@ -0,0 +1,171 @@
+package de.tudresden.inf.st.trainbenchmark.generator.relast;
+
+import de.tudresden.inf.st.train.jastadd.ast.*;
+import de.tudresden.inf.st.trainbenchmark.generator.relast.config.RelASTGeneratorConfig;
+import hu.bme.mit.trainbenchmark.generator.ModelSerializer;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+import static hu.bme.mit.trainbenchmark.constants.ModelConstants.*;
+
+public class RelASTSerializer extends ModelSerializer<RelASTGeneratorConfig> {
+
+  private RailwayContainer container;
+
+  RelASTSerializer(final RelASTGeneratorConfig generatorConfig) {
+    super(generatorConfig);
+  }
+
+  @Override
+  public String syntax() {
+    return "RELAST";
+  }
+
+  @Override
+  public void initModel() {
+    container = new RailwayContainer();
+  }
+
+  @Override
+  public void persistModel() throws IOException {
+    String jsonPath = gc.getConfigBase().getModelPathWithoutExtension() + "-relast.json";
+    System.out.println(jsonPath);
+    try {
+      container.resolveAll();
+      container.serialize(new File(jsonPath), true);
+    } catch (SerializationException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public ASTNode createVertex(
+    final int id,
+    final String type,
+    final Map<String, ?> attributes,
+    final Map<String, Object> outgoingEdges,
+    final Map<String, Object> incomingEdges) throws IOException {
+
+    switch (type) {
+      case REGION:
+        Region region = new Region();
+        region.setId(id);
+        container.addRegion(region);
+        return region;
+      case SEMAPHORE:
+        Semaphore semaphore = new Semaphore();
+        semaphore.setId(id);
+        if (attributes.get(SIGNAL) != null) {
+          semaphore.setSignal(Signal.valueOf(((hu.bme.mit.trainbenchmark.constants.Signal) attributes.get(SIGNAL)).name()));
+        }
+        return semaphore;
+      case ROUTE:
+        Route route = new Route();
+        route.setId(id);
+        if (attributes.get(ACTIVE) != null) {
+          route.setActive((Boolean) attributes.get(ACTIVE));
+        }
+        if (outgoingEdges.get(ENTRY) != null) {
+          route.setEntry((Semaphore) outgoingEdges.get(ENTRY));
+        }
+        if (outgoingEdges.get(EXIT) != null) {
+          route.setExit((Semaphore) outgoingEdges.get(EXIT));
+        }
+        container.addRoute(route);
+        return route;
+      case SWITCHPOSITION:
+        SwitchPosition switchPosition = new SwitchPosition();
+        switchPosition.setId(id);
+        if (attributes.get(POSITION) != null) {
+          switchPosition.setPosition(Position.valueOf(((hu.bme.mit.trainbenchmark.constants.Position) attributes.get(POSITION)).name()));
+        }
+        if (outgoingEdges.containsKey(TARGET)) {
+          switchPosition.setTarget((Switch) outgoingEdges.get(TARGET));
+        }
+        return switchPosition;
+      case SENSOR:
+        Sensor sensor = new Sensor();
+        sensor.setId(id);
+        return sensor;
+      case SEGMENT:
+        Segment segment = new Segment();
+        segment.setId(id);
+        if (attributes.get(LENGTH) != null) {
+          segment.setLength((Integer) attributes.get(LENGTH));
+        }
+        return segment;
+      case SWITCH:
+        Switch sw = new Switch();
+        sw.setId(id);
+        if (attributes.get(POSITION) != null) {
+          sw.setCurrentPosition(Position.valueOf(((hu.bme.mit.trainbenchmark.constants.Position) attributes.get(POSITION)).name()));
+        }
+        return sw;
+      default:
+        throw new IOException(String.format("Unknown type of vertex: %s", type));
+    }
+  }
+
+  @Override
+  public void createEdge(final String label, final Object from, final Object to) throws IOException {
+
+    switch (label) {
+      case MONITORED_BY: {
+        TrackElement trackElement = (TrackElement) from;
+        Sensor sensor = (Sensor) to;
+        trackElement.addToMonitoredBy(sensor);
+        break;
+      }
+      case REQUIRES: {
+        Route route = (Route) from;
+        Sensor sensor = (Sensor) to;
+        route.addToRequires(sensor);
+        break;
+      }
+      case CONNECTS_TO:
+        TrackElement from_track = (TrackElement) from;
+        TrackElement to_track = (TrackElement) to;
+        from_track.addToConnectsTo(to_track);
+        break;
+      case ELEMENTS: {
+        Region region = (Region) from;
+        TrackElement trackElement = (TrackElement) to;
+        region.addTrackElement(trackElement);
+        break;
+      }
+      case FOLLOWS: {
+        Route route = (Route) from;
+        SwitchPosition switchPosition = (SwitchPosition) to;
+        route.addSwitchPosition(switchPosition);
+        break;
+      }
+      case SEMAPHORES:
+        Segment segment = (Segment) from;
+        Semaphore semaphore = (Semaphore) to;
+        segment.addSemaphore(semaphore);
+        break;
+      case SENSORS: {
+        Region region = (Region) from;
+        Sensor sensor = (Sensor) to;
+        region.addSensor(sensor);
+        break;
+      }
+      default:
+        throw new IOException("An edge could not be created because '" + label + "' is an unknown label.");
+    }
+  }
+
+  @Override
+  public void setAttribute(final String type, final Object node, final String key, final Object value)
+    throws IOException {
+    if (key.equals(CURRENTPOSITION)) {
+      Switch sw = (Switch) node;
+      sw.setCurrentPosition(Position.valueOf(((hu.bme.mit.trainbenchmark.constants.Position) value).name()));
+    } else {
+      throw new IOException(String.format("SetAttribute. Unexpected key: %s", type));
+    }
+  }
+
+}
diff --git a/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/config/RelASTGeneratorConfig.java b/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/config/RelASTGeneratorConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..21c17b11e6c076b1d7e45e3c8b700772d611ca2c
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/config/RelASTGeneratorConfig.java
@@ -0,0 +1,17 @@
+package de.tudresden.inf.st.trainbenchmark.generator.relast.config;
+
+
+import hu.bme.mit.trainbenchmark.generator.config.GeneratorConfig;
+import hu.bme.mit.trainbenchmark.generator.config.GeneratorConfigBase;
+
+public class RelASTGeneratorConfig extends GeneratorConfig {
+
+  RelASTGeneratorConfig(final GeneratorConfigBase configBase) {
+    super(configBase);
+  }
+
+  @Override
+  public String getProjectName() {
+    return "relast";
+  }
+}
diff --git a/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/config/RelASTGeneratorConfigBuilder.java b/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/config/RelASTGeneratorConfigBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..94ec5cc83d732049c70391477cb879605bc12b73
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-generator-relast/src/main/java/de/tudresden/inf/st/trainbenchmark/generator/relast/config/RelASTGeneratorConfigBuilder.java
@@ -0,0 +1,13 @@
+package de.tudresden.inf.st.trainbenchmark.generator.relast.config;
+
+import hu.bme.mit.trainbenchmark.generator.config.GeneratorConfigBuilder;
+
+public class RelASTGeneratorConfigBuilder
+	extends GeneratorConfigBuilder<RelASTGeneratorConfig, RelASTGeneratorConfigBuilder> {
+
+	@Override
+	public RelASTGeneratorConfig createConfig() {
+		checkNotNulls();
+		return new RelASTGeneratorConfig(configBase);
+	}
+}