Store in GIT
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/graphviz-java.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
||||
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 356 KiB |
|
After Width: | Height: | Size: 798 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 356 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 563 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 154 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 215 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 261 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 681 KiB |
|
After Width: | Height: | Size: 418 KiB |
|
After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 270 KiB |
|
After Width: | Height: | Size: 154 KiB |
|
After Width: | Height: | Size: 31 KiB |
@@ -0,0 +1,7 @@
|
||||
DFA
|
||||
B0
|
||||
E1
|
||||
0>a>1
|
||||
0>b>1
|
||||
1>a>0
|
||||
1>b>1
|
||||
@@ -0,0 +1,13 @@
|
||||
DFA
|
||||
B0
|
||||
E4,2
|
||||
0>a>1
|
||||
0>b>2
|
||||
1>a>0
|
||||
1>b>2
|
||||
2>a>3
|
||||
2>b>4
|
||||
3>a>0
|
||||
3>b>2
|
||||
4>a>1
|
||||
4>b>0
|
||||
@@ -0,0 +1,11 @@
|
||||
DFA
|
||||
B1
|
||||
E3
|
||||
0>a>0
|
||||
0>b>1
|
||||
1>a>2
|
||||
1>b>1
|
||||
2>a>0
|
||||
2>b>3
|
||||
3>a>2
|
||||
3>b>1
|
||||
@@ -0,0 +1,15 @@
|
||||
DFA
|
||||
B0
|
||||
E2,4
|
||||
0>a>0
|
||||
0>b>1
|
||||
1>a>2
|
||||
1>b>1
|
||||
2>a>0
|
||||
2>b>3
|
||||
3>a>4
|
||||
3>b>1
|
||||
4>a>5
|
||||
4>b>3
|
||||
5>a>0
|
||||
5>b>3
|
||||
@@ -0,0 +1,11 @@
|
||||
NDFA
|
||||
B0
|
||||
E1,2
|
||||
0>a>1
|
||||
0>b>1
|
||||
0>$>2
|
||||
1>a>0
|
||||
1>b>1
|
||||
2>a>1
|
||||
2>b>0
|
||||
2>b>2
|
||||
@@ -0,0 +1,12 @@
|
||||
NDFA
|
||||
B0
|
||||
E4
|
||||
0>a>0
|
||||
0>b>0
|
||||
0>a>1
|
||||
0>b>3
|
||||
1>b>2
|
||||
2>b>4
|
||||
3>a>4
|
||||
4>a>4
|
||||
4>b>4
|
||||
@@ -0,0 +1,13 @@
|
||||
NDFA
|
||||
B0
|
||||
E2
|
||||
0>a>1
|
||||
0>b>1
|
||||
0>b>2
|
||||
1>b>3
|
||||
1>$>3
|
||||
1>a>2
|
||||
2>a>1
|
||||
3>a>4
|
||||
4>b>4
|
||||
4>$>2
|
||||
@@ -0,0 +1,2 @@
|
||||
REGEX
|
||||
(a|b)*
|
||||
@@ -0,0 +1,2 @@
|
||||
REGEX
|
||||
(aa)+(bba)*(a|b)*(c|d)
|
||||
@@ -0,0 +1,2 @@
|
||||
REGEX
|
||||
(n+o+)|(ye+s+)!*
|
||||
@@ -0,0 +1,150 @@
|
||||
package com.imegumii;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by imegumii on 18/04/2017.
|
||||
*/
|
||||
public class Automata <T extends Comparable> extends Importable {
|
||||
|
||||
protected Set<Transition<T>> transistions;
|
||||
|
||||
protected SortedSet<T> states;
|
||||
protected SortedSet<T> beginStates;
|
||||
protected SortedSet<T> eindStates;
|
||||
|
||||
protected SortedSet<Character> symbols;
|
||||
|
||||
public Automata() {
|
||||
super(Type.ERROR);
|
||||
states = new TreeSet<T>();
|
||||
beginStates = new TreeSet<T>();
|
||||
eindStates = new TreeSet<T>();
|
||||
|
||||
transistions = new TreeSet<>();
|
||||
|
||||
this.symbols = new TreeSet<>();
|
||||
}
|
||||
|
||||
public void addTransition (Transition<T> t) {
|
||||
if(t.symbol != Transition.EPSILON)
|
||||
symbols.add(t.symbol);
|
||||
|
||||
transistions.add(t);
|
||||
states.add(t.vanState);
|
||||
states.add(t.naarState);
|
||||
}
|
||||
|
||||
public void defineAsStartState(T t) {
|
||||
states.add(t);
|
||||
beginStates.add(t);
|
||||
}
|
||||
|
||||
public void defineAsEndState(T t) {
|
||||
states.add(t);
|
||||
eindStates.add(t);
|
||||
}
|
||||
|
||||
public void printTransitions () {
|
||||
transistions.forEach(System.out::println);
|
||||
}
|
||||
|
||||
public String getTransitions()
|
||||
{
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(type).append("\n");
|
||||
s.append('B');
|
||||
boolean first = true;
|
||||
for (T beginState : this.beginStates) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
s.append(',');
|
||||
}
|
||||
s.append(beginState.toString());
|
||||
}
|
||||
s.append('\n');
|
||||
first = true;
|
||||
s.append('E');
|
||||
for (T eindState : this.eindStates) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
s.append(',');
|
||||
}
|
||||
s.append(eindState.toString());
|
||||
}
|
||||
s.append('\n');
|
||||
|
||||
for(Transition<T> t : transistions)
|
||||
{
|
||||
s.append(t.toString()).append("\n");
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public void print() {
|
||||
System.out.println("Transitions");
|
||||
this.printTransitions();
|
||||
System.out.println("Beginstates");
|
||||
System.out.println(beginStates);
|
||||
System.out.println("Eindstates");
|
||||
System.out.println(eindStates);
|
||||
}
|
||||
|
||||
public void clearEindStates()
|
||||
{
|
||||
eindStates.clear();
|
||||
}
|
||||
|
||||
public void clearBeginStates()
|
||||
{
|
||||
beginStates.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (T state : this.states) {
|
||||
sb.append(state);
|
||||
}
|
||||
return "Automata" + sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof Automata))
|
||||
return false;
|
||||
|
||||
Automata<T> other = (Automata<T>) obj;
|
||||
|
||||
DFA<String> dfa1;
|
||||
DFA<String> dfa2;
|
||||
|
||||
if(this.type == Type.NDFA)
|
||||
{
|
||||
dfa1 = ((NDFA<String>)this).toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
else
|
||||
{
|
||||
dfa1 = ((DFA<String>)this).minimaliseerHopcroft();
|
||||
}
|
||||
|
||||
if(other.type == Type.NDFA)
|
||||
{
|
||||
dfa2 = ((NDFA<String>) obj).toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
else
|
||||
{
|
||||
dfa2 = ((DFA<String>) obj).minimaliseerHopcroft();
|
||||
}
|
||||
|
||||
DFA<String> result = dfa2.ontkenning().en(dfa1).minimaliseerHopcroft();
|
||||
|
||||
if(result.states.size() <= 1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.imegumii;
|
||||
|
||||
import com.sun.jmx.remote.internal.ArrayQueue;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* Created by kenny on 12-6-2017.
|
||||
*/
|
||||
public class BackgroundWorker implements Runnable{
|
||||
|
||||
public interface Worker {
|
||||
void execute();
|
||||
};
|
||||
|
||||
private Thread t;
|
||||
private boolean running;
|
||||
private Queue<Worker> workers;
|
||||
|
||||
private static BackgroundWorker worker;
|
||||
|
||||
public static BackgroundWorker instance()
|
||||
{
|
||||
if(worker == null)
|
||||
worker = new BackgroundWorker();
|
||||
|
||||
return worker;
|
||||
}
|
||||
|
||||
private BackgroundWorker()
|
||||
{
|
||||
running = true;
|
||||
workers = new ArrayDeque<Worker>();
|
||||
|
||||
t = new Thread(this);
|
||||
t.start();
|
||||
}
|
||||
|
||||
public void addWorker(Worker w)
|
||||
{
|
||||
workers.add(w);
|
||||
}
|
||||
|
||||
public void kill()
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
this.t.interrupt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
while(running)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Canceled thread");
|
||||
}
|
||||
|
||||
if(workers.isEmpty())
|
||||
continue;
|
||||
|
||||
Worker current = workers.poll();
|
||||
|
||||
current.execute();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.imegumii;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import javafx.util.Pair;
|
||||
|
||||
/**
|
||||
* Created by imegumii on 01/05/2017.
|
||||
*/
|
||||
public class DFA<T extends Comparable> extends Automata<T> {
|
||||
|
||||
public DFA() {
|
||||
super();
|
||||
this.type = Type.DFA;
|
||||
}
|
||||
|
||||
public boolean accepteer(String s) {
|
||||
// bij een DFA is er maar een beginstate, dus gebruiken we first.
|
||||
T beginState = this.beginStates.first();
|
||||
T currentState = beginState;
|
||||
|
||||
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (!this.symbols.contains(s.charAt(i))) {
|
||||
// reject, because we don't contain this symbol
|
||||
return false;
|
||||
}
|
||||
for (Transition<T> t : this.transistions) {
|
||||
// System.out.println("State is " + t.vanState);
|
||||
// System.out.println("CurrentState is " + currentState);
|
||||
if (t.vanState.equals(currentState)) {
|
||||
// System.out.println("Char is " + s.charAt(i) + " and state is " + t);
|
||||
// if states match, parse using symbols.
|
||||
if (t.symbol == s.charAt(i)) {
|
||||
// symbols match
|
||||
// System.out.println("Symbols match for " + t + " and " + s.charAt(i) + " with currentState " + currentState);
|
||||
currentState = t.naarState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// System.out.println("Ended on state " + currentState);
|
||||
return this.eindStates.contains(currentState);
|
||||
}
|
||||
|
||||
private TreeSet<String> addSymbols(int n, TreeSet<String> tempSet) {
|
||||
TreeSet<String> tempGenerated = new TreeSet<>(tempSet);
|
||||
if (n == 0) {
|
||||
return tempGenerated;
|
||||
}
|
||||
|
||||
for(String s : tempSet) {
|
||||
for(Character c : this.symbols) {
|
||||
tempGenerated.add(s + c);
|
||||
}
|
||||
}
|
||||
|
||||
tempGenerated.addAll(addSymbols(n - 1, tempGenerated));
|
||||
|
||||
return tempGenerated;
|
||||
}
|
||||
|
||||
public Taal geefTaalTotLengte(int n) {
|
||||
TreeSet<String> taal = new TreeSet<>();
|
||||
for (Character c : this.symbols) {
|
||||
taal.add("" + c);
|
||||
}
|
||||
return new Taal(addSymbols(n - 1, taal));
|
||||
}
|
||||
|
||||
public NDFA<String> reverse()
|
||||
{
|
||||
NDFA<String> reversed = new NDFA<String>();
|
||||
|
||||
for(Transition<T> t : transistions)
|
||||
{
|
||||
reversed.addTransition(new Transition<String>(t.naarState.toString(), t.symbol, t.vanState.toString()));
|
||||
}
|
||||
|
||||
for(T state : eindStates) {
|
||||
reversed.defineAsStartState(state.toString());
|
||||
}
|
||||
|
||||
for(T state : beginStates) {
|
||||
reversed.defineAsEndState(state.toString());
|
||||
}
|
||||
|
||||
return reversed;
|
||||
}
|
||||
|
||||
public DFA<String> minimaliseer() {
|
||||
return this.reverse().toDFA().reverse().toDFA();
|
||||
}
|
||||
|
||||
public DFA<String> minimaliseerHopcroft() {
|
||||
HopcroftConverter converter = new HopcroftConverter((DFA<String>) this);
|
||||
return converter.minimize();
|
||||
}
|
||||
|
||||
public DFA<T> ontkenning() {
|
||||
|
||||
DFA<T> result = new DFA<T>();
|
||||
|
||||
for(Transition<T> t : this.transistions)
|
||||
{
|
||||
result.addTransition(t);
|
||||
}
|
||||
|
||||
for(T s : this.eindStates)
|
||||
{
|
||||
result.defineAsStartState(s);
|
||||
}
|
||||
|
||||
for(T s : this.beginStates)
|
||||
{
|
||||
result.defineAsEndState(s);
|
||||
}
|
||||
|
||||
return result;
|
||||
/*
|
||||
DFA<T> returnDFA = new DFA<T>();
|
||||
|
||||
SortedSet<T> newEndStates = new TreeSet<>();
|
||||
|
||||
for (T state : this.states) {
|
||||
if (!this.eindStates.contains(state)) {
|
||||
newEndStates.add(state);
|
||||
}
|
||||
}
|
||||
|
||||
for (T newEndState : newEndStates) {
|
||||
returnDFA.defineAsEndState(newEndState);
|
||||
}
|
||||
|
||||
for (T beginState : this.beginStates) {
|
||||
returnDFA.defineAsStartState(beginState);
|
||||
}
|
||||
|
||||
for (Transition<T> transistion : this.transistions) {
|
||||
returnDFA.addTransition(transistion);
|
||||
}
|
||||
|
||||
return returnDFA;*/
|
||||
}
|
||||
|
||||
public DFA<String> en(DFA<T> other)
|
||||
{
|
||||
return maakTupleDFA((DFA<String>)this, (DFA<String>)other, false);
|
||||
}
|
||||
|
||||
public DFA<String> of(DFA<T> other)
|
||||
{
|
||||
return maakTupleDFA((DFA<String>)this, (DFA<String>)other, true);
|
||||
}
|
||||
|
||||
private DFA<String> maakTupleDFA(DFA<String> dfa1, DFA<String> dfa2, boolean of)
|
||||
{
|
||||
DFA<String> merged = new DFA<String>();
|
||||
|
||||
//Create all transitions and states
|
||||
for(Transition t1 : dfa1.transistions)
|
||||
{
|
||||
for(Transition t2 : dfa2.transistions)
|
||||
{
|
||||
if(t1.symbol == t2.symbol) {
|
||||
Transition t3 = new Transition<String>(t1.vanState + "-" + t2.vanState, t1.symbol, t1.naarState + "-" + t2.naarState);
|
||||
|
||||
if(dfa1.beginStates.contains(t1.vanState) && dfa2.beginStates.contains(t2.vanState))
|
||||
merged.defineAsStartState((String)t3.vanState);
|
||||
|
||||
if(of)
|
||||
{
|
||||
if(dfa1.eindStates.contains(t1.vanState) || dfa2.eindStates.contains(t2.vanState))
|
||||
merged.defineAsEndState((String)t3.vanState);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dfa1.eindStates.contains(t1.vanState) && dfa2.eindStates.contains(t2.vanState))
|
||||
merged.defineAsEndState((String)t3.vanState);
|
||||
}
|
||||
|
||||
merged.addTransition(t3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Delete wrong states
|
||||
SortedSet<String> usedStates = new TreeSet<String>();
|
||||
for(Transition t : merged.transistions)
|
||||
{
|
||||
usedStates.add((String)t.naarState);
|
||||
}
|
||||
|
||||
Iterator<Transition<String>> it = merged.transistions.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
Transition<String> t = it.next();
|
||||
|
||||
if(!usedStates.contains(t.vanState) && !merged.beginStates.contains(t.vanState))
|
||||
{
|
||||
it.remove();
|
||||
merged.eindStates.remove(t.vanState);
|
||||
}
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.imegumii;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.Buffer;
|
||||
|
||||
/**
|
||||
* Created by kenny on 8-6-2017.
|
||||
*/
|
||||
public class FileParser {
|
||||
|
||||
public static Importable read(String filename)
|
||||
{
|
||||
File f = new File("input/" + filename);
|
||||
|
||||
Importable imp = null;
|
||||
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
|
||||
|
||||
String type = br.readLine();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case "DFA":
|
||||
imp = readDFA(br);
|
||||
break;
|
||||
case "NDFA":
|
||||
imp = readNDFA(br);
|
||||
break;
|
||||
case "REGEX":
|
||||
imp = readRegex(br);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
||||
public static DFA<String> readDFA(BufferedReader br) throws IOException {
|
||||
|
||||
DFA<String> dfa = new DFA<String>();
|
||||
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if(line.startsWith("B")) {
|
||||
String[] states = line.substring(1,line.length()).split(",");
|
||||
for(String s : states) { dfa.defineAsStartState(s); }
|
||||
}
|
||||
|
||||
else if(line.startsWith("E")) {
|
||||
String[] states = line.substring(1,line.length()).split(",");
|
||||
for(String s : states) { dfa.defineAsEndState(s); }
|
||||
}
|
||||
|
||||
else {
|
||||
String[] trans = line.split(">");
|
||||
dfa.addTransition(new Transition<String>(trans[0], trans[1].toCharArray()[0], trans[2]));
|
||||
}
|
||||
}
|
||||
|
||||
return dfa;
|
||||
}
|
||||
|
||||
public static NDFA<String> readNDFA(BufferedReader br) throws IOException {
|
||||
|
||||
NDFA<String> ndfa = new NDFA<String>();
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if(line.startsWith("B")) {
|
||||
String[] states = line.substring(1,line.length()).split(",");
|
||||
for(String s : states) { ndfa.defineAsStartState(s); }
|
||||
}
|
||||
|
||||
else if(line.startsWith("E")) {
|
||||
String[] states = line.substring(1,line.length()).split(",");
|
||||
for(String s : states) { ndfa.defineAsEndState(s); }
|
||||
}
|
||||
|
||||
else {
|
||||
String[] trans = line.split(">");
|
||||
|
||||
if(trans[1].equals("$")) {
|
||||
ndfa.addTransition(new Transition<String>(trans[0], Transition.EPSILON, trans[2]));
|
||||
}
|
||||
else
|
||||
ndfa.addTransition(new Transition<String>(trans[0], trans[1].toCharArray()[0], trans[2]));
|
||||
}
|
||||
}
|
||||
|
||||
return ndfa;
|
||||
}
|
||||
|
||||
public static RegExp readRegex(BufferedReader br) throws IOException {
|
||||
String line = "Error";
|
||||
line = br.readLine();
|
||||
|
||||
RegExp regex = new RegExp();
|
||||
regex = regex.naarRegExp(line);
|
||||
|
||||
return regex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.imegumii;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Created by imegumii on 12/06/2017.
|
||||
*/
|
||||
public class GrammarConverter {
|
||||
|
||||
private SortedSet<String> getGrammar (NDFA<String> automata, String state) {
|
||||
SortedSet<String> canGoTo = new TreeSet<>();
|
||||
for (Character symbol : automata.symbols) {
|
||||
SortedSet<String> bereikbaarVanafViaEpsilonBereikbareState = automata.statesBereikbaarVanaf(state, symbol);
|
||||
for (String s1 : bereikbaarVanafViaEpsilonBereikbareState) {
|
||||
canGoTo.add("" + symbol + s1);
|
||||
}
|
||||
}
|
||||
return canGoTo;
|
||||
}
|
||||
|
||||
public Grammar toGrammar(NDFA<String> automata) {
|
||||
ArrayList<Grammar> grammar = new ArrayList<>();
|
||||
Grammar retval = null;
|
||||
for (String state : automata.states) {
|
||||
SortedSet<String> canGoTo = new TreeSet<>();
|
||||
// Check where we can go from here
|
||||
for (Character symbol : automata.symbols) {
|
||||
// canGoTo.add("" + symbol + state);
|
||||
// follow epsilon
|
||||
canGoTo.addAll(getGrammar(automata, state));
|
||||
|
||||
SortedSet<String> bereikbaarVanafEpsilon = automata.statesBereikbaarVanaf(state, Transition.EPSILON);
|
||||
for (String s : bereikbaarVanafEpsilon) {
|
||||
canGoTo.add("" + Transition.EPSILON + s);
|
||||
SortedSet<String> bereikbaarVanafEpsilonViaSymbool = automata.statesBereikbaarVanaf(s, symbol);
|
||||
for (String s1 : bereikbaarVanafEpsilonViaSymbool) {
|
||||
canGoTo.add("" + symbol + s1);
|
||||
}
|
||||
}
|
||||
// for (String s : bereikbaarVanafEpsilon) {
|
||||
// canGoTo.addAll(getGrammar(automata, s));
|
||||
// }
|
||||
|
||||
}
|
||||
grammar.add(new Grammar(state, canGoTo, null));
|
||||
}
|
||||
// System.out.println(grammar);
|
||||
// grammar.forEach(System.out::println);
|
||||
for (Grammar grammar1 : grammar) {
|
||||
if (grammar.size() > 1) {
|
||||
if (retval == null) {
|
||||
retval = grammar1;
|
||||
continue;
|
||||
} else {
|
||||
retval = retval.link(grammar1);
|
||||
}
|
||||
} else {
|
||||
retval = grammar1;
|
||||
}
|
||||
}
|
||||
return grammar.get(0);
|
||||
}
|
||||
|
||||
public class Grammar {
|
||||
Grammar below;
|
||||
String state;
|
||||
SortedSet<String> options;
|
||||
|
||||
public Grammar(String state, SortedSet<String> options, Grammar below) {
|
||||
this.state = state;
|
||||
this.options = options;
|
||||
this.below = below;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return state + " -> " + options;
|
||||
}
|
||||
|
||||
public Grammar link(Grammar other) {
|
||||
this.below = other;
|
||||
return other;
|
||||
}
|
||||
|
||||
public String printToString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(toString());
|
||||
sb.append("\n");
|
||||
if (below != null) {
|
||||
sb.append(below.printToString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void print() {
|
||||
System.out.println(state + " -> " + options);
|
||||
if (below != null) {
|
||||
below.print();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.imegumii;
|
||||
|
||||
import guru.nidi.graphviz.engine.Format;
|
||||
import guru.nidi.graphviz.engine.Graphviz;
|
||||
import guru.nidi.graphviz.model.Label;
|
||||
import guru.nidi.graphviz.model.MutableGraph;
|
||||
import guru.nidi.graphviz.model.Node;
|
||||
import guru.nidi.graphviz.parse.Parser;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import static guru.nidi.graphviz.model.Factory.graph;
|
||||
import static guru.nidi.graphviz.model.Factory.node;
|
||||
|
||||
/**
|
||||
* Created by kenny on 18-5-2017.
|
||||
*/
|
||||
public class Graph {
|
||||
|
||||
public static String generateGraphString(Automata<String> a)
|
||||
{
|
||||
String text = "digraph finite_state_machine {\nrankdir=LR;\nsize=\"8,5\";\n";
|
||||
|
||||
|
||||
if(a.eindStates.size() > 0) {
|
||||
text += "node [shape=cirlce, peripheries=2];";
|
||||
|
||||
for (String s : a.eindStates) {
|
||||
text += "\"" + s + "\" ";
|
||||
}
|
||||
|
||||
text += ";";
|
||||
}
|
||||
|
||||
if(a.beginStates.size() > 0) {
|
||||
text += "\nnode [shape = point];\n";
|
||||
|
||||
for (String s : a.beginStates) {
|
||||
text += "\" \" -> \"" + s + "\" [label = \" \"];";
|
||||
}
|
||||
}
|
||||
|
||||
text += "\nnode [shape = circle];\n";
|
||||
|
||||
for(Transition<String> t : a.transistions)
|
||||
{
|
||||
String s = "";
|
||||
if(t.symbol == Transition.EPSILON)
|
||||
s = "$";
|
||||
else
|
||||
s = t.symbol + "";
|
||||
|
||||
text += "\"" + t.vanState + "\" -> \"" + t.naarState + "\" [ label = \"" + s + "\"];\n";
|
||||
}
|
||||
|
||||
text += "}";
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String generateImageString(Automata<String> a)
|
||||
{
|
||||
String text = "digraph {\nrankdir=LR;\n";
|
||||
|
||||
if(a.eindStates.size() > 0) {
|
||||
for (String s : a.eindStates) {
|
||||
text += "\"" + s + "\" [peripheries=2]\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(a.beginStates.size() > 0) {
|
||||
text += "\nstart [shape = point];\n";
|
||||
|
||||
for (String s : a.beginStates) {
|
||||
text += "\"start\" -> \"" + s + "\" [label = \" \", color=aquamarine4];";
|
||||
}
|
||||
}
|
||||
|
||||
for(Transition<String> t : a.transistions)
|
||||
{
|
||||
String s = "";
|
||||
if(t.symbol == Transition.EPSILON)
|
||||
s = "$";
|
||||
else
|
||||
s = t.symbol + "";
|
||||
|
||||
text += "\"" + t.vanState + "\" -> \"" + t.naarState + "\" [ label = \"" + s + "\"];\n";
|
||||
}
|
||||
|
||||
text += "}";
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public static synchronized File generateImage(Automata<String> a)
|
||||
{
|
||||
return generateImage(a, null);
|
||||
}
|
||||
|
||||
public static synchronized File generateImage(Automata<String> a, String fileName) {
|
||||
|
||||
File f;
|
||||
if (fileName != null) {
|
||||
f = new File("images/" + fileName + ".png");
|
||||
} else {
|
||||
f = new File("images/" + a.hashCode() + ".png");
|
||||
}
|
||||
|
||||
try {
|
||||
MutableGraph g = Parser.read(Graph.generateImageString(a));
|
||||
Graphviz.fromGraph(g).width(Math.min(15000, Math.max(a.states.size() * 150, 750))).render(Format.PNG).toFile(f);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
package com.imegumii;
|
||||
|
||||
import javafx.geometry.HPos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Created by kenny on 30-5-2017.
|
||||
*/
|
||||
public class HopcroftConverter {
|
||||
|
||||
private DFA<String> automata;
|
||||
private SortedSet<HopcroftSet> sets;
|
||||
|
||||
public HopcroftConverter(DFA<String> automata)
|
||||
{
|
||||
this.automata = automata;
|
||||
this.sets = new TreeSet<HopcroftSet>();
|
||||
|
||||
DFAtoHopcroft();
|
||||
updateGroupReferences();
|
||||
|
||||
System.out.println("\nFound " + sets.size() + " sets.");
|
||||
}
|
||||
|
||||
public DFA<String> minimize()
|
||||
{
|
||||
int lastround = 0;
|
||||
int newround = 2;
|
||||
|
||||
int count = 0;
|
||||
|
||||
while(lastround != newround) {
|
||||
|
||||
count++;
|
||||
System.out.println("Minimize round " + count + " (" + lastround + "/" + newround + ")");
|
||||
|
||||
lastround = newround;
|
||||
newround = splitGroups(lastround);
|
||||
|
||||
updateGroupReferences();
|
||||
}
|
||||
|
||||
return HopcrofttoDFA();
|
||||
}
|
||||
|
||||
private void DFAtoHopcroft()
|
||||
{
|
||||
String beginGroup = getGroupName();
|
||||
String endGroup = getGroupName();
|
||||
|
||||
for(Transition t : automata.transistions)
|
||||
{
|
||||
boolean found = false;
|
||||
HopcroftSet currentSet = null;
|
||||
|
||||
for(HopcroftSet s : sets) {
|
||||
if (t.vanState.equals(s.state)) {
|
||||
found = true;
|
||||
currentSet = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
String groupName = beginGroup;
|
||||
boolean endState = false;
|
||||
if(automata.eindStates.contains((String)t.vanState)) {
|
||||
groupName = endGroup;
|
||||
endState = true;
|
||||
}
|
||||
currentSet = new HopcroftSet(groupName, (String)t.vanState, endState);
|
||||
sets.add(currentSet);
|
||||
}
|
||||
|
||||
currentSet.addColum(new HopcroftColumn(t.symbol, (String)t.naarState, "-"));
|
||||
}
|
||||
}
|
||||
|
||||
private DFA<String> HopcrofttoDFA()
|
||||
{
|
||||
DFA<String> result = new DFA<String>();
|
||||
|
||||
ArrayList<String> groups = new ArrayList<String>();
|
||||
|
||||
for(HopcroftSet s : sets)
|
||||
{
|
||||
if(!groups.contains(s.group))
|
||||
{
|
||||
for(HopcroftColumn c : s.columns)
|
||||
result.addTransition(new Transition<String>(s.group, c.symbol, c.group));
|
||||
|
||||
if(s.isEndState)
|
||||
result.defineAsEndState(s.group);
|
||||
|
||||
groups.add(s.group);
|
||||
}
|
||||
|
||||
if(automata.beginStates.contains(s.state))
|
||||
result.defineAsStartState(s.group);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void updateGroupReferences()
|
||||
{
|
||||
for(HopcroftSet s : sets)
|
||||
{
|
||||
for(HopcroftColumn c : s.columns)
|
||||
{
|
||||
for(HopcroftSet h : sets)
|
||||
{
|
||||
if(c.state.equals(h.state))
|
||||
c.group = h.group;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int splitGroups(int oldsize)
|
||||
{
|
||||
HashMap<String, ArrayList<HopcroftSet>> groups = new HashMap<String, ArrayList<HopcroftSet>>();
|
||||
|
||||
for(HopcroftSet s : sets)
|
||||
{
|
||||
String key = s.group;
|
||||
|
||||
for(HopcroftColumn c : s.columns)
|
||||
key += c.symbol + c.group;
|
||||
|
||||
if(!groups.containsKey(key))
|
||||
{
|
||||
groups.put(key, new ArrayList<HopcroftSet>());
|
||||
}
|
||||
|
||||
groups.get(key).add(s);
|
||||
}
|
||||
|
||||
if(oldsize == groups.size())
|
||||
return oldsize;
|
||||
|
||||
sets.clear();
|
||||
|
||||
for(ArrayList<HopcroftSet> arr : groups.values())
|
||||
{
|
||||
String newGroupName = getGroupName();
|
||||
|
||||
for(HopcroftSet ns : arr)
|
||||
{
|
||||
ns.group = newGroupName;
|
||||
sets.add(ns);
|
||||
}
|
||||
}
|
||||
|
||||
return groups.size();
|
||||
}
|
||||
|
||||
|
||||
private int count = -1;
|
||||
private int suffix = 0;
|
||||
private String[] alphabet = {"A", "B", "C", "D", "E", "F", "G","H","I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
|
||||
|
||||
private String getGroupName()
|
||||
{
|
||||
count++;
|
||||
if(count >= alphabet.length) {
|
||||
count = 0;
|
||||
suffix++;
|
||||
}
|
||||
|
||||
return alphabet[count] + suffix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class HopcroftSet implements Comparable<HopcroftSet>{
|
||||
|
||||
public String group;
|
||||
public String state;
|
||||
|
||||
public ArrayList<HopcroftColumn> columns;
|
||||
|
||||
public boolean isEndState = false;
|
||||
|
||||
public HopcroftSet(String group, String state, boolean isEndState)
|
||||
{
|
||||
this.group = group;
|
||||
this.state = state;
|
||||
this.isEndState = isEndState;
|
||||
|
||||
columns = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addColum(HopcroftColumn c)
|
||||
{
|
||||
this.columns.add(c);
|
||||
}
|
||||
|
||||
public void clearColumns()
|
||||
{
|
||||
this.columns.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(HopcroftSet o) {
|
||||
return (this.group + this.state).compareTo(o.group + o.state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String s = group + " " + state + " | ";
|
||||
|
||||
for(HopcroftColumn c : columns)
|
||||
s += "(" + c.symbol + ") " + c.state + " " + c.group + " | ";
|
||||
|
||||
s+= " " + (isEndState?"*":"");
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
class HopcroftColumn {
|
||||
|
||||
public char symbol;
|
||||
public String state;
|
||||
public String group;
|
||||
|
||||
public HopcroftColumn(char s, String state, String group)
|
||||
{
|
||||
this.symbol = s;
|
||||
this.state = state;
|
||||
this.group = group;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.imegumii;
|
||||
|
||||
/**
|
||||
* Created by kenny on 9-6-2017.
|
||||
*/
|
||||
public class Importable {
|
||||
public static enum Type {DFA, NDFA, REGEX, ERROR};
|
||||
|
||||
public Type type;
|
||||
|
||||
public Importable(Type t)
|
||||
{
|
||||
this.type = t;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.imegumii;
|
||||
|
||||
import com.imegumii.ui.Frame;
|
||||
import com.imegumii.ui.PopupFrame;
|
||||
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// String s = "a*(aa+ |ba*b ) * (abba|baab|bbbb)+";
|
||||
//
|
||||
// String s2 = "a(a+ | b*((a|b)+))";
|
||||
// String s3 = "(a|b)+a";
|
||||
//
|
||||
// String s4 = "a+((ab)*b|ab|(b)*bb)+(abba|baab)+";
|
||||
// String s5 = "a(ab)*b(a|b)|ab|(b)*bb";
|
||||
// String s6 = "(fuck)+";
|
||||
// String s7 = "a((a|b)+(baab|abba))";
|
||||
// String s8 = "(( (a|b)*(baab))+)banaan";
|
||||
//
|
||||
//// NDFA<String> ndfa = (NDFA<String>) FileParser.read("ndfa1.dot");
|
||||
//// ndfa.print();
|
||||
//// new GrammarConverter().toGrammar(ndfa).print();
|
||||
//
|
||||
// RegExp r = new RegExp();
|
||||
// String todo = s8;
|
||||
// System.out.println(todo);
|
||||
// System.out.println(r.naarRegExp(todo).getTaal(6, 10));
|
||||
|
||||
new Frame();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.imegumii;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by imegumii on 01/05/2017.
|
||||
*/
|
||||
public class NDFA<T extends Comparable> extends Automata<T> {
|
||||
|
||||
public NDFA() {
|
||||
super();
|
||||
this.type = Type.NDFA;
|
||||
}
|
||||
|
||||
public SortedSet<T> statesBereikbaarVanaf(T vanaf, char s) {
|
||||
SortedSet<T> bereikbaar = new TreeSet<T>();
|
||||
Iterator<Transition<T>> it = this.transistions.iterator();
|
||||
|
||||
while(it.hasNext()) {
|
||||
Transition<T> t = it.next();
|
||||
|
||||
// System.out.println(t);
|
||||
if (vanaf.equals(t.vanState)) {
|
||||
// System.out.println("Dit is onze staat");
|
||||
boolean isGelijk = false;
|
||||
isGelijk = s == t.symbol;
|
||||
// System.out.println("Zijn symbolen gelijk? " + isGelijk);
|
||||
|
||||
if (isGelijk && !bereikbaar.contains(t.naarState)) {
|
||||
bereikbaar.add(t.naarState);
|
||||
bereikbaar.addAll(statesBereikbaarVanaf(t.naarState, Transition.EPSILON));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return bereikbaar;
|
||||
}
|
||||
|
||||
public DFA<String> toDFA () {
|
||||
DFA<String> eindDFA = new DFA<>();
|
||||
|
||||
SortedSet<T> startSet = new TreeSet<T>();
|
||||
//er kunnen meer start states zijn,
|
||||
// een NDFA kan namelijk meerdere start states hebben (die met epsilon overgangen dan toch naar 1 state gewerkt kunnen worden)
|
||||
for (T t : this.beginStates) {
|
||||
startSet.add(t);
|
||||
startSet.addAll(statesBereikbaarVanaf(t, Transition.EPSILON));
|
||||
}
|
||||
// System.out.println("Begin states zijn: ");
|
||||
// startSet.forEach(System.out::println);
|
||||
|
||||
HashMap<SortedSet<T>, Integer> totaalEindStates = new HashMap<>();
|
||||
|
||||
totaalEindStates.put(startSet, 0);
|
||||
|
||||
Queue<SortedSet<T>> kue = new LinkedList<>();
|
||||
kue.offer(startSet); // add beginstate(s)
|
||||
|
||||
// System.out.println("Start ------------");
|
||||
|
||||
int stateCounter = 1;
|
||||
|
||||
SortedSet<Transition<String>> trans = new TreeSet<>();
|
||||
|
||||
while (!kue.isEmpty()) {
|
||||
SortedSet<T> set = kue.poll();
|
||||
// we beginnen bij de begin states
|
||||
|
||||
// kijk welke states je kunt bereiken vanaf deze state.
|
||||
for (Character symbol : this.symbols) {
|
||||
SortedSet<T> totaalTeBereiken = new TreeSet<>();
|
||||
boolean isEindState = false;
|
||||
boolean isBeginState = stateCounter == 1;
|
||||
for (T t : set) {
|
||||
// kijk wat er te bereiken is vanaf t
|
||||
// System.out.println("Bereikbaar vanaf T "+ t + " en s " + symbol + " is");
|
||||
SortedSet<T> bereikbareStates = statesBereikbaarVanaf(t, symbol);
|
||||
// System.out.println("Vanaf " + t + " kan ik bij " + bereikbareStates + " komen via " + symbol);
|
||||
totaalTeBereiken.addAll(bereikbareStates);
|
||||
if (this.eindStates.contains(t)) {
|
||||
isEindState = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!totaalEindStates.containsKey(totaalTeBereiken)) {
|
||||
kue.offer(totaalTeBereiken);
|
||||
totaalEindStates.put(totaalTeBereiken, stateCounter);
|
||||
stateCounter++;
|
||||
}
|
||||
|
||||
// add transitions
|
||||
// System.out.println("Vanaf " + set + " kan ik dus bij " + totaalTeBereiken + " komen via " + symbol);
|
||||
eindDFA.addTransition(new Transition<>(totaalEindStates.get(set).toString(), symbol, totaalEindStates.get(totaalTeBereiken).toString()));
|
||||
if (isBeginState) {
|
||||
// beginstate
|
||||
eindDFA.defineAsStartState(totaalEindStates.get(set).toString());
|
||||
}
|
||||
if (isEindState) {
|
||||
// System.out.println("Eind state is ");
|
||||
eindDFA.defineAsEndState(totaalEindStates.get(set).toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// System.out.println("----end");
|
||||
|
||||
// System.out.println("In totaal krijgen we " + totaalEindStates);
|
||||
// eindDFA.transistions.forEach((t) -> {
|
||||
//// System.out.println(t.vanState);
|
||||
// System.out.println("(" + getByValue(totaalEindStates, t.vanState) + ", " + t.symbol + ")-->" + getByValue(totaalEindStates, t.naarState));
|
||||
//
|
||||
// });
|
||||
|
||||
|
||||
// trans.forEach(System.out::println);
|
||||
// for (Transition<String> t : trans) {
|
||||
// eindDFA.addTransition(t);
|
||||
// }
|
||||
return eindDFA;
|
||||
}
|
||||
|
||||
// public SortedSet<T> getByValue (HashMap<SortedSet<T>, Integer> map, String value) {
|
||||
// for (Map.Entry<SortedSet<T>, Integer> e : map.entrySet()) {
|
||||
// if (value.equals(e.getValue().toString())) {
|
||||
// return e.getKey();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
package com.imegumii;
|
||||
|
||||
import sun.misc.Regexp;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Created by kenny on 2-5-2017.
|
||||
*/
|
||||
public class RegExp extends Importable{
|
||||
|
||||
public enum Operator { PLUS, STER, OF, PUNT, EEN}
|
||||
|
||||
Operator operator;
|
||||
String characters;
|
||||
|
||||
RegExp links;
|
||||
RegExp rechts;
|
||||
|
||||
static final Comparator<String> vergelijkDmvLengte = (s1, s2) -> {
|
||||
if (s1.length() == s2.length())
|
||||
{return s1.compareTo(s2);}
|
||||
else
|
||||
{return s1.length() - s2.length();}
|
||||
};
|
||||
|
||||
public RegExp()
|
||||
{
|
||||
super(Type.REGEX);
|
||||
operator = Operator.EEN;
|
||||
characters = "";
|
||||
links = null;
|
||||
rechts = null;
|
||||
}
|
||||
|
||||
public RegExp(String chars){
|
||||
super(Type.REGEX);
|
||||
operator = Operator.EEN;
|
||||
characters = chars;
|
||||
links = null;
|
||||
rechts = null;
|
||||
}
|
||||
|
||||
public RegExp loopRecursiefDoorString(String startString, RegExp r) {
|
||||
int count = 0;
|
||||
boolean moetRecursief = false;
|
||||
|
||||
for (int i = 0; i < startString.length(); i++) {
|
||||
char c = startString.charAt(i);
|
||||
|
||||
if (c == '(') {
|
||||
count++;
|
||||
}
|
||||
if (c == ')') {
|
||||
count--;
|
||||
}
|
||||
if (count > 1) {
|
||||
moetRecursief = true;
|
||||
}
|
||||
}
|
||||
|
||||
Queue<String> queue = new LinkedList<>();
|
||||
queue.add(startString);
|
||||
|
||||
Deque<RegExp> processedParantheses = new ArrayDeque<>();
|
||||
|
||||
RegExp retval = new RegExp();
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
String s = queue.poll();
|
||||
// System.out.println("Working on " + s);
|
||||
Deque<Integer> start = new ArrayDeque<>();
|
||||
Deque<Integer> end = new ArrayDeque<>();
|
||||
|
||||
String toProcessAfter = s;
|
||||
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
|
||||
if (c == '(') {
|
||||
start.addLast(i);
|
||||
}
|
||||
|
||||
if (c == ')') {
|
||||
end.addFirst(i);
|
||||
}
|
||||
|
||||
if (!start.isEmpty() && !end.isEmpty()) {
|
||||
int startPos = start.pollLast();
|
||||
int endPos = end.pollFirst();
|
||||
|
||||
String sub = s.substring(startPos + 1, endPos);
|
||||
// System.out.println("Sub is " + sub);
|
||||
|
||||
StringBuilder toReplace = new StringBuilder(s.substring(startPos, endPos + 1));
|
||||
StringBuilder replaceWith = new StringBuilder("" + Transition.ENDCHAR);
|
||||
// System.out.println("Toreplace is " + toReplace.toString());
|
||||
toProcessAfter = toProcessAfter.replace(toReplace, replaceWith);
|
||||
// System.out.println("Next string is " + toProcessAfter);
|
||||
queue.add(toProcessAfter);
|
||||
if (sub.contains("" + Transition.ENDCHAR)) {
|
||||
// We have simplified the parantheses here, therefore before we continue we must first turn this into a regexp
|
||||
RegExp reg = stringNaarRegExp(sub, r, processedParantheses);
|
||||
processedParantheses.add(reg);
|
||||
// System.out.println(reg.getTaal(10, 100));
|
||||
} else {
|
||||
processedParantheses.add(stringNaarRegExp(sub, r, null));
|
||||
}
|
||||
// System.out.println("----");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!s.contains("(")) {
|
||||
retval = stringNaarRegExp(toProcessAfter, r, processedParantheses);
|
||||
}
|
||||
}
|
||||
// System.out.println(retval.getTaal(10, 100));
|
||||
// System.out.println("----------");
|
||||
return retval;
|
||||
}
|
||||
|
||||
public RegExp naarRegExp(String s) {
|
||||
|
||||
StringBuilder noSpacesString = new StringBuilder();
|
||||
|
||||
for (char c : s.toCharArray()) {
|
||||
if (c != ' ') {
|
||||
noSpacesString.append(c);
|
||||
}
|
||||
}
|
||||
// RegExp retval = new RegExp();
|
||||
// Als eerste moet de string in groupen gedeeld worden op basis van haakjes.
|
||||
// bijv. "a+((ab)*b|ab|(b)*bb)+(abba|baab)+" naar ["a+", [ [["ab"], "*b"], ["ab"], [["b"], "*bb"], "+" ], [ ["abba", "baab"], "+"] ]
|
||||
// Dit moet dan naar dit worden omgezet:
|
||||
// a.plus().punt( (ab.ster().punt(b).of(ab).of(b.ster().punt(bb)).plus()) ).punt( abba.punt().baab.plus() )
|
||||
// Niet gelukt.
|
||||
// System.out.println("We lopen door " + s);
|
||||
RegExp r = loopRecursiefDoorString(noSpacesString.toString(), new RegExp());
|
||||
return r;
|
||||
}
|
||||
|
||||
public RegExp stringNaarRegExp(String start, RegExp initieel, Deque<RegExp> alreadyParsed) {
|
||||
ArrayList<RegExp> toOf = new ArrayList<>();
|
||||
|
||||
ArrayList<String> strings = new ArrayList<>();
|
||||
StringBuilder currentString = new StringBuilder();
|
||||
for (int i = 0; i < start.length(); i++) {
|
||||
char current = start.charAt(i);
|
||||
|
||||
if (current == '|') {
|
||||
// flush currentString to strings array
|
||||
strings.add(currentString.toString());
|
||||
currentString = new StringBuilder();
|
||||
continue;
|
||||
}
|
||||
|
||||
currentString.append(current);
|
||||
}
|
||||
|
||||
strings.add(currentString.toString());
|
||||
|
||||
// System.out.println("OfStrings: " + strings);
|
||||
|
||||
RegExp retval = new RegExp();
|
||||
// toDot.add(initieel);
|
||||
|
||||
for (String s : strings) {
|
||||
RegExp total = new RegExp();
|
||||
ArrayList<RegExp> toDot = new ArrayList<>();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char current = s.charAt(i);
|
||||
RegExp prev;
|
||||
switch(current) {
|
||||
case '*':
|
||||
prev = toDot.get(toDot.size() -1);
|
||||
toDot.add(prev.ster());
|
||||
toDot.remove(prev);
|
||||
// System.out.println("STER");
|
||||
break;
|
||||
case '+':
|
||||
prev = toDot.get(toDot.size() -1);
|
||||
toDot.add(prev.plus());
|
||||
toDot.remove(prev);
|
||||
// System.out.println("PLUS");
|
||||
break;
|
||||
case Transition.ENDCHAR:
|
||||
toDot.add(alreadyParsed.pollFirst());
|
||||
break;
|
||||
default:
|
||||
toDot.add(new RegExp("" + current));
|
||||
// System.out.println("NEW CHAR");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (RegExp regExp : toDot) {
|
||||
total = total.punt(regExp);
|
||||
}
|
||||
|
||||
toOf.add(total);
|
||||
}
|
||||
RegExp prev = null;
|
||||
for (RegExp regExp : toOf) {
|
||||
if (toOf.size() > 1) {
|
||||
if (prev == null) {
|
||||
prev = regExp;
|
||||
continue;
|
||||
}
|
||||
retval = prev.of(regExp);
|
||||
prev = retval;
|
||||
} else {
|
||||
retval = retval.punt(regExp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
public RegExp plus()
|
||||
{
|
||||
RegExp res = new RegExp();
|
||||
res.operator = Operator.PLUS;
|
||||
res.links = this;
|
||||
return res;
|
||||
}
|
||||
|
||||
public RegExp ster()
|
||||
{
|
||||
RegExp res = new RegExp();
|
||||
res.operator = Operator.STER;
|
||||
res.links = this;
|
||||
return res;
|
||||
}
|
||||
|
||||
public RegExp of(RegExp other)
|
||||
{
|
||||
RegExp res = new RegExp();
|
||||
res.operator = Operator.OF;
|
||||
res.links = this;
|
||||
res.rechts = other;
|
||||
return res;
|
||||
}
|
||||
|
||||
public RegExp punt(RegExp other)
|
||||
{
|
||||
RegExp res = new RegExp();
|
||||
res.operator = Operator.PUNT;
|
||||
res.links = this;
|
||||
res.rechts = other;
|
||||
return res;
|
||||
}
|
||||
|
||||
public Taal getTaal(int maxOperaties, int maxLength)
|
||||
{
|
||||
SortedSet<String> leeg = new TreeSet<>(vergelijkDmvLengte);
|
||||
SortedSet<String> resultaat = new TreeSet<>(vergelijkDmvLengte);
|
||||
|
||||
SortedSet<String> resLinks, resRechts;
|
||||
|
||||
if(maxOperaties < 1) return new Taal(leeg);
|
||||
|
||||
switch(operator)
|
||||
{
|
||||
case EEN:
|
||||
resultaat.add(characters);
|
||||
break;
|
||||
|
||||
case OF:
|
||||
resLinks = links == null ? leeg : links.getTaal(maxOperaties - 1, maxLength).getSymbols();
|
||||
resRechts = rechts == null ? leeg : rechts.getTaal(maxOperaties - 1, maxLength).getSymbols();
|
||||
resultaat.addAll (resLinks);
|
||||
resultaat.addAll (resRechts);
|
||||
break;
|
||||
|
||||
case PUNT:
|
||||
resLinks = links == null ? leeg : links.getTaal(maxOperaties, maxLength).getSymbols();
|
||||
resRechts = rechts == null ? leeg : rechts.getTaal(maxOperaties, maxLength).getSymbols();
|
||||
for (String s1 : resLinks) {
|
||||
for (String s2 : resRechts) {
|
||||
resultaat.add(s1 + s2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STER:
|
||||
case PLUS:
|
||||
resLinks = links == null ? leeg : links.getTaal(maxOperaties - 1, maxLength).getSymbols();
|
||||
resultaat.addAll(resLinks);
|
||||
for (int i = 1; i < maxOperaties; i++)
|
||||
{
|
||||
HashSet<String> tempTaal = new HashSet<String>(resultaat);
|
||||
for (String s1 : resLinks)
|
||||
{
|
||||
for (String s2 : tempTaal)
|
||||
{
|
||||
resultaat.add (s1+s2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.operator == Operator.STER)
|
||||
{
|
||||
resultaat.add("");
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
System.out.println ("getTaal is nog niet gedefinieerd voor de operator: " + this.operator);
|
||||
break;
|
||||
|
||||
}
|
||||
SortedSet<String> ret = new TreeSet<>();
|
||||
resultaat.stream().filter(r -> r.length() <= maxLength).forEach(ret::add);
|
||||
return new Taal(ret);
|
||||
}
|
||||
|
||||
public class Tuple<X, Y> {
|
||||
public final X left;
|
||||
public final Y right;
|
||||
public Tuple(X left, Y right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + left + "," + right + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Chars: " + this.characters + " en operator: " + this.operator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.imegumii;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
* Created by imegumii on 02/05/2017.
|
||||
*/
|
||||
public class Taal {
|
||||
private SortedSet<String> symbols;
|
||||
|
||||
public Taal(SortedSet<String> sortedSet) {
|
||||
this.symbols = sortedSet;
|
||||
}
|
||||
|
||||
public SortedSet<String> getSymbols() {
|
||||
return symbols;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return symbols.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,495 @@
|
||||
package com.imegumii;
|
||||
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Created by kenny on 8-6-2017.
|
||||
*/
|
||||
public class Test {
|
||||
public static void test()
|
||||
{
|
||||
// Practicum1();
|
||||
|
||||
// Practicum2();
|
||||
|
||||
// Practicum4();
|
||||
|
||||
// Practicum5();
|
||||
|
||||
// ReverseAutomata();
|
||||
|
||||
// Hopcroft();
|
||||
|
||||
// TupleConstructie();
|
||||
|
||||
// FileReadTest();
|
||||
|
||||
// Hopcroft();
|
||||
// TestUitOpdrachtBeschrijving();
|
||||
|
||||
String s = "a*(aa+ |ba*b ) * (abba|baab|bbbb)+";
|
||||
|
||||
|
||||
String s2 = "a(a+ | b*((a|b)+))";
|
||||
String s3 = "(a|b)+a";
|
||||
|
||||
String s4 = "a+((ab)*b|ab|(b)*bb)+(abba|baab)+";
|
||||
String s5 = "((ab)*b(a|b)|ab|(b)*bb)+";
|
||||
|
||||
RegExp reg = new RegExp();
|
||||
// System.out.println(reg.toRegExp("a*|b+").getTaal(5));
|
||||
|
||||
// RegExp r1 = new RegExp("a");
|
||||
// RegExp r2 = new RegExp("b");
|
||||
//
|
||||
// RegExp r3 = r1.punt(r2);
|
||||
//
|
||||
// RegExp r4 = new RegExp();
|
||||
//
|
||||
// RegExp r5 = r3.punt(r4);
|
||||
//
|
||||
// traverseRegExp(r5);
|
||||
// System.out.println(aantalOperators(r5, 1));
|
||||
// System.out.println(r5.getTaal(5));
|
||||
|
||||
// RegExp all = bSter.punt(aPlus);
|
||||
// RegExp all = r1.punt(r2.ster()).punt(r3.plus());
|
||||
//
|
||||
// System.out.println(all.getTaal(5));
|
||||
// reg.parseString(s);
|
||||
// reg.parseString(s2);
|
||||
// System.out.println(reg.parseString(s4).getTaal(3));
|
||||
// System.out.println(aantalOperators(reg.parseString(s2),1));
|
||||
// System.out.println(aantalOperators(reg.parseString(s4), 1));
|
||||
// System.out.println(aantalOperators(reg.parseString(s5), 1));
|
||||
// System.out.println(reg.parseString(s3).getTaal(100)); // werkte!
|
||||
}
|
||||
|
||||
public static void P1Opdracht1(TreeSet<String> stringsToParse) {
|
||||
Character [] characters = {'a', 'b'};
|
||||
DFA<String> myAutomata = new DFA<String>();
|
||||
|
||||
// AAB
|
||||
myAutomata.addTransition(new Transition<String>("q0", 'a', "q1"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("q1", 'b', "q2"));
|
||||
myAutomata.addTransition(new Transition<String>("q1", 'a', "q0"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("q2", 'b', "q3"));
|
||||
myAutomata.addTransition(new Transition<String>("q2", 'a', "q5"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("q3", "q0"));
|
||||
|
||||
// BAAB
|
||||
myAutomata.addTransition(new Transition<String>("q0", 'b', "q4"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("q4", 'a', "q5"));
|
||||
myAutomata.addTransition(new Transition<String>("q4", 'b', "q4"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("q5", 'a', "q6"));
|
||||
myAutomata.addTransition(new Transition<String>("q5", 'b', "q4"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("q6", 'a', "q4"));
|
||||
myAutomata.addTransition(new Transition<String>("q6", 'b', "q7"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("q7", 'a', "q4"));
|
||||
myAutomata.addTransition(new Transition<String>("q7", 'b', "q4"));
|
||||
|
||||
myAutomata.defineAsStartState("q0");
|
||||
myAutomata.defineAsEndState("q3");
|
||||
myAutomata.defineAsEndState("q7");
|
||||
|
||||
myAutomata.printTransitions();
|
||||
|
||||
final long[] startTime = {System.currentTimeMillis()};
|
||||
myAutomata.geefTaalTotLengte(10).getSymbols().forEach((s) -> {
|
||||
long before = System.currentTimeMillis();
|
||||
boolean result = myAutomata.accepteer(s);
|
||||
long after = System.currentTimeMillis();
|
||||
long delta = (after-before);
|
||||
System.out.println("string " + s + " fully parsed, result: " + result + " , it took " + delta + " ms");
|
||||
startTime[0] += delta;
|
||||
});
|
||||
System.out.println((System.currentTimeMillis() - startTime[0]));
|
||||
}
|
||||
|
||||
public static void Practicum1() {
|
||||
TreeSet<String> stringsToParse = new TreeSet<>();
|
||||
stringsToParse.add("abbaa");
|
||||
stringsToParse.add("babaa");
|
||||
stringsToParse.add("abbaaabaab");
|
||||
stringsToParse.add("abaab");
|
||||
stringsToParse.add("aaaabba");
|
||||
stringsToParse.add("baab");
|
||||
stringsToParse.add("baaba");
|
||||
stringsToParse.add("baabaabba");
|
||||
stringsToParse.add("aaaaabb"); // this is wrong, something is wrong
|
||||
|
||||
|
||||
P1Opdracht1(stringsToParse);
|
||||
}
|
||||
|
||||
public static void Practicum2()
|
||||
{
|
||||
RegExp a = new RegExp("a");
|
||||
RegExp b = new RegExp("b");
|
||||
|
||||
// expr1: "baa"
|
||||
RegExp expr1 = new RegExp("baa");
|
||||
// expr2: "bb"
|
||||
RegExp expr2 = new RegExp("bb");
|
||||
// expr3: "baa | baa"
|
||||
RegExp expr3 = expr1.of(expr2);
|
||||
|
||||
// all: "(a|b)*"
|
||||
RegExp all = (a.of(b)).ster();
|
||||
|
||||
// expr4: "(baa | baa)+"
|
||||
RegExp expr4 = expr3.plus();
|
||||
// expr5: "(baa | baa)+ (a|b)*"
|
||||
RegExp expr5 = expr4.punt(all);
|
||||
|
||||
// System.out.println("taal van (baa):\n" + expr1.getTaal(5));
|
||||
// System.out.println("taal van (bb):\n" + expr2.getTaal(5));
|
||||
// System.out.println("taal van (baa | bb):\n" + expr3.getTaal(5));
|
||||
//
|
||||
// System.out.println("taal van (a|b)*:\n" + all.getTaal(5));
|
||||
// System.out.println("taal van (baa | bb)+:\n" + expr4.getTaal(5));
|
||||
// System.out.println("taal van (baa | bb)+ (a|b)*:\n" + expr5.getTaal(6));
|
||||
|
||||
}
|
||||
|
||||
public static void Thompson() {
|
||||
RegExp expr1 = new RegExp();
|
||||
expr1 = expr1.naarRegExp("a(abba|baab)*b+");
|
||||
|
||||
NDFA<String> test = ThompsonConverter.convert(expr1);
|
||||
|
||||
Graph.generateImage(test, "thompson");
|
||||
}
|
||||
|
||||
public static void Hopcroft()
|
||||
{
|
||||
DFA<String> automata = new DFA<String>();
|
||||
|
||||
|
||||
automata.addTransition(new Transition<String>("q0", 'a', "q2"));
|
||||
automata.addTransition(new Transition<String>("q0", 'b', "q3"));
|
||||
automata.addTransition(new Transition<String>("q1", 'a', "q3"));
|
||||
automata.addTransition(new Transition<String>("q1", 'b', "q2"));
|
||||
automata.addTransition(new Transition<String>("q2", 'a', "q0"));
|
||||
automata.addTransition(new Transition<String>("q2", 'b', "q4"));
|
||||
automata.addTransition(new Transition<String>("q3", 'a', "q1"));
|
||||
automata.addTransition(new Transition<String>("q3", 'b', "q5"));
|
||||
automata.addTransition(new Transition<String>("q4", 'a', "q6"));
|
||||
automata.addTransition(new Transition<String>("q4", 'b', "q5"));
|
||||
automata.addTransition(new Transition<String>("q5", 'a', "q2"));
|
||||
automata.addTransition(new Transition<String>("q5", 'b', "q0"));
|
||||
automata.addTransition(new Transition<String>("q6", 'a', "q4"));
|
||||
automata.addTransition(new Transition<String>("q6", 'b', "q0"));
|
||||
|
||||
automata.defineAsStartState("q0");
|
||||
|
||||
automata.defineAsEndState("q1");
|
||||
automata.defineAsEndState("q3");
|
||||
automata.defineAsEndState("q4");
|
||||
automata.defineAsEndState("q6");
|
||||
|
||||
|
||||
/*
|
||||
automata.addTransition(new Transition<String>("0", 'a', "0"));
|
||||
automata.addTransition(new Transition<String>("0", 'b', "1"));
|
||||
|
||||
automata.addTransition(new Transition<String>("1", 'a', "2"));
|
||||
automata.addTransition(new Transition<String>("1", 'b', "1"));
|
||||
|
||||
automata.addTransition(new Transition<String>("2", 'a', "0"));
|
||||
automata.addTransition(new Transition<String>("2", 'b', "3"));
|
||||
|
||||
automata.addTransition(new Transition<String>("3", 'a', "4"));
|
||||
automata.addTransition(new Transition<String>("3", 'b', "1"));
|
||||
|
||||
automata.addTransition(new Transition<String>("4", 'a', "5"));
|
||||
automata.addTransition(new Transition<String>("4", 'b', "3"));
|
||||
|
||||
automata.addTransition(new Transition<String>("5", 'a', "0"));
|
||||
automata.addTransition(new Transition<String>("5", 'b', "3"));
|
||||
|
||||
automata.defineAsStartState("0");
|
||||
automata.defineAsEndState("2");
|
||||
automata.defineAsEndState("4");
|
||||
*/
|
||||
|
||||
System.out.println("\nNormal automata..");
|
||||
System.out.println(Graph.generateGraphString(automata));
|
||||
|
||||
HopcroftConverter convert = new HopcroftConverter(automata);
|
||||
DFA<String> minimized = convert.minimize();
|
||||
|
||||
System.out.println("\nMinimized automata..");
|
||||
Graph.generateImage(minimized, null);
|
||||
}
|
||||
|
||||
public static void ReverseAutomata()
|
||||
{
|
||||
DFA<String> myAutomata = new DFA<String>();
|
||||
|
||||
// AAB
|
||||
myAutomata.addTransition(new Transition<String>("0", 'a', "0"));
|
||||
myAutomata.addTransition(new Transition<String>("0", 'b', "1"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("1", 'a', "0"));
|
||||
myAutomata.addTransition(new Transition<String>("1", 'b', "2"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("2", 'a', "0"));
|
||||
myAutomata.addTransition(new Transition<String>("2", 'b', "2"));
|
||||
|
||||
myAutomata.defineAsStartState("0");
|
||||
myAutomata.defineAsEndState("2");
|
||||
|
||||
// System.out.println(Graph.generateGraphString(myAutomata));
|
||||
|
||||
// System.out.println("\nREVERSE:");
|
||||
|
||||
NDFA<String> reverseAutomata = myAutomata.reverse();
|
||||
|
||||
// System.out.println(Graph.generateGraphString(reverseAutomata));
|
||||
|
||||
System.out.println("ORIGINEEL");
|
||||
myAutomata.printTransitions();
|
||||
System.out.println("MET BEGIN EN EIND");
|
||||
System.out.println(myAutomata.beginStates);
|
||||
System.out.println(myAutomata.eindStates);
|
||||
System.out.println("REVERSE");
|
||||
reverseAutomata.printTransitions();
|
||||
System.out.println("MET BEGIN EN EIND");
|
||||
System.out.println(reverseAutomata.beginStates);
|
||||
System.out.println(reverseAutomata.eindStates);
|
||||
}
|
||||
|
||||
public static void Practicum4() {
|
||||
NDFA<String> myAutomata = new NDFA<String>();
|
||||
|
||||
// myAutomata.addTransition(new Transition<String>("0", 'a', "1"));
|
||||
// myAutomata.addTransition(new Transition<String>("0", 'a', "2"));
|
||||
// myAutomata.addTransition(new Transition<String>("1", 'a', "1"));
|
||||
// myAutomata.addTransition(new Transition<String>("1", 'a', "2"));
|
||||
// myAutomata.addTransition(new Transition<String>("2", 'b', "1"));
|
||||
// myAutomata.addTransition(new Transition<String>("2", 'b', "3"));
|
||||
// myAutomata.addTransition(new Transition<String>("3", 'a', "2"));
|
||||
// myAutomata.addTransition(new Transition<String>("3", 'a', "1"));
|
||||
// myAutomata.defineAsStartState("0");
|
||||
// myAutomata.defineAsEndState("0");
|
||||
// myAutomata.defineAsEndState("1");
|
||||
|
||||
// Test 2
|
||||
// myAutomata.addTransition(new Transition<String>("0", 'a', "1"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("0", 'a', "3"));
|
||||
// myAutomata.addTransition(new Transition<String>("0", 'b', "3"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("0", 'a', "2"));
|
||||
// myAutomata.addTransition(new Transition<String>("0", 'b', "2"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("1", 'a', "1"));
|
||||
// myAutomata.addTransition(new Transition<String>("1", 'b', "3"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("1", 'a', "2"));
|
||||
// myAutomata.addTransition(new Transition<String>("1", 'b', "2"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("2", 'b', "2"));
|
||||
// myAutomata.addTransition(new Transition<String>("2", 'b', "4"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("2", 'b', "3")); //ja? Ja.
|
||||
// myAutomata.addTransition(new Transition<String>("3", 'b', "2"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("3", 'b', "3"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("3", 'a', "4"));
|
||||
// myAutomata.addTransition(new Transition<String>("3", 'b', "4"));
|
||||
//
|
||||
// myAutomata.defineAsStartState("0");
|
||||
// myAutomata.defineAsEndState("1");
|
||||
|
||||
// Test 3
|
||||
|
||||
// myAutomata.addTransition(new Transition<String>("1", 'a', "2"));
|
||||
// myAutomata.addTransition(new Transition<String>("1", 'b', "1"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("2", 'a', "3"));
|
||||
// myAutomata.addTransition(new Transition<String>("2", 'b', "2"));
|
||||
// myAutomata.addTransition(new Transition<String>("2", Transition.EPSILON, "1"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("3", 'a', "4"));
|
||||
// myAutomata.addTransition(new Transition<String>("3", 'b', "3"));
|
||||
// myAutomata.addTransition(new Transition<String>("3", Transition.EPSILON, "2"));
|
||||
//
|
||||
// myAutomata.addTransition(new Transition<String>("4", 'a', "1"));
|
||||
// myAutomata.addTransition(new Transition<String>("4", 'b', "4"));
|
||||
// myAutomata.addTransition(new Transition<String>("4", Transition.EPSILON, "3"));
|
||||
//
|
||||
// myAutomata.defineAsStartState("1");
|
||||
// myAutomata.defineAsEndState("2");
|
||||
// myAutomata.defineAsEndState("3");
|
||||
|
||||
System.out.println("De NDFA is ");
|
||||
myAutomata.printTransitions();
|
||||
System.out.println("Met als begin en eind states");
|
||||
System.out.println(myAutomata.beginStates);
|
||||
System.out.println(myAutomata.eindStates);
|
||||
|
||||
System.out.println("DFA is dan ");
|
||||
DFA<String> myDfa = myAutomata.toDFA();
|
||||
myDfa.printTransitions();
|
||||
System.out.println("Met als begin en eind states");
|
||||
System.out.println(myDfa.beginStates);
|
||||
System.out.println(myDfa.eindStates);
|
||||
|
||||
}
|
||||
|
||||
public static void Practicum5 () {
|
||||
|
||||
DFA<String> myAutomata = new DFA<String>();
|
||||
// Test 4 minimalisatie
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("0", 'a', "0"));
|
||||
myAutomata.addTransition(new Transition<String>("0", 'b', "1"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("1", 'a', "2"));
|
||||
myAutomata.addTransition(new Transition<String>("1", 'b', "1"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("2", 'a', "0"));
|
||||
myAutomata.addTransition(new Transition<String>("2", 'b', "3"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("3", 'a', "4"));
|
||||
myAutomata.addTransition(new Transition<String>("3", 'b', "1"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("4", 'a', "5"));
|
||||
myAutomata.addTransition(new Transition<String>("4", 'b', "3"));
|
||||
|
||||
myAutomata.addTransition(new Transition<String>("5", 'a', "0"));
|
||||
myAutomata.addTransition(new Transition<String>("5", 'b', "3"));
|
||||
|
||||
myAutomata.defineAsStartState("0");
|
||||
myAutomata.defineAsEndState("2");
|
||||
myAutomata.defineAsEndState("4");
|
||||
|
||||
System.out.println("Ongeminimaliseerd krijgen we:");
|
||||
myAutomata.print();
|
||||
System.out.println("-------");
|
||||
Graph.generateImage(myAutomata, null);
|
||||
|
||||
DFA<String> geminimaliseerd = myAutomata.minimaliseer();
|
||||
System.out.println("Geminimaliseerd krijgen we:");
|
||||
geminimaliseerd.print();
|
||||
System.out.println("------");
|
||||
Graph.generateImage(geminimaliseerd, null);
|
||||
geminimaliseerd.ontkenning();
|
||||
}
|
||||
|
||||
public static void TupleConstructie()
|
||||
{
|
||||
DFA<String> aut1 = new DFA<String>();
|
||||
|
||||
aut1.addTransition(new Transition<String>("1", 'a', "2"));
|
||||
aut1.addTransition(new Transition<String>("1", 'b', "1"));
|
||||
|
||||
aut1.addTransition(new Transition<String>("2", 'a', "1"));
|
||||
aut1.addTransition(new Transition<String>("2", 'b', "2"));
|
||||
|
||||
|
||||
aut1.defineAsStartState("1");
|
||||
aut1.defineAsEndState("1");
|
||||
|
||||
System.out.println("\n\nA1\n--------");
|
||||
System.out.println(Graph.generateImageString(aut1));
|
||||
Graph.generateImage(aut1, "automaat1");
|
||||
|
||||
|
||||
DFA<String> aut2 = new DFA<String>();
|
||||
|
||||
aut2.addTransition(new Transition<String>("1", 'a', "1"));
|
||||
aut2.addTransition(new Transition<String>("1", 'b', "2"));
|
||||
|
||||
aut2.addTransition(new Transition<String>("2", 'a', "1"));
|
||||
aut2.addTransition(new Transition<String>("2", 'b', "3"));
|
||||
|
||||
aut2.addTransition(new Transition<String>("3", 'a', "1"));
|
||||
aut2.addTransition(new Transition<String>("3", 'b', "4"));
|
||||
|
||||
aut2.addTransition(new Transition<String>("4", 'a', "4"));
|
||||
aut2.addTransition(new Transition<String>("4", 'b', "4"));
|
||||
|
||||
aut2.defineAsStartState("1");
|
||||
aut2.defineAsEndState("1");
|
||||
aut2.defineAsEndState("2");
|
||||
|
||||
System.out.println("\n\nA2\n--------");
|
||||
System.out.println(Graph.generateImageString(aut2));
|
||||
Graph.generateImage(aut2, "automaat2");
|
||||
|
||||
DFA<String> en = aut1.en(aut2);
|
||||
|
||||
System.out.println("\n\nEN\n--------");
|
||||
System.out.println(Graph.generateImageString(en));
|
||||
Graph.generateImage(en, "en");
|
||||
|
||||
DFA<String> of = aut1.of(aut2);
|
||||
|
||||
System.out.println("\n\nOF\n--------");
|
||||
System.out.println(Graph.generateImageString(of));
|
||||
Graph.generateImage(of, "of");
|
||||
}
|
||||
|
||||
public static void TestUitOpdrachtBeschrijving() {
|
||||
NDFA<String> ndfa = new NDFA<String>();
|
||||
|
||||
ndfa.addTransition(new Transition<String>("q0", 'a', "q1"));
|
||||
|
||||
ndfa.addTransition(new Transition<String>("q1", 'b', "q2"));
|
||||
ndfa.addTransition(new Transition<String>("q1", 'b', "q0"));
|
||||
|
||||
ndfa.addTransition(new Transition<String>("q2", 'a', "q0"));
|
||||
ndfa.addTransition(new Transition<String>("q2", 'a', "q3"));
|
||||
|
||||
ndfa.addTransition(new Transition<String>("q3", 'a', "q4"));
|
||||
|
||||
ndfa.defineAsStartState("q0");
|
||||
|
||||
ndfa.defineAsEndState("q0");
|
||||
ndfa.defineAsEndState("q4");
|
||||
|
||||
Graph.generateImage(ndfa, "Ndfa");
|
||||
|
||||
DFA<String> dfa = ndfa.toDFA();
|
||||
|
||||
Graph.generateImage(dfa, "Dfa");
|
||||
}
|
||||
|
||||
public static void traverseRegExp(RegExp r) {
|
||||
if (r == null) {
|
||||
return;
|
||||
}
|
||||
System.out.println(r);
|
||||
System.out.println("Printing left ");
|
||||
traverseRegExp(r.links);
|
||||
System.out.println("Printing right");
|
||||
traverseRegExp(r.rechts);
|
||||
System.out.println("----");
|
||||
}
|
||||
|
||||
public static int aantalOperators(RegExp r, int i) {
|
||||
if (r != null) {
|
||||
if (r.links != null) {
|
||||
i++;
|
||||
i = aantalOperators(r.links, i);
|
||||
}
|
||||
if (r.rechts != null) {
|
||||
i++;
|
||||
i = aantalOperators(r.rechts, i);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package com.imegumii;
|
||||
|
||||
/**
|
||||
* Created by kenny on 17-5-2017.
|
||||
*/
|
||||
public class ThompsonConverter {
|
||||
|
||||
private static int count = 0;
|
||||
|
||||
public static NDFA<String> convert(RegExp regex)
|
||||
{
|
||||
NDFA<String> generated = new NDFA<String>();
|
||||
|
||||
convertStatement(regex, generated);
|
||||
|
||||
return generated;
|
||||
}
|
||||
|
||||
private static void convertStatement(RegExp regex, NDFA<String> automata)
|
||||
{
|
||||
switch(regex.operator)
|
||||
{
|
||||
case PLUS:
|
||||
|
||||
//Links
|
||||
convertStatement(regex.links, automata);
|
||||
String endLink1 = automata.eindStates.first();
|
||||
String beginLink1 = automata.beginStates.first();
|
||||
|
||||
String newstart = getState();
|
||||
String newEnd = getState();
|
||||
|
||||
//Repeat
|
||||
automata.addTransition(new Transition<String>(newstart, Transition.EPSILON, beginLink1));
|
||||
automata.addTransition(new Transition<String>(endLink1, Transition.EPSILON, newEnd));
|
||||
automata.addTransition(new Transition<String>(endLink1, Transition.EPSILON, beginLink1));
|
||||
|
||||
automata.clearEindStates();
|
||||
automata.clearBeginStates();
|
||||
|
||||
automata.defineAsStartState(newstart);
|
||||
automata.defineAsEndState(newEnd);
|
||||
|
||||
break;
|
||||
case STER:
|
||||
|
||||
//Links
|
||||
convertStatement(regex.links, automata);
|
||||
String endLink2 = automata.eindStates.first();
|
||||
String beginLink2 = automata.beginStates.first();
|
||||
|
||||
//New states
|
||||
String start2 = getState();
|
||||
String end2 = getState();
|
||||
|
||||
//Repeat and skip
|
||||
automata.addTransition(new Transition<String>(start2, Transition.EPSILON, end2));
|
||||
automata.addTransition(new Transition<String>(endLink2, Transition.EPSILON, beginLink2));
|
||||
automata.addTransition(new Transition<String>(start2, Transition.EPSILON, beginLink2));
|
||||
automata.addTransition(new Transition<String>(endLink2, Transition.EPSILON, end2));
|
||||
|
||||
automata.clearEindStates();
|
||||
automata.clearBeginStates();
|
||||
|
||||
automata.defineAsStartState(start2);
|
||||
automata.defineAsEndState(end2);
|
||||
|
||||
break;
|
||||
case OF:
|
||||
|
||||
//Links
|
||||
convertStatement(regex.links, automata);
|
||||
String topEnd = automata.eindStates.first();
|
||||
String topBegin = automata.beginStates.first();
|
||||
|
||||
//Rechts
|
||||
convertStatement(regex.rechts, automata);
|
||||
String bottomBegin = automata.beginStates.first();
|
||||
String bottomEnd = automata.eindStates.first();
|
||||
|
||||
//New states
|
||||
String start3 = getState();
|
||||
String end3 = getState();
|
||||
|
||||
//Link both
|
||||
automata.addTransition(new Transition<String>(start3, Transition.EPSILON, topBegin));
|
||||
automata.addTransition(new Transition<String>(start3, Transition.EPSILON, bottomBegin));
|
||||
automata.addTransition(new Transition<String>(topEnd, Transition.EPSILON, end3));
|
||||
automata.addTransition(new Transition<String>(bottomEnd, Transition.EPSILON, end3));
|
||||
|
||||
automata.clearEindStates();
|
||||
automata.clearBeginStates();
|
||||
|
||||
automata.defineAsStartState(start3);
|
||||
automata.defineAsEndState(end3);
|
||||
|
||||
|
||||
break;
|
||||
case PUNT:
|
||||
|
||||
//Links
|
||||
convertStatement(regex.links, automata);
|
||||
String endLink = automata.eindStates.first();
|
||||
String newBeginLink = automata.beginStates.first();
|
||||
|
||||
//Rechts
|
||||
convertStatement(regex.rechts, automata);
|
||||
String beginLink = automata.beginStates.first();
|
||||
String newEndLink = automata.eindStates.first();
|
||||
|
||||
//Link both
|
||||
automata.addTransition(new Transition<String>(endLink, Transition.EPSILON, beginLink));
|
||||
|
||||
automata.clearEindStates();
|
||||
automata.clearBeginStates();
|
||||
|
||||
automata.defineAsStartState(newBeginLink);
|
||||
automata.defineAsEndState(newEndLink);
|
||||
|
||||
break;
|
||||
case EEN:
|
||||
|
||||
char[] s = regex.characters.toCharArray();
|
||||
|
||||
automata.clearBeginStates();
|
||||
automata.clearEindStates();
|
||||
|
||||
if(regex.characters.length() <= 0)
|
||||
{
|
||||
String state1 = getState();
|
||||
String state2 = getState();
|
||||
|
||||
Transition<String> t = new Transition<String>(state1, Transition.EPSILON, state2);
|
||||
|
||||
automata.addTransition(t);
|
||||
automata.defineAsStartState(state1);
|
||||
automata.defineAsEndState(state2);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
String prevState = getState();
|
||||
String newState = "";
|
||||
automata.defineAsStartState(prevState);
|
||||
|
||||
for(char c : s)
|
||||
{
|
||||
newState = getState();
|
||||
Transition<String> t = new Transition<String>(prevState, c, newState);
|
||||
prevState = newState;
|
||||
automata.addTransition(t);
|
||||
}
|
||||
|
||||
automata.defineAsEndState(newState);
|
||||
|
||||
break;
|
||||
default:
|
||||
System.out.println("Error #8.1");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getState()
|
||||
{
|
||||
count++;
|
||||
return "q" + count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.imegumii;
|
||||
|
||||
/**
|
||||
* Created by imegumii on 18/04/2017.
|
||||
*/
|
||||
public class Transition <T extends Comparable> implements Comparable<Transition<T>> {
|
||||
public static final char ENDCHAR = '$';
|
||||
|
||||
public static final char EPSILON = 'ε';
|
||||
|
||||
public T vanState;
|
||||
public char symbol;
|
||||
public T naarState;
|
||||
|
||||
public Transition(T from, T to) {
|
||||
this(from, ENDCHAR, to);
|
||||
}
|
||||
|
||||
public Transition(T van, char s, T naar) {
|
||||
this.vanState = van;
|
||||
this.symbol = s;
|
||||
this.naarState = naar;
|
||||
}
|
||||
|
||||
public boolean equals (Object other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
} else if (other instanceof Transition) {
|
||||
Transition otherTransition = (Transition) other;
|
||||
return this.vanState.equals(otherTransition.vanState) && this.naarState.equals(otherTransition.naarState) && this.symbol == otherTransition.symbol;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Transition<T> t) {
|
||||
int vanCompare = vanState.compareTo(t.vanState);
|
||||
int symbolCompare = new Character (symbol).compareTo(t.symbol);
|
||||
int naarCompare = naarState.compareTo(t.naarState);
|
||||
|
||||
return (vanCompare != 0 ? vanCompare : (symbolCompare != 0 ? symbolCompare : naarCompare));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "" + this.vanState + ">" + this.symbol + ">" + this.naarState;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.imegumii;
|
||||
|
||||
/**
|
||||
* Created by kenny on 12-6-2017.
|
||||
*/
|
||||
public class Util {
|
||||
|
||||
public static String randomString(int lenght)
|
||||
{
|
||||
String s = "";
|
||||
String all = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
for(int i = 0; i < lenght; i++)
|
||||
{
|
||||
int rand = (int)(Math.random() * all.length());
|
||||
s += all.substring(rand, rand+1);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.imegumii.ui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by kenny on 8-6-2017.
|
||||
*/
|
||||
public class Frame extends JFrame {
|
||||
|
||||
public Frame()
|
||||
{
|
||||
super("Automata");
|
||||
|
||||
this.setSize(1000, 800);
|
||||
//this.setResizable(false);
|
||||
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
JPanel container = new JPanel(new BorderLayout());
|
||||
container.add(TabPanel.Instance(), BorderLayout.CENTER);
|
||||
container.add(InputPanel.Instance(), BorderLayout.NORTH);
|
||||
container.add(StatusPanel.Instance(), BorderLayout.SOUTH);
|
||||
|
||||
this.setContentPane(container);
|
||||
|
||||
this.setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.imegumii.ui;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.NoninvertibleTransformException;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Created by kenny on 9-6-2017.
|
||||
*/
|
||||
public class GraphImagePanel extends JPanel {
|
||||
|
||||
private BufferedImage image;
|
||||
|
||||
private float scale = 1f;
|
||||
private float x = 0f, y = 0f;
|
||||
private Point dragStartScreen;
|
||||
private Point dragEndScreen;
|
||||
|
||||
public GraphImagePanel(File f)
|
||||
{
|
||||
super();
|
||||
|
||||
this.setBackground(Color.WHITE);
|
||||
|
||||
try {
|
||||
image = ImageIO.read(f);
|
||||
// x = image.getWidth() / 2;
|
||||
// y = image.getHeight() / 2;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
addMouseWheelListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
// System.out.println("Scrolled" + scale);
|
||||
double delta = 0.05f * e.getPreciseWheelRotation();
|
||||
scale += delta;
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
addMouseMotionListener(new MouseMotionListener() {
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
dragEndScreen = e.getPoint();
|
||||
double dx = dragEndScreen.getX() - dragStartScreen.getX();
|
||||
double dy = dragEndScreen.getY() - dragStartScreen.getY();
|
||||
x += dx;
|
||||
y += dy;
|
||||
dragStartScreen = dragEndScreen;
|
||||
dragEndScreen = null;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
addMouseListener(new MouseListener() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
dragStartScreen = e.getPoint();
|
||||
dragEndScreen = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics g){
|
||||
super.paintComponent(g);
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
|
||||
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC));
|
||||
|
||||
if(image != null){
|
||||
|
||||
// int width = this.getWidth();
|
||||
// int height = this.getHeight();
|
||||
//
|
||||
// if(image.getWidth() > image.getHeight()) {
|
||||
// height = (int)((width * image.getHeight()) / image.getWidth());
|
||||
// }
|
||||
// else {
|
||||
// width = (int) ((height * image.getWidth()) / image.getHeight());
|
||||
// }
|
||||
AffineTransform at = new AffineTransform();
|
||||
g.drawLine(-1000, 0, 1000, 0);
|
||||
g.drawLine(0, -1000, 0, 1000);
|
||||
at.scale(1, -1);
|
||||
at.setToTranslation(x, y);
|
||||
at.scale(scale, scale);
|
||||
g2d.drawImage(image, at, this);
|
||||
// g2d.drawImage(image, 0,0, width, height, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
package com.imegumii.ui;
|
||||
|
||||
import com.imegumii.*;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.xpath.SourceTree;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.io.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* Created by kenny on 8-6-2017.
|
||||
*/
|
||||
public class GraphPanel extends JPanel {
|
||||
|
||||
private String name;
|
||||
private File imageLocation;
|
||||
private Automata<String> automata;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public GraphPanel(String name, File f, Automata<String> automata)
|
||||
{
|
||||
super(new BorderLayout());
|
||||
|
||||
this.name = name;
|
||||
this.imageLocation = f;
|
||||
this.automata = automata;
|
||||
|
||||
this.add(new GraphImagePanel(imageLocation), BorderLayout.CENTER);
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
|
||||
buttonPanel.setBackground(Color.WHITE);
|
||||
buttonPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK), BorderFactory.createEmptyBorder(10, 10, 10, 10)));
|
||||
|
||||
JButton closeTab = new JButton("Close");
|
||||
closeTab.setForeground(new Color(200, 100, 100));
|
||||
closeTab.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
TabPanel.Instance().remove(GraphPanel.this);
|
||||
}
|
||||
});
|
||||
|
||||
JButton exportData = new JButton("Export data");
|
||||
exportData.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
String filename = "data." + Util.randomString(5) + ".dot";
|
||||
File file = new File("export/" + filename);
|
||||
|
||||
if(file.exists()){
|
||||
int reply = JOptionPane.showConfirmDialog(null, "The file " + filename + "already exists. Do you want to overwrite it?", "File exists", JOptionPane.YES_NO_OPTION);
|
||||
if (reply != JOptionPane.YES_OPTION) {
|
||||
StatusPanel.Instance().setStatus("Cancelled export");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PrintWriter w = null;
|
||||
try {
|
||||
w = new PrintWriter(file);
|
||||
w.print(automata.getTransitions());
|
||||
w.flush();
|
||||
w.close();
|
||||
StatusPanel.Instance().setStatus("Success: " + filename);
|
||||
} catch (FileNotFoundException e1) {
|
||||
StatusPanel.Instance().setStatus("Something went wrong while exporting the file");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
JButton exportImage = new JButton("Export image");
|
||||
exportImage.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
String filename = "img." + Util.randomString(5) + ".png";
|
||||
File file = new File("export/" + filename);
|
||||
|
||||
if(file.exists()){
|
||||
int reply = JOptionPane.showConfirmDialog(GraphPanel.this, "The file " + filename + "already exists. Do you want to overwrite it?", "File exists", JOptionPane.YES_NO_OPTION);
|
||||
if (reply != JOptionPane.YES_OPTION) {
|
||||
StatusPanel.Instance().setStatus("Cancelled export");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
FileUtils.copyFile(f, file);
|
||||
StatusPanel.Instance().setStatus("Success: " + filename);
|
||||
} catch (IOException e1) {
|
||||
StatusPanel.Instance().setStatus("Something went wrong while exporting the file");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
JButton minimizeButton = new JButton("Hopcroft");
|
||||
minimizeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
if(automata.type == Importable.Type.NDFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting to DFA ", 20);
|
||||
DFA<String> convert = ((NDFA<String>) automata).toDFA();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating image for DFA", 30);
|
||||
File img = Graph.generateImage(convert);
|
||||
TabPanel.Instance().addGraph(name, img, convert);
|
||||
|
||||
StatusPanel.Instance().setStatus("Minimizing DFA", 50);
|
||||
DFA<String> mini = convert.minimaliseerHopcroft();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating minimized image", 70);
|
||||
File img2 = Graph.generateImage(mini);
|
||||
TabPanel.Instance().addGraph(name, img2, mini);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
else if(automata.type == Importable.Type.DFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Minimizing dfa." + name, 40);
|
||||
DFA<String> dfa = (DFA<String>) automata;
|
||||
DFA<String> mini = dfa.minimaliseerHopcroft();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating minimized image", 60);
|
||||
File img3 = Graph.generateImage(mini);
|
||||
TabPanel.Instance().addGraph(name, img3, mini);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
JButton minimize2Button = new JButton("Bryzowski");
|
||||
minimize2Button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
if(automata.type == Importable.Type.NDFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting to DFA ", 20);
|
||||
DFA<String> convert = ((NDFA<String>) automata).toDFA();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating image for DFA", 30);
|
||||
File img = Graph.generateImage(convert);
|
||||
TabPanel.Instance().addGraph(name, img, convert);
|
||||
|
||||
StatusPanel.Instance().setStatus("Minimizing DFA", 50);
|
||||
DFA<String> mini = convert.minimaliseer();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating minimized image", 70);
|
||||
File img2 = Graph.generateImage(mini);
|
||||
TabPanel.Instance().addGraph(name, img2, mini);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
else if(automata.type == Importable.Type.DFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Minimizing dfa." + name, 40);
|
||||
DFA<String> dfa = (DFA<String>) automata;
|
||||
DFA<String> mini = dfa.minimaliseer();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating minimized image", 60);
|
||||
File img3 = Graph.generateImage(mini);
|
||||
TabPanel.Instance().addGraph(name, img3, mini);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
JButton toDfaButton = new JButton("to DFA");
|
||||
toDfaButton.addActionListener(e -> {
|
||||
BackgroundWorker.instance().addWorker(() -> {
|
||||
StatusPanel.Instance().setStatus("Converting to DFA ", 10);
|
||||
DFA<String> convert = ((NDFA<String>) automata).toDFA();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating image for DFA", 50);
|
||||
File img = Graph.generateImage(convert);
|
||||
TabPanel.Instance().addGraph(name, img, convert);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
});
|
||||
});
|
||||
|
||||
JButton reverseButton = new JButton("Reverse");
|
||||
reverseButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
StatusPanel.Instance().setStatus("Reversing ", 20);
|
||||
|
||||
NDFA<String> reverse = ((DFA<String>) automata).reverse();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating reversed image", 70);
|
||||
|
||||
File img = Graph.generateImage(reverse);
|
||||
|
||||
TabPanel.Instance().addGraph("Reverse " + name, img, reverse);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
JButton notButton = new JButton("Not");
|
||||
notButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
StatusPanel.Instance().setStatus("Nothing ", 20);
|
||||
|
||||
DFA<String> not = ((DFA<String>) automata).ontkenning();
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating not image", 70);
|
||||
|
||||
File img = Graph.generateImage(not);
|
||||
|
||||
TabPanel.Instance().addGraph("Not " + name, img, not);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
JButton showPopup = new JButton("Show popup");
|
||||
showPopup.addActionListener(e -> {
|
||||
new PopupFrame(name, automata);
|
||||
});
|
||||
|
||||
JButton showGrammar = new JButton("Show grammar");
|
||||
showGrammar.addActionListener(e -> {
|
||||
BackgroundWorker.instance().addWorker(() -> {
|
||||
GrammarConverter c = new GrammarConverter();
|
||||
new TextPanel("Grammar", c.toGrammar((NDFA<String>) automata).printToString());
|
||||
});
|
||||
});
|
||||
|
||||
buttonPanel.add(Box.createHorizontalGlue());
|
||||
|
||||
if(automata.type == Importable.Type.DFA) {
|
||||
buttonPanel.add(notButton);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
buttonPanel.add(reverseButton);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
}
|
||||
|
||||
buttonPanel.add(showPopup);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
if (automata.type == Importable.Type.NDFA) {
|
||||
buttonPanel.add(showGrammar);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
buttonPanel.add(toDfaButton);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
}
|
||||
|
||||
buttonPanel.add(minimize2Button);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
buttonPanel.add(minimizeButton);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
buttonPanel.add(exportImage);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
buttonPanel.add(exportData);
|
||||
buttonPanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
buttonPanel.add(closeTab);
|
||||
|
||||
this.add(buttonPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
package com.imegumii.ui;
|
||||
|
||||
import com.imegumii.*;
|
||||
import jdk.nashorn.internal.runtime.regexp.joni.Regex;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by kenny on 8-6-2017.
|
||||
*/
|
||||
public class InputPanel extends JPanel {
|
||||
|
||||
private static InputPanel panel;
|
||||
|
||||
public static InputPanel Instance()
|
||||
{
|
||||
if(panel == null)
|
||||
panel = new InputPanel();
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private InputPanel()
|
||||
{
|
||||
super();
|
||||
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
|
||||
|
||||
JPanel topPanel = new JPanel();
|
||||
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
|
||||
topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
|
||||
|
||||
topPanel.add(new JLabel("Regular expression"));
|
||||
topPanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
JTextField text = new JTextField();
|
||||
|
||||
topPanel.add(text);
|
||||
|
||||
topPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
JButton button = new JButton("Generate");
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
String regS = text.getText().trim();
|
||||
String name = regS;
|
||||
|
||||
StatusPanel.Instance().setStatus("Parsing REGEX", 20);
|
||||
|
||||
RegExp regex = new RegExp();
|
||||
regex = regex.naarRegExp(regS);
|
||||
|
||||
StatusPanel.Instance().setStatus("Converting REGEX to NDFA", 40);
|
||||
|
||||
NDFA<String> ndfa = ThompsonConverter.convert(regex);
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating image for NDFA", 70);
|
||||
|
||||
File img = Graph.generateImage(ndfa);
|
||||
|
||||
TabPanel.Instance().addGraph(name, img, ndfa);
|
||||
|
||||
// StatusPanel.Instance().setStatus("Generating taal", 90);
|
||||
|
||||
// new PopupFrame(name, regex);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
topPanel.add(button);
|
||||
|
||||
topPanel.add(Box.createHorizontalGlue());
|
||||
this.add(topPanel);
|
||||
|
||||
|
||||
//------------
|
||||
//BOTTOM PANEL
|
||||
//-----------
|
||||
|
||||
JPanel bottomPanel = new JPanel();
|
||||
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS));
|
||||
bottomPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
|
||||
|
||||
bottomPanel.add(new JLabel("File"));
|
||||
bottomPanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
JComboBox<String> fileCombo = new JComboBox<String>(findFiles());
|
||||
|
||||
bottomPanel.add(fileCombo);
|
||||
|
||||
bottomPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
JButton fileButton = new JButton("Generate");
|
||||
fileButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
;
|
||||
StatusPanel.Instance().setStatus("Parsing file", 10);
|
||||
|
||||
String file = (String)fileCombo.getSelectedItem();
|
||||
String name = file.replaceAll(".dot", "");
|
||||
|
||||
Importable p = FileParser.read(file);
|
||||
|
||||
if(p.type == Importable.Type.NDFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Generating image for NDFA", 60);
|
||||
NDFA<String> ndfa = (NDFA<String>)p;
|
||||
|
||||
File f = Graph.generateImage(ndfa);
|
||||
|
||||
TabPanel.Instance().addGraph(name, f, ndfa);
|
||||
}
|
||||
|
||||
if(p.type == Importable.Type.DFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Generating image for DFA", 60);
|
||||
DFA<String> dfa = (DFA<String>)p;
|
||||
|
||||
File f = Graph.generateImage(dfa);
|
||||
|
||||
TabPanel.Instance().addGraph(name, f, dfa);
|
||||
}
|
||||
|
||||
if(p.type == Importable.Type.REGEX)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting REGEX to NDFA", 40);
|
||||
RegExp regex = (RegExp) p;
|
||||
|
||||
NDFA<String> ndfa = ThompsonConverter.convert(regex);
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating image for NDFA", 70);
|
||||
|
||||
File f = Graph.generateImage(ndfa);
|
||||
|
||||
TabPanel.Instance().addGraph(name, f, ndfa);
|
||||
}
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
bottomPanel.add(fileButton);
|
||||
|
||||
this.add(bottomPanel);
|
||||
|
||||
|
||||
|
||||
//------------
|
||||
//Advanced PANEL
|
||||
//-----------
|
||||
|
||||
JPanel advPanel = new JPanel();
|
||||
advPanel.setLayout(new BoxLayout(advPanel, BoxLayout.LINE_AXIS));
|
||||
advPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
|
||||
|
||||
JComboBox<String> f1Combo = new JComboBox<String>(findFiles());
|
||||
JComboBox<String> f2Combo = new JComboBox<String>(findFiles());
|
||||
|
||||
JButton orButton = new JButton("or");
|
||||
orButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
StatusPanel.Instance().setStatus("Parsing files", 10);
|
||||
|
||||
String file1 = (String)f1Combo.getSelectedItem();
|
||||
String name1 = file1.replaceAll(".dot", "");
|
||||
String file2 = (String)f2Combo.getSelectedItem();
|
||||
String name2 = file2.replaceAll(".dot", "");
|
||||
|
||||
Importable p1 = FileParser.read(file1);
|
||||
Importable p2 = FileParser.read(file1);
|
||||
|
||||
DFA<String> dfa1 = null;
|
||||
|
||||
if(p1.type == Importable.Type.NDFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting NDFA to DFA", 30);
|
||||
NDFA<String> ndfa1 = (NDFA<String>)p1;
|
||||
dfa1 = ndfa1.toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
if(p1.type == Importable.Type.DFA)
|
||||
{
|
||||
dfa1 = (DFA<String>)p1;
|
||||
}
|
||||
if(p1.type == Importable.Type.REGEX)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting REGEX to DFA", 30);
|
||||
RegExp regex = (RegExp) p1;
|
||||
NDFA<String> ndfa1 = ThompsonConverter.convert(regex);
|
||||
dfa1 = ndfa1.toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
|
||||
DFA<String> dfa2 = null;
|
||||
|
||||
if(p2.type == Importable.Type.NDFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting NDFA to DFA", 50);
|
||||
NDFA<String> ndfa2 = (NDFA<String>)p2;
|
||||
dfa2 = ndfa2.toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
if(p2.type == Importable.Type.DFA)
|
||||
{
|
||||
dfa2 = (DFA<String>)p2;
|
||||
}
|
||||
if(p2.type == Importable.Type.REGEX)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting REGEX to DFA", 50);
|
||||
RegExp regex2 = (RegExp) p2;
|
||||
NDFA<String> ndfa2 = ThompsonConverter.convert(regex2);
|
||||
dfa2 = ndfa2.toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
|
||||
StatusPanel.Instance().setStatus("Executing or operation", 65);
|
||||
DFA<String> of = dfa1.of(dfa2);
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating image", 80);
|
||||
|
||||
File f = Graph.generateImage(of);
|
||||
TabPanel.Instance().addGraph(name1 + " or " + name2, f, of);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
JButton andButton = new JButton("and");
|
||||
andButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
StatusPanel.Instance().setStatus("Parsing files", 10);
|
||||
|
||||
String file1 = (String)f1Combo.getSelectedItem();
|
||||
String name1 = file1.replaceAll(".dot", "");
|
||||
String file2 = (String)f2Combo.getSelectedItem();
|
||||
String name2 = file2.replaceAll(".dot", "");
|
||||
|
||||
Importable p1 = FileParser.read(file1);
|
||||
Importable p2 = FileParser.read(file1);
|
||||
|
||||
DFA<String> dfa1 = null;
|
||||
|
||||
if(p1.type == Importable.Type.NDFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting NDFA to DFA", 30);
|
||||
NDFA<String> ndfa1 = (NDFA<String>)p1;
|
||||
dfa1 = ndfa1.toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
if(p1.type == Importable.Type.DFA)
|
||||
{
|
||||
dfa1 = (DFA<String>)p1;
|
||||
}
|
||||
if(p1.type == Importable.Type.REGEX)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting REGEX to DFA", 30);
|
||||
RegExp regex = (RegExp) p1;
|
||||
NDFA<String> ndfa1 = ThompsonConverter.convert(regex);
|
||||
dfa1 = ndfa1.toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
|
||||
DFA<String> dfa2 = null;
|
||||
|
||||
if(p2.type == Importable.Type.NDFA)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting NDFA to DFA", 50);
|
||||
NDFA<String> ndfa2 = (NDFA<String>)p2;
|
||||
dfa2 = ndfa2.toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
if(p2.type == Importable.Type.DFA)
|
||||
{
|
||||
dfa2 = (DFA<String>)p2;
|
||||
}
|
||||
if(p2.type == Importable.Type.REGEX)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting REGEX to DFA", 50);
|
||||
RegExp regex2 = (RegExp) p2;
|
||||
NDFA<String> ndfa2 = ThompsonConverter.convert(regex2);
|
||||
dfa2 = ndfa2.toDFA().minimaliseerHopcroft();
|
||||
}
|
||||
|
||||
StatusPanel.Instance().setStatus("Executing and operation", 65);
|
||||
DFA<String> en = dfa1.en(dfa2);
|
||||
|
||||
StatusPanel.Instance().setStatus("Generating image", 80);
|
||||
|
||||
File f = Graph.generateImage(en);
|
||||
TabPanel.Instance().addGraph(name1 + " and " + name2, f, en);
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
JButton equalsButton = new JButton("equals");
|
||||
equalsButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
BackgroundWorker.instance().addWorker(new BackgroundWorker.Worker() {
|
||||
@Override
|
||||
public void execute() {
|
||||
StatusPanel.Instance().setStatus("Parsing files", 10);
|
||||
|
||||
String file1 = (String)f1Combo.getSelectedItem();
|
||||
String name1 = file1.replaceAll(".dot", "");
|
||||
String file2 = (String)f2Combo.getSelectedItem();
|
||||
String name2 = file2.replaceAll(".dot", "");
|
||||
|
||||
Importable p1 = FileParser.read(file1);
|
||||
Importable p2 = FileParser.read(file1);
|
||||
|
||||
Automata<String> aut = null;
|
||||
|
||||
if(p1.type == Importable.Type.NDFA )
|
||||
{
|
||||
aut = (NDFA<String>)p1;
|
||||
}
|
||||
if(p1.type == Importable.Type.DFA)
|
||||
{
|
||||
aut = (DFA<String>)p1;
|
||||
}
|
||||
if(p1.type == Importable.Type.REGEX)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting REGEX to NDFA", 30);
|
||||
RegExp regex = (RegExp) p1;
|
||||
aut = (NDFA<String>)ThompsonConverter.convert(regex);
|
||||
}
|
||||
|
||||
Automata<String> aut2 = null;
|
||||
|
||||
if(p2.type == Importable.Type.NDFA)
|
||||
{
|
||||
aut2 = (NDFA<String>)p2;
|
||||
}
|
||||
if(p2.type == Importable.Type.DFA)
|
||||
{
|
||||
aut2 = (DFA<String>)p2;
|
||||
}
|
||||
if(p2.type == Importable.Type.REGEX)
|
||||
{
|
||||
StatusPanel.Instance().setStatus("Converting REGEX to NDFA", 50);
|
||||
RegExp regex2 = (RegExp) p2;
|
||||
aut2 = (NDFA<String>)ThompsonConverter.convert(regex2);
|
||||
}
|
||||
|
||||
StatusPanel.Instance().setStatus("Executing equals operation", 80);
|
||||
|
||||
boolean equals = aut.equals(aut2);
|
||||
|
||||
new TextPanel(name1 + " equals " + name2, (equals?"They are equal":"They are not equal"));
|
||||
|
||||
StatusPanel.Instance().setStatus("Done", 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
advPanel.add(f1Combo);
|
||||
advPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
advPanel.add(equalsButton);
|
||||
advPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
advPanel.add(andButton);
|
||||
advPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
advPanel.add(orButton);
|
||||
advPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
advPanel.add(f2Combo);
|
||||
advPanel.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
this.add(advPanel);
|
||||
}
|
||||
|
||||
private String[] findFiles()
|
||||
{
|
||||
File folder = new File("input");
|
||||
File[] listOfFiles = folder.listFiles();
|
||||
|
||||
ArrayList<String> fileNames = new ArrayList<String>();
|
||||
|
||||
for (int i = 0; i < listOfFiles.length; i++) {
|
||||
if (listOfFiles[i].isFile() && listOfFiles[i].getName().endsWith(".dot")) {
|
||||
fileNames.add(listOfFiles[i].getName());
|
||||
}
|
||||
}
|
||||
|
||||
String[] files = new String[fileNames.size()];
|
||||
files = fileNames.toArray(files);
|
||||
|
||||
return files;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package com.imegumii.ui;
|
||||
|
||||
import com.imegumii.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Created by kenny on 12-6-2017.
|
||||
*/
|
||||
public class PopupFrame extends JFrame {
|
||||
|
||||
boolean selected = false;
|
||||
|
||||
public PopupFrame(String name, Importable r)
|
||||
{
|
||||
super(name);
|
||||
|
||||
this.setSize(600, 600);
|
||||
//this.setResizable(false);
|
||||
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
|
||||
DFA<String> tempDfa = null;
|
||||
|
||||
if (r.type == Importable.Type.DFA) {
|
||||
tempDfa = ((DFA<String>) r).minimaliseer();
|
||||
} else if (r.type == Importable.Type.REGEX) {
|
||||
tempDfa = ThompsonConverter.convert((RegExp) r).toDFA().minimaliseer();
|
||||
} else if (r.type == Importable.Type.NDFA) {
|
||||
tempDfa = ((NDFA<String>) r).toDFA().minimaliseer();
|
||||
}
|
||||
|
||||
JPanel container = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel topPanel = new JPanel();
|
||||
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
|
||||
topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
|
||||
|
||||
JPanel acceptPanel = new JPanel();
|
||||
acceptPanel.setLayout(new BoxLayout(acceptPanel, BoxLayout.LINE_AXIS));
|
||||
acceptPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
|
||||
|
||||
JPanel generatePanel = new JPanel();
|
||||
generatePanel.setLayout(new BoxLayout(generatePanel, BoxLayout.LINE_AXIS));
|
||||
generatePanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
|
||||
|
||||
JPanel textPanel = new JPanel();
|
||||
textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS));
|
||||
textPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
|
||||
|
||||
JTextArea textArea = new JTextArea();
|
||||
JScrollPane scrollPane = new JScrollPane(textArea);
|
||||
|
||||
JTextArea acceptArea = new JTextArea();
|
||||
JScrollPane acceptScrollPane = new JScrollPane(acceptArea);
|
||||
|
||||
JTextField operaties = new JTextField();
|
||||
JTextField lengte = new JTextField();
|
||||
|
||||
JButton generateButton = new JButton("Generate language");
|
||||
// JButton cancelButton = new JButton("Cancel operation");
|
||||
JCheckBox checkBox = new JCheckBox("Negate");
|
||||
|
||||
JTextField acceptString = new JTextField();
|
||||
|
||||
JButton acceptButton = new JButton("Accept string");
|
||||
DFA<String> minimizedDfa = tempDfa;
|
||||
generateButton.addActionListener(e -> {
|
||||
textArea.setText(""); // reset
|
||||
BackgroundWorker.instance().addWorker(() -> {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
// Taal t = r.getTaal(Integer.parseInt(operaties.getText()), Integer.parseInt(lengte.getText()));
|
||||
SortedSet<String> symbols = minimizedDfa.geefTaalTotLengte(Integer.parseInt(lengte.getText())).getSymbols();
|
||||
SortedSet<String> actuallyContains = new TreeSet<>();
|
||||
if (selected) {
|
||||
for (String symbol : symbols) {
|
||||
if (!minimizedDfa.accepteer(symbol)) {
|
||||
actuallyContains.add(symbol);
|
||||
}
|
||||
}
|
||||
textArea.append("The language does not contain " + actuallyContains.size() + " strings out of a max of " + symbols.size() + "\n");
|
||||
} else {
|
||||
for (String symbol : symbols) {
|
||||
if (minimizedDfa.accepteer(symbol)) {
|
||||
actuallyContains.add(symbol);
|
||||
}
|
||||
}
|
||||
textArea.append("The language contains " + actuallyContains.size() + " strings out of a max of " + symbols.size() + "\n");
|
||||
}
|
||||
textArea.append("It took " + (System.currentTimeMillis() - currentTime) + " milliseconds to generate and filter them\n");
|
||||
actuallyContains.forEach(s -> textArea.append("String: " + s + "\n"));
|
||||
});
|
||||
});
|
||||
|
||||
checkBox.addItemListener(e -> {
|
||||
if (e.getStateChange() == ItemEvent.DESELECTED) {
|
||||
selected = false;
|
||||
} else {
|
||||
selected = true;
|
||||
}
|
||||
});
|
||||
|
||||
// cancelButton.addActionListener(e -> {
|
||||
// BackgroundWorker.instance().cancel();
|
||||
// });
|
||||
|
||||
acceptButton.addActionListener(e -> {
|
||||
BackgroundWorker.instance().addWorker(() -> {
|
||||
try {
|
||||
acceptArea.getDocument().insertString(0, "Does the regex accept " + acceptString.getText() + " ? " + (minimizedDfa.accepteer(acceptString.getText()) ? "yes" : "no") + "\n", null);
|
||||
} catch (BadLocationException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
operaties.setText("4");
|
||||
lengte.setText("5");
|
||||
|
||||
textPanel.add(scrollPane);
|
||||
textPanel.add(acceptScrollPane);
|
||||
container.add(textPanel, BorderLayout.CENTER);
|
||||
|
||||
generatePanel.add(generateButton);
|
||||
generatePanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
generatePanel.add(checkBox);
|
||||
generatePanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
// generatePanel.add(cancelButton);
|
||||
// generatePanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
generatePanel.add(new JLabel("Max operations"));
|
||||
generatePanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
generatePanel.add(operaties);
|
||||
generatePanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
generatePanel.add(new JLabel("Max length"));
|
||||
generatePanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
generatePanel.add(lengte);
|
||||
|
||||
acceptPanel.add(acceptButton);
|
||||
acceptPanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
acceptPanel.add(new JLabel("Input a string"));
|
||||
acceptPanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
acceptPanel.add(acceptString);
|
||||
acceptPanel.add(Box.createRigidArea(new Dimension(10,0)));
|
||||
|
||||
topPanel.add(generatePanel);
|
||||
topPanel.add(acceptPanel);
|
||||
|
||||
container.add(topPanel, BorderLayout.NORTH);
|
||||
|
||||
this.setContentPane(container);
|
||||
|
||||
this.setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.imegumii.ui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Created by kenny on 9-6-2017.
|
||||
*/
|
||||
public class StatusPanel extends JPanel {
|
||||
|
||||
private static StatusPanel panel;
|
||||
|
||||
private JLabel status;
|
||||
private JProgressBar progress;
|
||||
|
||||
public static StatusPanel Instance()
|
||||
{
|
||||
if(panel == null)
|
||||
panel = new StatusPanel();
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
public StatusPanel()
|
||||
{
|
||||
super();
|
||||
this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
|
||||
this.setBackground(Color.LIGHT_GRAY);
|
||||
this.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
|
||||
|
||||
progress = new JProgressBar();
|
||||
progress.setValue(0);
|
||||
progress.setPreferredSize(new Dimension(250, 0));
|
||||
|
||||
status = new JLabel("Application ready");
|
||||
|
||||
this.add(progress);
|
||||
this.add(Box.createHorizontalGlue());
|
||||
this.add(status);
|
||||
}
|
||||
|
||||
public void setStatus(String text, int progress)
|
||||
{
|
||||
this.progress.setValue(progress);
|
||||
this.status.setText(text);
|
||||
}
|
||||
|
||||
public void setStatus(int progress)
|
||||
{
|
||||
this.progress.setValue(progress);
|
||||
}
|
||||
|
||||
public void setStatus(String text)
|
||||
{
|
||||
this.status.setText(text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.imegumii.ui;
|
||||
|
||||
import com.imegumii.Automata;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Created by kenny on 9-6-2017.
|
||||
*/
|
||||
public class TabPanel extends JTabbedPane {
|
||||
|
||||
private static TabPanel panel;
|
||||
|
||||
public static TabPanel Instance()
|
||||
{
|
||||
if(panel == null)
|
||||
panel = new TabPanel();
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private TabPanel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public void addGraph(String name, File image, Automata<String> a)
|
||||
{
|
||||
String n = a.type.toString() + ": " + name;
|
||||
|
||||
this.addTab(n, new GraphPanel(name, image, a));
|
||||
this.setSelectedIndex(this.getTabCount() - 1);
|
||||
}
|
||||
|
||||
public void removeGraph(GraphPanel component)
|
||||
{
|
||||
this.remove(component);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.imegumii.ui;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Created by imegumii on 13/06/2017.
|
||||
*/
|
||||
public class TextPanel extends JFrame {
|
||||
public TextPanel (String name, String text) {
|
||||
super(name);
|
||||
this.setSize(600, 600);
|
||||
//this.setResizable(false);
|
||||
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
|
||||
JTextArea textArea = new JTextArea();
|
||||
JScrollPane scrollPane = new JScrollPane(textArea);
|
||||
|
||||
textArea.append(text);
|
||||
|
||||
this.setContentPane(scrollPane);
|
||||
|
||||
this.setVisible(true);
|
||||
}
|
||||
}
|
||||