Skip to content
Snippets Groups Projects
Commit 73c9b6f2 authored by René Schöne's avatar René Schöne
Browse files

Polishing.

- Cleanup build.gradle files
- Add circular reachability analysis
- Rename jrag with SCC to ConnectedComponents.jrag
- Add some documentation to attributes in Navigation aspect
- Add links to documentation for lexer and parser
parent 6c4665ef
No related branches found
No related tags found
No related merge requests found
# See http://help.github.com/ignore-files/ for more about ignoring files. # See http://help.github.com/ignore-files/ for more about ignoring files.
/src/data/ !/src/data
/src/data/*
# compiled output # compiled output
/dist /dist
......
../../../statemachine.base/build/docs/ragdoc/
\ No newline at end of file
// General configuration (plugins, settings, dependencies)
group 'de.tudresden.inf.st' group 'de.tudresden.inf.st'
version '0.1' version '0.1'
...@@ -8,25 +9,24 @@ apply plugin: "idea" ...@@ -8,25 +9,24 @@ apply plugin: "idea"
sourceCompatibility = 1.8 sourceCompatibility = 1.8
repositories { repositories.mavenCentral()
mavenCentral()
}
idea { buildscript {
module { repositories.mavenLocal()
generatedSourceDirs += file('src/gen/java') repositories.mavenCentral()
dependencies {
classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3'
} }
} }
idea.module.generatedSourceDirs += file('src/gen/java')
configurations { configurations {
ragdoc ragdoc
} }
sourceSets { sourceSets.main.java.srcDir "src/gen/java"
main { jar.manifest.attributes('Main-Class': 'de.tudresden.inf.st.statemachine.Main')
java.srcDir "src/gen/java"
}
}
dependencies { dependencies {
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jackson_version}" implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jackson_version}"
...@@ -36,39 +36,17 @@ dependencies { ...@@ -36,39 +36,17 @@ dependencies {
ragdoc files('../libs/rd-builder.jar') ragdoc files('../libs/rd-builder.jar')
} }
// Default run configuration
run { run {
mainClassName = 'de.tudresden.inf.st.statemachine.Main' mainClassName = 'de.tudresden.inf.st.statemachine.Main'
standardInput = System.in standardInput = System.in
} }
buildscript { // Generated files
repositories.mavenLocal()
repositories.mavenCentral()
dependencies {
classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3'
}
}
jar {
manifest {
attributes(
'Main-Class': 'de.tudresden.inf.st.statemachine.Main'
)
}
}
def ecoreFile = "./src/main/resources/StateMachine.ecore" def ecoreFile = "./src/main/resources/StateMachine.ecore"
def relastFile = "./src/gen/jastadd/StateMachine.relast" def relastFile = "./src/gen/jastadd/StateMachine.relast"
String[] relastArguments = [
"../libs/relast.jar",
"--grammarName=./src/gen/jastadd/StateMachine",
"--useJastAddNames",
"--listClass=ArrayList",
"--jastAddList=JastAddList",
"--resolverHelper",
"--file"
]
// First phase: Ecore -> RelAst
task ecoreToRelast(type: JavaExec) { task ecoreToRelast(type: JavaExec) {
group = 'Build' group = 'Build'
main = "-jar" main = "-jar"
...@@ -85,16 +63,25 @@ task ecoreToRelast(type: JavaExec) { ...@@ -85,16 +63,25 @@ task ecoreToRelast(type: JavaExec) {
outputs.files file(relastFile) outputs.files file(relastFile)
} }
task preprocess(type: JavaExec) { // Second phase: RelAst -> JastAdd
task relastToJastAdd(type: JavaExec) {
group = 'Build' group = 'Build'
main = "-jar" main = "-jar"
args relastArguments + relastFile args "../libs/relast.jar",
"--grammarName=./src/gen/jastadd/StateMachine",
"--useJastAddNames",
"--listClass=ArrayList",
"--jastAddList=JastAddList",
"--resolverHelper",
"--file",
relastFile
inputs.files relastFile inputs.files relastFile
outputs.files file("./src/gen/jastadd/StateMachine.ast"), file("./src/gen/jastadd/StateMachine.jadd") outputs.files file("./src/gen/jastadd/StateMachine.ast"), file("./src/gen/jastadd/StateMachine.jadd")
} }
// Third phase: JastAdd -> Java (using JastAdd Gradle plugin)
jastadd { jastadd {
configureModuleBuild() configureModuleBuild()
modules { modules {
...@@ -144,11 +131,12 @@ jastadd { ...@@ -144,11 +131,12 @@ jastadd {
scanner.genDir = "src/gen/java/de/tudresden/inf/st/statemachine/jastadd/scanner" scanner.genDir = "src/gen/java/de/tudresden/inf/st/statemachine/jastadd/scanner"
parser.genDir = "src/gen/java/de/tudresden/inf/st/statemachine/jastadd/parser" parser.genDir = "src/gen/java/de/tudresden/inf/st/statemachine/jastadd/parser"
jastaddOptions = ['--List=JastAddList'] extraJastAddOptions = ['--List=JastAddList']
} }
preprocess.dependsOn ecoreToRelast // Workflow configuration for phases
generateAst.dependsOn preprocess relastToJastAdd.dependsOn ecoreToRelast
generateAst.dependsOn relastToJastAdd
//// always run jastadd //// always run jastadd
//jastadd.outputs.upToDateWhen {false} //jastadd.outputs.upToDateWhen {false}
aspect Analysis { aspect Analysis {
syn Set<State> State.reachableWithin(int n) { //circular [new HashSet<>()] syn Set<State> State.reachableWithin(int n) {
if (n == 0) { if (n == 0) {
return new HashSet<>(); return new HashSet<>();
} }
...@@ -11,8 +11,16 @@ aspect Analysis { ...@@ -11,8 +11,16 @@ aspect Analysis {
return result; return result;
} }
syn Set<State> State.reachable() circular [new HashSet<State>()] {
Set<State> result = new HashSet<>();
result.addAll(successors());
for (State s : successors()) {
result.addAll(s.reachable());
}
return result;
}
public void StateMachine.printSomeAnalysis() { public void StateMachine.printSomeAnalysis() {
// analysis
Set<Set<State>> sccs = this.SCC(); Set<Set<State>> sccs = this.SCC();
System.out.println("SCCs found:"); System.out.println("SCCs found:");
for (Set<State> scc : sccs) { for (Set<State> scc : sccs) {
...@@ -20,7 +28,7 @@ aspect Analysis { ...@@ -20,7 +28,7 @@ aspect Analysis {
} }
for (State s : this.states()) { for (State s : this.states()) {
System.out.println(s + ".successors() = " + s.successors()); System.out.println(s + ": successors() = " + s.successors() + ", reachable() = " + s.reachable());
} }
Set<State> current; Set<State> current;
......
aspect Reachability { aspect ConnectedComponents {
// syn Set<State> State.successors() circular [new HashSet<>()] { // syn Set<State> State.successors() circular [new HashSet<>()] {
// Set<State> result = new HashSet<>(); // Set<State> result = new HashSet<>();
// for (Transition t : getOutgoingList()) { // for (Transition t : getOutgoingList()) {
...@@ -30,54 +30,38 @@ aspect Reachability { ...@@ -30,54 +30,38 @@ aspect Reachability {
// coll HashSet<Set<State>> StateMachine.SCC() with add root StateMachine; // coll HashSet<Set<State>> StateMachine.SCC() with add root StateMachine;
// State contributes SCC() when SCC().size() > 0 to StateMachine.SCC(); // State contributes SCC() when SCC().size() > 0 to StateMachine.SCC();
/** /**
* Kosaraju's algorithm * Kosaraju's algorithm
*/ */
syn Set<Set<State>> StateMachine.SCC(){ syn Set<Set<State>> StateMachine.SCC() {
Map<State, Integer> visited = new HashMap<>(); Map<State, Set> visited = new HashMap<>();
Deque<State> locked = new LinkedList<>(); LinkedList<State> locked = new LinkedList<>();
for (State n : states())
if (!visited.containsKey(n))
n.visit(visited, locked); // forward search
// visit nodes forward for (State n : locked)
for (Element e : getElementList()){ if (visited.get(n) == null)
if (e.isState()){ n.assign(visited, new HashSet()); // backward search
State n=e.asState();
n.visit(visited, locked);
}
}
// assign nodes to SCCs backward
int scc = 0;
for (State n : locked) {
n.assign(visited, scc);
scc++;
}
Map<Integer, Set<State>> result = visited.entrySet().stream().collect( return new HashSet(visited.values());
Collectors.groupingBy(
e -> e.getValue(),
Collectors.mapping(e -> e.getKey(), Collectors.toSet())
)
);
return result.values().stream().collect(Collectors.toSet());
} }
void State.visit(Map<State, Integer> visited, Deque<State> locked) { void State.visit(Map<State, Set> visited, LinkedList<State> locked) {
if (visited.containsKey(this)) return; visited.put(this, null);
visited.put(this, -1); for (Transition t : getOutgoingList())
for (Transition t : getOutgoingList()) { if (!visited.containsKey(t.getTo()))
State s = t.getTo(); t.getTo().visit(visited, locked);
s.visit(visited, locked);
}
locked.addFirst(this); locked.addFirst(this);
} }
void State.assign(Map<State, Integer> visited, int root) { void State.assign(Map<State, Set> visited, Set root) {
if (visited.get(this) > -1) return; root.add(this);
visited.put(this, root); visited.put(this, root);
for (Transition t : getIncomingList()) { for (Transition t : getIncomingList())
State p = t.getFrom(); if (visited.get(t.getFrom()) == null)
p.assign(visited, root); t.getFrom().assign(visited, root);
}
} }
} }
aspect Navigation { aspect Navigation {
/** Check, whether an this element is a state */
syn boolean Element.isState() = false; syn boolean Element.isState() = false;
eq State.isState() = true; eq State.isState() = true;
/** View this element as a state */
syn State Element.asState() = null; syn State Element.asState() = null;
eq State.asState() = this; eq State.asState() = this;
/** Check, whether an this element is a transition */
syn boolean Element.isTransition() = false; syn boolean Element.isTransition() = false;
eq Transition.isTransition() = true; eq Transition.isTransition() = true;
/** View this element as a transition */
syn Transition Element.asTransition() = null; syn Transition Element.asTransition() = null;
eq Transition.asTransition() = this; eq Transition.asTransition() = this;
/** Get all states */
syn List<State> StateMachine.states() { syn List<State> StateMachine.states() {
List<State> states = new ArrayList<>(); List<State> states = new ArrayList<>();
for (Element element: getElementList()) { for (Element element: getElementList()) {
......
...@@ -4,6 +4,7 @@ package de.tudresden.inf.st.statemachine.jastadd.parser; ...@@ -4,6 +4,7 @@ package de.tudresden.inf.st.statemachine.jastadd.parser;
import de.tudresden.inf.st.statemachine.jastadd.model.*; import de.tudresden.inf.st.statemachine.jastadd.model.*;
import java.util.*; import java.util.*;
:}; :};
// Documentation links: http://beaver.sourceforge.net/spec.html and https://bitbucket.org/jastadd/jastaddparser
%embed {: %embed {:
// this code is inlined in the generated parser class // this code is inlined in the generated parser class
......
...@@ -2,6 +2,7 @@ package de.tudresden.inf.st.statemachine.jastadd.scanner; ...@@ -2,6 +2,7 @@ package de.tudresden.inf.st.statemachine.jastadd.scanner;
import de.tudresden.inf.st.statemachine.jastadd.parser.StateMachineParser.Terminals; // The terminals are implicitly defined in the parser import de.tudresden.inf.st.statemachine.jastadd.parser.StateMachineParser.Terminals; // The terminals are implicitly defined in the parser
%% %%
// Documentation links: https://www.jflex.de/manual.html and http://beaver.sourceforge.net/scanners.html
// define the signature for the generated scanner // define the signature for the generated scanner
%public %public
......
...@@ -7,9 +7,7 @@ apply plugin: "idea" ...@@ -7,9 +7,7 @@ apply plugin: "idea"
sourceCompatibility = 1.8 sourceCompatibility = 1.8
repositories { repositories.mavenCentral()
mavenCentral()
}
dependencies { dependencies {
implementation project(':statemachine.base') implementation project(':statemachine.base')
...@@ -17,10 +15,14 @@ dependencies { ...@@ -17,10 +15,14 @@ dependencies {
implementation fileTree(dir: "${System.properties['java.home']}", include: '**/jfxrt.jar') implementation fileTree(dir: "${System.properties['java.home']}", include: '**/jfxrt.jar')
} }
sourceSets.main.java.srcDir "src/main/java"
run { run {
mainClassName = 'de.tudresden.inf.st.statemachine.DrAstRunner' mainClassName = 'de.tudresden.inf.st.statemachine.DrAstRunner'
standardInput = System.in standardInput = System.in
} }
run.dependsOn ':statemachine.base:jar'
run.doFirst { environment 'JAVA_TOOL_OPTIONS', '-Dlog4j2.disableJmx=true' }
task jarDrAst(type: Jar, dependsOn: ':statemachine.base:jar') { task jarDrAst(type: Jar, dependsOn: ':statemachine.base:jar') {
group = "build" group = "build"
...@@ -34,16 +36,3 @@ task jarDrAst(type: Jar, dependsOn: ':statemachine.base:jar') { ...@@ -34,16 +36,3 @@ task jarDrAst(type: Jar, dependsOn: ':statemachine.base:jar') {
from { sourceSets.main.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } from { sourceSets.main.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
with jar with jar
} }
task runDrAST(type: JavaExec, dependsOn: [jar, ':statemachine.base:jar']) {
group = "application"
description = 'run the DrAST visual debugger tool'
classpath = sourceSets.main.runtimeClasspath
main = 'de.tudresden.inf.st.statemachine.DrAstRunner'
}
sourceSets {
main {
java.srcDir "src/main/java"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment