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.
/src/data/
!/src/data
/src/data/*
# compiled output
/dist
......
../../../statemachine.base/build/docs/ragdoc/
\ No newline at end of file
// 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}
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;
......
aspect Reachability {
aspect ConnectedComponents {
// syn Set<State> State.successors() circular [new HashSet<>()] {
// Set<State> result = new HashSet<>();
// for (Transition t : getOutgoingList()) {
......@@ -30,54 +30,38 @@ aspect Reachability {
// 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<>();
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
// 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++;
}
for (State n : locked)
if (visited.get(n) == null)
n.assign(visited, new HashSet()); // backward search
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());
return new HashSet(visited.values());
}
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);
}
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, Integer> visited, int root) {
if (visited.get(this) > -1) return;
void State.assign(Map<State, Set> visited, Set root) {
root.add(this);
visited.put(this, root);
for (Transition t : getIncomingList()) {
State p = t.getFrom();
p.assign(visited, root);
}
for (Transition t : getIncomingList())
if (visited.get(t.getFrom()) == null)
t.getFrom().assign(visited, root);
}
}
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()) {
......
......@@ -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
......
......@@ -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
......
......@@ -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"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment