diff --git a/ragdoc-view/.gitignore b/ragdoc-view/.gitignore index 5198bf6a10b6b4d19476a4fd12750b1932cbaab5..a2cbceafa95df13a18b2c9f10c9d761548a0d31c 100644 --- a/ragdoc-view/.gitignore +++ b/ragdoc-view/.gitignore @@ -1,6 +1,7 @@ # See http://help.github.com/ignore-files/ for more about ignoring files. -/src/data/ +!/src/data +/src/data/* # compiled output /dist diff --git a/ragdoc-view/src/app/data b/ragdoc-view/src/app/data new file mode 120000 index 0000000000000000000000000000000000000000..33f7f5e196c2f522a471eec9a0b63b8effa84cc3 --- /dev/null +++ b/ragdoc-view/src/app/data @@ -0,0 +1 @@ +../../../statemachine.base/build/docs/ragdoc/ \ No newline at end of file diff --git a/statemachine.base/build.gradle b/statemachine.base/build.gradle index c549365fe7ab12f7ceaeca78f2b7b3a95b1fb596..9657cfb82d6f0d57eccea069db79cd816d28bdb9 100644 --- a/statemachine.base/build.gradle +++ b/statemachine.base/build.gradle @@ -1,3 +1,4 @@ +// General configuration (plugins, settings, dependencies) group 'de.tudresden.inf.st' version '0.1' @@ -8,25 +9,24 @@ apply plugin: "idea" sourceCompatibility = 1.8 -repositories { - mavenCentral() -} +repositories.mavenCentral() -idea { - module { - generatedSourceDirs += file('src/gen/java') +buildscript { + repositories.mavenLocal() + repositories.mavenCentral() + dependencies { + classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3' } } +idea.module.generatedSourceDirs += file('src/gen/java') + configurations { ragdoc } -sourceSets { - main { - java.srcDir "src/gen/java" - } -} +sourceSets.main.java.srcDir "src/gen/java" +jar.manifest.attributes('Main-Class': 'de.tudresden.inf.st.statemachine.Main') dependencies { implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jackson_version}" @@ -36,39 +36,17 @@ dependencies { ragdoc files('../libs/rd-builder.jar') } +// Default run configuration run { mainClassName = 'de.tudresden.inf.st.statemachine.Main' standardInput = System.in } -buildscript { - 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' - ) - } -} - +// Generated files def ecoreFile = "./src/main/resources/StateMachine.ecore" 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) { group = 'Build' main = "-jar" @@ -85,16 +63,25 @@ task ecoreToRelast(type: JavaExec) { outputs.files file(relastFile) } -task preprocess(type: JavaExec) { +// Second phase: RelAst -> JastAdd +task relastToJastAdd(type: JavaExec) { group = 'Build' 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 outputs.files file("./src/gen/jastadd/StateMachine.ast"), file("./src/gen/jastadd/StateMachine.jadd") } +// Third phase: JastAdd -> Java (using JastAdd Gradle plugin) jastadd { configureModuleBuild() modules { @@ -144,11 +131,12 @@ jastadd { scanner.genDir = "src/gen/java/de/tudresden/inf/st/statemachine/jastadd/scanner" parser.genDir = "src/gen/java/de/tudresden/inf/st/statemachine/jastadd/parser" - jastaddOptions = ['--List=JastAddList'] + extraJastAddOptions = ['--List=JastAddList'] } -preprocess.dependsOn ecoreToRelast -generateAst.dependsOn preprocess +// Workflow configuration for phases +relastToJastAdd.dependsOn ecoreToRelast +generateAst.dependsOn relastToJastAdd //// always run jastadd //jastadd.outputs.upToDateWhen {false} diff --git a/statemachine.base/src/main/jastadd/Analysis.jrag b/statemachine.base/src/main/jastadd/Analysis.jrag index 872fa7cd18626b741bca378833ef326a58df056d..fd38416bcad8031d77655a45673f82d3c46dec85 100644 --- a/statemachine.base/src/main/jastadd/Analysis.jrag +++ b/statemachine.base/src/main/jastadd/Analysis.jrag @@ -1,5 +1,5 @@ aspect Analysis { - syn Set<State> State.reachableWithin(int n) { //circular [new HashSet<>()] + syn Set<State> State.reachableWithin(int n) { if (n == 0) { return new HashSet<>(); } @@ -11,8 +11,16 @@ aspect Analysis { 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() { - // analysis Set<Set<State>> sccs = this.SCC(); System.out.println("SCCs found:"); for (Set<State> scc : sccs) { @@ -20,7 +28,7 @@ aspect Analysis { } 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; diff --git a/statemachine.base/src/main/jastadd/ConnectedComponents.jrag b/statemachine.base/src/main/jastadd/ConnectedComponents.jrag new file mode 100644 index 0000000000000000000000000000000000000000..406e5f593ebcd4dabbd5f24d37f6a7eae8ab5296 --- /dev/null +++ b/statemachine.base/src/main/jastadd/ConnectedComponents.jrag @@ -0,0 +1,67 @@ +aspect ConnectedComponents { +// syn Set<State> State.successors() circular [new HashSet<>()] { +// Set<State> result = new HashSet<>(); +// for (Transition t : getOutgoingList()) { +// State s = t.getTo(); +// result.add(s); +// result.addAll(s.successors()); +// } +// return result; +// } + +// syn Set<State> State.predecessors() circular [new HashSet<>()] { +// Set<State> result = new HashSet<>(); +// for (Transition t : getIncomingList()) { +// State s = t.getFrom(); +// result.add(s); +// result.addAll(s.predecessors()); +// } +// return result; +// } + +// syn boolean State.hasCycle() = successors().contains(this); + +// syn Set<State> State.SCC() { +// Set<State> result = new HashSet<>(successors()); +// result.retainAll(predecessors()); +// return result; +// } + +// coll HashSet<Set<State>> StateMachine.SCC() with add root StateMachine; +// State contributes SCC() when SCC().size() > 0 to StateMachine.SCC(); + + /** + * Kosaraju's algorithm + */ + syn Set<Set<State>> StateMachine.SCC() { + Map<State, Set> visited = new HashMap<>(); + LinkedList<State> locked = new LinkedList<>(); + + for (State n : states()) + if (!visited.containsKey(n)) + n.visit(visited, locked); // forward search + + for (State n : locked) + if (visited.get(n) == null) + n.assign(visited, new HashSet()); // backward search + + return new HashSet(visited.values()); + } + + void State.visit(Map<State, Set> visited, LinkedList<State> locked) { + visited.put(this, null); + for (Transition t : getOutgoingList()) + if (!visited.containsKey(t.getTo())) + t.getTo().visit(visited, locked); + locked.addFirst(this); + } + + void State.assign(Map<State, Set> visited, Set root) { + root.add(this); + visited.put(this, root); + for (Transition t : getIncomingList()) + if (visited.get(t.getFrom()) == null) + t.getFrom().assign(visited, root); + } + +} diff --git a/statemachine.base/src/main/jastadd/Navigation.jrag b/statemachine.base/src/main/jastadd/Navigation.jrag index 0ccd14a71897c8831bc70a881cacfd0b7c5dd8a5..8aa18c02438c38ae7e821cff5de792b10fb36204 100644 --- a/statemachine.base/src/main/jastadd/Navigation.jrag +++ b/statemachine.base/src/main/jastadd/Navigation.jrag @@ -1,17 +1,22 @@ aspect Navigation { + /** Check, whether an this element is a state */ syn boolean Element.isState() = false; eq State.isState() = true; + /** View this element as a state */ syn State Element.asState() = null; eq State.asState() = this; + /** Check, whether an this element is a transition */ syn boolean Element.isTransition() = false; eq Transition.isTransition() = true; + /** View this element as a transition */ syn Transition Element.asTransition() = null; eq Transition.asTransition() = this; + /** Get all states */ syn List<State> StateMachine.states() { List<State> states = new ArrayList<>(); for (Element element: getElementList()) { diff --git a/statemachine.base/src/main/jastadd/Reachability.jrag b/statemachine.base/src/main/jastadd/Reachability.jrag deleted file mode 100644 index 1d4fc9ce9220ffdbbcd569c9d9062f4ff93a8f6e..0000000000000000000000000000000000000000 --- a/statemachine.base/src/main/jastadd/Reachability.jrag +++ /dev/null @@ -1,83 +0,0 @@ -aspect Reachability { -// syn Set<State> State.successors() circular [new HashSet<>()] { -// Set<State> result = new HashSet<>(); -// for (Transition t : getOutgoingList()) { -// State s = t.getTo(); -// result.add(s); -// result.addAll(s.successors()); -// } -// return result; -// } - -// syn Set<State> State.predecessors() circular [new HashSet<>()] { -// Set<State> result = new HashSet<>(); -// for (Transition t : getIncomingList()) { -// State s = t.getFrom(); -// result.add(s); -// result.addAll(s.predecessors()); -// } -// return result; -// } - -// syn boolean State.hasCycle() = successors().contains(this); - -// syn Set<State> State.SCC() { -// Set<State> result = new HashSet<>(successors()); -// result.retainAll(predecessors()); -// return result; -// } - -// coll HashSet<Set<State>> StateMachine.SCC() with add root StateMachine; -// State contributes SCC() when SCC().size() > 0 to StateMachine.SCC(); - - - /** - * Kosaraju's algorithm - */ - syn Set<Set<State>> StateMachine.SCC(){ - Map<State, Integer> visited = new HashMap<>(); - Deque<State> locked = new LinkedList<>(); - - // visit nodes forward - for (Element e : getElementList()){ - if (e.isState()){ - 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( - 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) { - if (visited.containsKey(this)) return; - visited.put(this, -1); - for (Transition t : getOutgoingList()) { - State s = t.getTo(); - s.visit(visited, locked); - } - locked.addFirst(this); - } - - void State.assign(Map<State, Integer> visited, int root) { - if (visited.get(this) > -1) return; - visited.put(this, root); - for (Transition t : getIncomingList()) { - State p = t.getFrom(); - p.assign(visited, root); - } - } - -} diff --git a/statemachine.base/src/main/jastadd/StateMachineParser.parser b/statemachine.base/src/main/jastadd/StateMachineParser.parser index 197392ec59f05154f50b716da6a4bd92981f1902..361e117ec1d2f4a7c25879e245e3cba720e8296a 100644 --- a/statemachine.base/src/main/jastadd/StateMachineParser.parser +++ b/statemachine.base/src/main/jastadd/StateMachineParser.parser @@ -4,6 +4,7 @@ package de.tudresden.inf.st.statemachine.jastadd.parser; import de.tudresden.inf.st.statemachine.jastadd.model.*; import java.util.*; :}; +// Documentation links: http://beaver.sourceforge.net/spec.html and https://bitbucket.org/jastadd/jastaddparser %embed {: // this code is inlined in the generated parser class diff --git a/statemachine.base/src/main/jastadd/StateMachineScanner.flex b/statemachine.base/src/main/jastadd/StateMachineScanner.flex index ad86af4783a0ca7ba0a425bf33204226c493139d..547fb1a00115870c46edab42efac34c3ec53fe4b 100644 --- a/statemachine.base/src/main/jastadd/StateMachineScanner.flex +++ b/statemachine.base/src/main/jastadd/StateMachineScanner.flex @@ -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 %% +// Documentation links: https://www.jflex.de/manual.html and http://beaver.sourceforge.net/scanners.html // define the signature for the generated scanner %public diff --git a/statemachine.drast/build.gradle b/statemachine.drast/build.gradle index 8fb499104ace1c89c55531cf918672b63a355192..fcf3218d92a4f97276c5570a6479cfaa97fbba90 100644 --- a/statemachine.drast/build.gradle +++ b/statemachine.drast/build.gradle @@ -7,9 +7,7 @@ apply plugin: "idea" sourceCompatibility = 1.8 -repositories { - mavenCentral() -} +repositories.mavenCentral() dependencies { implementation project(':statemachine.base') @@ -17,10 +15,14 @@ dependencies { implementation fileTree(dir: "${System.properties['java.home']}", include: '**/jfxrt.jar') } +sourceSets.main.java.srcDir "src/main/java" + run { mainClassName = 'de.tudresden.inf.st.statemachine.DrAstRunner' 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') { group = "build" @@ -34,16 +36,3 @@ task jarDrAst(type: Jar, dependsOn: ':statemachine.base:jar') { from { sourceSets.main.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } 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" - } -}