diff --git a/FormeleMethoden.iml b/FormeleMethoden.iml
new file mode 100644
index 0000000..4e83dc3
--- /dev/null
+++ b/FormeleMethoden.iml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/images/1048780942.png b/images/1048780942.png
new file mode 100644
index 0000000..27f446a
Binary files /dev/null and b/images/1048780942.png differ
diff --git a/images/1068821280.png b/images/1068821280.png
new file mode 100644
index 0000000..86e5b53
Binary files /dev/null and b/images/1068821280.png differ
diff --git a/images/1105752207.png b/images/1105752207.png
new file mode 100644
index 0000000..ace387d
Binary files /dev/null and b/images/1105752207.png differ
diff --git a/images/1136662765.png b/images/1136662765.png
new file mode 100644
index 0000000..0ec401f
Binary files /dev/null and b/images/1136662765.png differ
diff --git a/images/1220868996.png b/images/1220868996.png
new file mode 100644
index 0000000..60a4cbf
Binary files /dev/null and b/images/1220868996.png differ
diff --git a/images/1261661665.png b/images/1261661665.png
new file mode 100644
index 0000000..86e5b53
Binary files /dev/null and b/images/1261661665.png differ
diff --git a/images/1288384970.png b/images/1288384970.png
new file mode 100644
index 0000000..aea5fa4
Binary files /dev/null and b/images/1288384970.png differ
diff --git a/images/1289763598.png b/images/1289763598.png
new file mode 100644
index 0000000..186f168
Binary files /dev/null and b/images/1289763598.png differ
diff --git a/images/1462205525.png b/images/1462205525.png
new file mode 100644
index 0000000..5691ef9
Binary files /dev/null and b/images/1462205525.png differ
diff --git a/images/1494429597.png b/images/1494429597.png
new file mode 100644
index 0000000..aea5fa4
Binary files /dev/null and b/images/1494429597.png differ
diff --git a/images/1509687272.png b/images/1509687272.png
new file mode 100644
index 0000000..9e7c1a7
Binary files /dev/null and b/images/1509687272.png differ
diff --git a/images/156596164.png b/images/156596164.png
new file mode 100644
index 0000000..915844e
Binary files /dev/null and b/images/156596164.png differ
diff --git a/images/157529001.png b/images/157529001.png
new file mode 100644
index 0000000..d28d2f7
Binary files /dev/null and b/images/157529001.png differ
diff --git a/images/1653777739.png b/images/1653777739.png
new file mode 100644
index 0000000..ba9e5ba
Binary files /dev/null and b/images/1653777739.png differ
diff --git a/images/1740047789.png b/images/1740047789.png
new file mode 100644
index 0000000..8387455
Binary files /dev/null and b/images/1740047789.png differ
diff --git a/images/1862002344.png b/images/1862002344.png
new file mode 100644
index 0000000..40b6a36
Binary files /dev/null and b/images/1862002344.png differ
diff --git a/images/1954850820.png b/images/1954850820.png
new file mode 100644
index 0000000..8d7d0bf
Binary files /dev/null and b/images/1954850820.png differ
diff --git a/images/1963223277.png b/images/1963223277.png
new file mode 100644
index 0000000..e85de4a
Binary files /dev/null and b/images/1963223277.png differ
diff --git a/images/203837073.png b/images/203837073.png
new file mode 100644
index 0000000..d170308
Binary files /dev/null and b/images/203837073.png differ
diff --git a/images/207639314.png b/images/207639314.png
new file mode 100644
index 0000000..5691ef9
Binary files /dev/null and b/images/207639314.png differ
diff --git a/images/2087861873.png b/images/2087861873.png
new file mode 100644
index 0000000..3ba01b3
Binary files /dev/null and b/images/2087861873.png differ
diff --git a/images/2112867385.png b/images/2112867385.png
new file mode 100644
index 0000000..1dcd20f
Binary files /dev/null and b/images/2112867385.png differ
diff --git a/images/302729159.png b/images/302729159.png
new file mode 100644
index 0000000..42d8984
Binary files /dev/null and b/images/302729159.png differ
diff --git a/images/312365023.png b/images/312365023.png
new file mode 100644
index 0000000..5bd41f0
Binary files /dev/null and b/images/312365023.png differ
diff --git a/images/318078938.png b/images/318078938.png
new file mode 100644
index 0000000..b01ae97
Binary files /dev/null and b/images/318078938.png differ
diff --git a/images/336201256.png b/images/336201256.png
new file mode 100644
index 0000000..dd7a5f5
Binary files /dev/null and b/images/336201256.png differ
diff --git a/images/383269663.png b/images/383269663.png
new file mode 100644
index 0000000..a1c29ad
Binary files /dev/null and b/images/383269663.png differ
diff --git a/images/389888761.png b/images/389888761.png
new file mode 100644
index 0000000..d571a96
Binary files /dev/null and b/images/389888761.png differ
diff --git a/images/459301452.png b/images/459301452.png
new file mode 100644
index 0000000..ba9e5ba
Binary files /dev/null and b/images/459301452.png differ
diff --git a/images/495694988.png b/images/495694988.png
new file mode 100644
index 0000000..21b3767
Binary files /dev/null and b/images/495694988.png differ
diff --git a/images/509460607.png b/images/509460607.png
new file mode 100644
index 0000000..44aab15
Binary files /dev/null and b/images/509460607.png differ
diff --git a/images/603413993.png b/images/603413993.png
new file mode 100644
index 0000000..fdf2387
Binary files /dev/null and b/images/603413993.png differ
diff --git a/images/634333128.png b/images/634333128.png
new file mode 100644
index 0000000..153ccf5
Binary files /dev/null and b/images/634333128.png differ
diff --git a/images/654648053.png b/images/654648053.png
new file mode 100644
index 0000000..dfa332c
Binary files /dev/null and b/images/654648053.png differ
diff --git a/images/655304795.png b/images/655304795.png
new file mode 100644
index 0000000..42d8984
Binary files /dev/null and b/images/655304795.png differ
diff --git a/images/664788275.png b/images/664788275.png
new file mode 100644
index 0000000..ba49623
Binary files /dev/null and b/images/664788275.png differ
diff --git a/images/703135839.png b/images/703135839.png
new file mode 100644
index 0000000..5bd41f0
Binary files /dev/null and b/images/703135839.png differ
diff --git a/images/723574364.png b/images/723574364.png
new file mode 100644
index 0000000..aea5fa4
Binary files /dev/null and b/images/723574364.png differ
diff --git a/images/754924751.png b/images/754924751.png
new file mode 100644
index 0000000..bf80bd0
Binary files /dev/null and b/images/754924751.png differ
diff --git a/images/765439555.png b/images/765439555.png
new file mode 100644
index 0000000..8563547
Binary files /dev/null and b/images/765439555.png differ
diff --git a/images/792217629.png b/images/792217629.png
new file mode 100644
index 0000000..86b5331
Binary files /dev/null and b/images/792217629.png differ
diff --git a/images/821989711.png b/images/821989711.png
new file mode 100644
index 0000000..28bb4dc
Binary files /dev/null and b/images/821989711.png differ
diff --git a/images/851412221.png b/images/851412221.png
new file mode 100644
index 0000000..86dff9a
Binary files /dev/null and b/images/851412221.png differ
diff --git a/images/982413416.png b/images/982413416.png
new file mode 100644
index 0000000..5d03914
Binary files /dev/null and b/images/982413416.png differ
diff --git a/images/cdfa.png b/images/cdfa.png
new file mode 100644
index 0000000..5befd75
Binary files /dev/null and b/images/cdfa.png differ
diff --git a/images/dfa.png b/images/dfa.png
new file mode 100644
index 0000000..5bd41f0
Binary files /dev/null and b/images/dfa.png differ
diff --git a/images/dfa1.png b/images/dfa1.png
new file mode 100644
index 0000000..5bd41f0
Binary files /dev/null and b/images/dfa1.png differ
diff --git a/images/dfa2.png b/images/dfa2.png
new file mode 100644
index 0000000..5691ef9
Binary files /dev/null and b/images/dfa2.png differ
diff --git a/images/dfa4.png b/images/dfa4.png
new file mode 100644
index 0000000..a49e57b
Binary files /dev/null and b/images/dfa4.png differ
diff --git a/images/mcdfa.png b/images/mcdfa.png
new file mode 100644
index 0000000..ce91539
Binary files /dev/null and b/images/mcdfa.png differ
diff --git a/images/ndfa1.png b/images/ndfa1.png
new file mode 100644
index 0000000..5e9c4b5
Binary files /dev/null and b/images/ndfa1.png differ
diff --git a/images/ndfa2.png b/images/ndfa2.png
new file mode 100644
index 0000000..e85de4a
Binary files /dev/null and b/images/ndfa2.png differ
diff --git a/images/ndfa3.png b/images/ndfa3.png
new file mode 100644
index 0000000..aea5fa4
Binary files /dev/null and b/images/ndfa3.png differ
diff --git a/images/regex1.png b/images/regex1.png
new file mode 100644
index 0000000..cc90c66
Binary files /dev/null and b/images/regex1.png differ
diff --git a/images/regex3.png b/images/regex3.png
new file mode 100644
index 0000000..27bc191
Binary files /dev/null and b/images/regex3.png differ
diff --git a/images/test.png b/images/test.png
new file mode 100644
index 0000000..50f7c34
Binary files /dev/null and b/images/test.png differ
diff --git a/input/dfa1.dot b/input/dfa1.dot
new file mode 100644
index 0000000..cbc32cc
--- /dev/null
+++ b/input/dfa1.dot
@@ -0,0 +1,7 @@
+DFA
+B0
+E1
+0>a>1
+0>b>1
+1>a>0
+1>b>1
\ No newline at end of file
diff --git a/input/dfa2.dot b/input/dfa2.dot
new file mode 100644
index 0000000..4e2b9d3
--- /dev/null
+++ b/input/dfa2.dot
@@ -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
\ No newline at end of file
diff --git a/input/dfa3.dot b/input/dfa3.dot
new file mode 100644
index 0000000..4473d15
--- /dev/null
+++ b/input/dfa3.dot
@@ -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
\ No newline at end of file
diff --git a/input/dfa4.dot b/input/dfa4.dot
new file mode 100644
index 0000000..fced27f
--- /dev/null
+++ b/input/dfa4.dot
@@ -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
diff --git a/input/ndfa1.dot b/input/ndfa1.dot
new file mode 100644
index 0000000..2942a7b
--- /dev/null
+++ b/input/ndfa1.dot
@@ -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
\ No newline at end of file
diff --git a/input/ndfa2.dot b/input/ndfa2.dot
new file mode 100644
index 0000000..2146846
--- /dev/null
+++ b/input/ndfa2.dot
@@ -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
\ No newline at end of file
diff --git a/input/ndfa3.dot b/input/ndfa3.dot
new file mode 100644
index 0000000..d71989a
--- /dev/null
+++ b/input/ndfa3.dot
@@ -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
\ No newline at end of file
diff --git a/input/regex1.dot b/input/regex1.dot
new file mode 100644
index 0000000..773f066
--- /dev/null
+++ b/input/regex1.dot
@@ -0,0 +1,2 @@
+REGEX
+(a|b)*
\ No newline at end of file
diff --git a/input/regex2.dot b/input/regex2.dot
new file mode 100644
index 0000000..af98a82
--- /dev/null
+++ b/input/regex2.dot
@@ -0,0 +1,2 @@
+REGEX
+(aa)+(bba)*(a|b)*(c|d)
\ No newline at end of file
diff --git a/input/regex3.dot b/input/regex3.dot
new file mode 100644
index 0000000..9f6778b
--- /dev/null
+++ b/input/regex3.dot
@@ -0,0 +1,2 @@
+REGEX
+(n+o+)|(ye+s+)!*
\ No newline at end of file
diff --git a/src/com/imegumii/Automata.java b/src/com/imegumii/Automata.java
new file mode 100644
index 0000000..faf1ad3
--- /dev/null
+++ b/src/com/imegumii/Automata.java
@@ -0,0 +1,150 @@
+package com.imegumii;
+
+import java.util.*;
+
+/**
+ * Created by imegumii on 18/04/2017.
+ */
+public class Automata extends Importable {
+
+ protected Set> transistions;
+
+ protected SortedSet states;
+ protected SortedSet beginStates;
+ protected SortedSet eindStates;
+
+ protected SortedSet symbols;
+
+ public Automata() {
+ super(Type.ERROR);
+ states = new TreeSet();
+ beginStates = new TreeSet();
+ eindStates = new TreeSet();
+
+ transistions = new TreeSet<>();
+
+ this.symbols = new TreeSet<>();
+ }
+
+ public void addTransition (Transition 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 : 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 other = (Automata) obj;
+
+ DFA dfa1;
+ DFA dfa2;
+
+ if(this.type == Type.NDFA)
+ {
+ dfa1 = ((NDFA)this).toDFA().minimaliseerHopcroft();
+ }
+ else
+ {
+ dfa1 = ((DFA)this).minimaliseerHopcroft();
+ }
+
+ if(other.type == Type.NDFA)
+ {
+ dfa2 = ((NDFA) obj).toDFA().minimaliseerHopcroft();
+ }
+ else
+ {
+ dfa2 = ((DFA) obj).minimaliseerHopcroft();
+ }
+
+ DFA result = dfa2.ontkenning().en(dfa1).minimaliseerHopcroft();
+
+ if(result.states.size() <= 1)
+ return true;
+
+ return false;
+ }
+}
diff --git a/src/com/imegumii/BackgroundWorker.java b/src/com/imegumii/BackgroundWorker.java
new file mode 100644
index 0000000..a2ec1ab
--- /dev/null
+++ b/src/com/imegumii/BackgroundWorker.java
@@ -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 workers;
+
+ private static BackgroundWorker worker;
+
+ public static BackgroundWorker instance()
+ {
+ if(worker == null)
+ worker = new BackgroundWorker();
+
+ return worker;
+ }
+
+ private BackgroundWorker()
+ {
+ running = true;
+ workers = new ArrayDeque();
+
+ 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();
+ }
+
+ }
+}
diff --git a/src/com/imegumii/DFA.java b/src/com/imegumii/DFA.java
new file mode 100644
index 0000000..c6e9c7b
--- /dev/null
+++ b/src/com/imegumii/DFA.java
@@ -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 extends Automata {
+
+ 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 : 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 addSymbols(int n, TreeSet tempSet) {
+ TreeSet 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 taal = new TreeSet<>();
+ for (Character c : this.symbols) {
+ taal.add("" + c);
+ }
+ return new Taal(addSymbols(n - 1, taal));
+ }
+
+ public NDFA reverse()
+ {
+ NDFA reversed = new NDFA();
+
+ for(Transition t : transistions)
+ {
+ reversed.addTransition(new Transition(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 minimaliseer() {
+ return this.reverse().toDFA().reverse().toDFA();
+ }
+
+ public DFA minimaliseerHopcroft() {
+ HopcroftConverter converter = new HopcroftConverter((DFA) this);
+ return converter.minimize();
+ }
+
+ public DFA ontkenning() {
+
+ DFA result = new DFA();
+
+ for(Transition 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 returnDFA = new DFA();
+
+ SortedSet 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 transistion : this.transistions) {
+ returnDFA.addTransition(transistion);
+ }
+
+ return returnDFA;*/
+ }
+
+ public DFA en(DFA other)
+ {
+ return maakTupleDFA((DFA)this, (DFA)other, false);
+ }
+
+ public DFA of(DFA other)
+ {
+ return maakTupleDFA((DFA)this, (DFA)other, true);
+ }
+
+ private DFA maakTupleDFA(DFA dfa1, DFA dfa2, boolean of)
+ {
+ DFA merged = new DFA();
+
+ //Create all transitions and states
+ for(Transition t1 : dfa1.transistions)
+ {
+ for(Transition t2 : dfa2.transistions)
+ {
+ if(t1.symbol == t2.symbol) {
+ Transition t3 = new Transition(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 usedStates = new TreeSet();
+ for(Transition t : merged.transistions)
+ {
+ usedStates.add((String)t.naarState);
+ }
+
+ Iterator> it = merged.transistions.iterator();
+
+ while(it.hasNext())
+ {
+ Transition t = it.next();
+
+ if(!usedStates.contains(t.vanState) && !merged.beginStates.contains(t.vanState))
+ {
+ it.remove();
+ merged.eindStates.remove(t.vanState);
+ }
+ }
+
+ return merged;
+ }
+}
diff --git a/src/com/imegumii/FileParser.java b/src/com/imegumii/FileParser.java
new file mode 100644
index 0000000..a6bdfea
--- /dev/null
+++ b/src/com/imegumii/FileParser.java
@@ -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 readDFA(BufferedReader br) throws IOException {
+
+ DFA dfa = new DFA();
+
+ 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(trans[0], trans[1].toCharArray()[0], trans[2]));
+ }
+ }
+
+ return dfa;
+ }
+
+ public static NDFA readNDFA(BufferedReader br) throws IOException {
+
+ NDFA ndfa = new NDFA();
+ 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(trans[0], Transition.EPSILON, trans[2]));
+ }
+ else
+ ndfa.addTransition(new Transition(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;
+ }
+}
diff --git a/src/com/imegumii/GrammarConverter.java b/src/com/imegumii/GrammarConverter.java
new file mode 100644
index 0000000..d067e35
--- /dev/null
+++ b/src/com/imegumii/GrammarConverter.java
@@ -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 getGrammar (NDFA automata, String state) {
+ SortedSet canGoTo = new TreeSet<>();
+ for (Character symbol : automata.symbols) {
+ SortedSet bereikbaarVanafViaEpsilonBereikbareState = automata.statesBereikbaarVanaf(state, symbol);
+ for (String s1 : bereikbaarVanafViaEpsilonBereikbareState) {
+ canGoTo.add("" + symbol + s1);
+ }
+ }
+ return canGoTo;
+ }
+
+ public Grammar toGrammar(NDFA automata) {
+ ArrayList grammar = new ArrayList<>();
+ Grammar retval = null;
+ for (String state : automata.states) {
+ SortedSet 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 bereikbaarVanafEpsilon = automata.statesBereikbaarVanaf(state, Transition.EPSILON);
+ for (String s : bereikbaarVanafEpsilon) {
+ canGoTo.add("" + Transition.EPSILON + s);
+ SortedSet 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 options;
+
+ public Grammar(String state, SortedSet 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();
+ }
+ }
+ }
+}
diff --git a/src/com/imegumii/Graph.java b/src/com/imegumii/Graph.java
new file mode 100644
index 0000000..a87e424
--- /dev/null
+++ b/src/com/imegumii/Graph.java
@@ -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 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 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 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 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 a)
+ {
+ return generateImage(a, null);
+ }
+
+ public static synchronized File generateImage(Automata 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;
+ }
+}
diff --git a/src/com/imegumii/HopcroftConverter.java b/src/com/imegumii/HopcroftConverter.java
new file mode 100644
index 0000000..19f3d1e
--- /dev/null
+++ b/src/com/imegumii/HopcroftConverter.java
@@ -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 automata;
+ private SortedSet sets;
+
+ public HopcroftConverter(DFA automata)
+ {
+ this.automata = automata;
+ this.sets = new TreeSet();
+
+ DFAtoHopcroft();
+ updateGroupReferences();
+
+ System.out.println("\nFound " + sets.size() + " sets.");
+ }
+
+ public DFA 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 HopcrofttoDFA()
+ {
+ DFA result = new DFA();
+
+ ArrayList groups = new ArrayList();
+
+ for(HopcroftSet s : sets)
+ {
+ if(!groups.contains(s.group))
+ {
+ for(HopcroftColumn c : s.columns)
+ result.addTransition(new Transition(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> groups = new HashMap>();
+
+ 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());
+ }
+
+ groups.get(key).add(s);
+ }
+
+ if(oldsize == groups.size())
+ return oldsize;
+
+ sets.clear();
+
+ for(ArrayList 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{
+
+ public String group;
+ public String state;
+
+ public ArrayList 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;
+ }
+}
\ No newline at end of file
diff --git a/src/com/imegumii/Importable.java b/src/com/imegumii/Importable.java
new file mode 100644
index 0000000..0c71155
--- /dev/null
+++ b/src/com/imegumii/Importable.java
@@ -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;
+ }
+}
diff --git a/src/com/imegumii/Main.java b/src/com/imegumii/Main.java
new file mode 100644
index 0000000..cbde22c
--- /dev/null
+++ b/src/com/imegumii/Main.java
@@ -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 ndfa = (NDFA) 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();
+ }
+}
diff --git a/src/com/imegumii/NDFA.java b/src/com/imegumii/NDFA.java
new file mode 100644
index 0000000..784aebb
--- /dev/null
+++ b/src/com/imegumii/NDFA.java
@@ -0,0 +1,135 @@
+package com.imegumii;
+
+import java.util.*;
+
+/**
+ * Created by imegumii on 01/05/2017.
+ */
+public class NDFA extends Automata {
+
+ public NDFA() {
+ super();
+ this.type = Type.NDFA;
+ }
+
+ public SortedSet statesBereikbaarVanaf(T vanaf, char s) {
+ SortedSet bereikbaar = new TreeSet();
+ Iterator> it = this.transistions.iterator();
+
+ while(it.hasNext()) {
+ Transition 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 toDFA () {
+ DFA eindDFA = new DFA<>();
+
+ SortedSet startSet = new TreeSet();
+ //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, Integer> totaalEindStates = new HashMap<>();
+
+ totaalEindStates.put(startSet, 0);
+
+ Queue> kue = new LinkedList<>();
+ kue.offer(startSet); // add beginstate(s)
+
+// System.out.println("Start ------------");
+
+ int stateCounter = 1;
+
+ SortedSet> trans = new TreeSet<>();
+
+ while (!kue.isEmpty()) {
+ SortedSet set = kue.poll();
+ // we beginnen bij de begin states
+
+ // kijk welke states je kunt bereiken vanaf deze state.
+ for (Character symbol : this.symbols) {
+ SortedSet 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 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 t : trans) {
+// eindDFA.addTransition(t);
+// }
+ return eindDFA;
+ }
+
+// public SortedSet getByValue (HashMap, Integer> map, String value) {
+// for (Map.Entry, Integer> e : map.entrySet()) {
+// if (value.equals(e.getValue().toString())) {
+// return e.getKey();
+// }
+// }
+//
+// return null;
+// }
+
+}
diff --git a/src/com/imegumii/RegExp.java b/src/com/imegumii/RegExp.java
new file mode 100644
index 0000000..bae1d49
--- /dev/null
+++ b/src/com/imegumii/RegExp.java
@@ -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 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 queue = new LinkedList<>();
+ queue.add(startString);
+
+ Deque processedParantheses = new ArrayDeque<>();
+
+ RegExp retval = new RegExp();
+
+ while (!queue.isEmpty()) {
+ String s = queue.poll();
+// System.out.println("Working on " + s);
+ Deque start = new ArrayDeque<>();
+ Deque 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 alreadyParsed) {
+ ArrayList toOf = new ArrayList<>();
+
+ ArrayList 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 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 leeg = new TreeSet<>(vergelijkDmvLengte);
+ SortedSet resultaat = new TreeSet<>(vergelijkDmvLengte);
+
+ SortedSet 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 tempTaal = new HashSet(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 ret = new TreeSet<>();
+ resultaat.stream().filter(r -> r.length() <= maxLength).forEach(ret::add);
+ return new Taal(ret);
+ }
+
+ public class Tuple {
+ 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;
+ }
+}
diff --git a/src/com/imegumii/Taal.java b/src/com/imegumii/Taal.java
new file mode 100644
index 0000000..3c26d68
--- /dev/null
+++ b/src/com/imegumii/Taal.java
@@ -0,0 +1,23 @@
+package com.imegumii;
+
+import java.util.SortedSet;
+
+/**
+ * Created by imegumii on 02/05/2017.
+ */
+public class Taal {
+ private SortedSet symbols;
+
+ public Taal(SortedSet sortedSet) {
+ this.symbols = sortedSet;
+ }
+
+ public SortedSet getSymbols() {
+ return symbols;
+ }
+
+ @Override
+ public String toString() {
+ return symbols.toString();
+ }
+}
diff --git a/src/com/imegumii/Test.java b/src/com/imegumii/Test.java
new file mode 100644
index 0000000..159aac1
--- /dev/null
+++ b/src/com/imegumii/Test.java
@@ -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 stringsToParse) {
+ Character [] characters = {'a', 'b'};
+ DFA myAutomata = new DFA();
+
+ // AAB
+ myAutomata.addTransition(new Transition("q0", 'a', "q1"));
+
+ myAutomata.addTransition(new Transition("q1", 'b', "q2"));
+ myAutomata.addTransition(new Transition("q1", 'a', "q0"));
+
+ myAutomata.addTransition(new Transition("q2", 'b', "q3"));
+ myAutomata.addTransition(new Transition("q2", 'a', "q5"));
+
+ myAutomata.addTransition(new Transition("q3", "q0"));
+
+ // BAAB
+ myAutomata.addTransition(new Transition("q0", 'b', "q4"));
+
+ myAutomata.addTransition(new Transition("q4", 'a', "q5"));
+ myAutomata.addTransition(new Transition("q4", 'b', "q4"));
+
+ myAutomata.addTransition(new Transition("q5", 'a', "q6"));
+ myAutomata.addTransition(new Transition("q5", 'b', "q4"));
+
+ myAutomata.addTransition(new Transition("q6", 'a', "q4"));
+ myAutomata.addTransition(new Transition("q6", 'b', "q7"));
+
+ myAutomata.addTransition(new Transition("q7", 'a', "q4"));
+ myAutomata.addTransition(new Transition("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 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 test = ThompsonConverter.convert(expr1);
+
+ Graph.generateImage(test, "thompson");
+ }
+
+ public static void Hopcroft()
+ {
+ DFA automata = new DFA();
+
+
+ automata.addTransition(new Transition("q0", 'a', "q2"));
+ automata.addTransition(new Transition("q0", 'b', "q3"));
+ automata.addTransition(new Transition("q1", 'a', "q3"));
+ automata.addTransition(new Transition("q1", 'b', "q2"));
+ automata.addTransition(new Transition("q2", 'a', "q0"));
+ automata.addTransition(new Transition("q2", 'b', "q4"));
+ automata.addTransition(new Transition("q3", 'a', "q1"));
+ automata.addTransition(new Transition("q3", 'b', "q5"));
+ automata.addTransition(new Transition("q4", 'a', "q6"));
+ automata.addTransition(new Transition("q4", 'b', "q5"));
+ automata.addTransition(new Transition("q5", 'a', "q2"));
+ automata.addTransition(new Transition("q5", 'b', "q0"));
+ automata.addTransition(new Transition("q6", 'a', "q4"));
+ automata.addTransition(new Transition("q6", 'b', "q0"));
+
+ automata.defineAsStartState("q0");
+
+ automata.defineAsEndState("q1");
+ automata.defineAsEndState("q3");
+ automata.defineAsEndState("q4");
+ automata.defineAsEndState("q6");
+
+
+ /*
+ automata.addTransition(new Transition("0", 'a', "0"));
+ automata.addTransition(new Transition("0", 'b', "1"));
+
+ automata.addTransition(new Transition("1", 'a', "2"));
+ automata.addTransition(new Transition("1", 'b', "1"));
+
+ automata.addTransition(new Transition("2", 'a', "0"));
+ automata.addTransition(new Transition("2", 'b', "3"));
+
+ automata.addTransition(new Transition("3", 'a', "4"));
+ automata.addTransition(new Transition("3", 'b', "1"));
+
+ automata.addTransition(new Transition("4", 'a', "5"));
+ automata.addTransition(new Transition("4", 'b', "3"));
+
+ automata.addTransition(new Transition("5", 'a', "0"));
+ automata.addTransition(new Transition("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 minimized = convert.minimize();
+
+ System.out.println("\nMinimized automata..");
+ Graph.generateImage(minimized, null);
+ }
+
+ public static void ReverseAutomata()
+ {
+ DFA myAutomata = new DFA();
+
+ // AAB
+ myAutomata.addTransition(new Transition("0", 'a', "0"));
+ myAutomata.addTransition(new Transition("0", 'b', "1"));
+
+ myAutomata.addTransition(new Transition("1", 'a', "0"));
+ myAutomata.addTransition(new Transition("1", 'b', "2"));
+
+ myAutomata.addTransition(new Transition("2", 'a', "0"));
+ myAutomata.addTransition(new Transition("2", 'b', "2"));
+
+ myAutomata.defineAsStartState("0");
+ myAutomata.defineAsEndState("2");
+
+// System.out.println(Graph.generateGraphString(myAutomata));
+
+// System.out.println("\nREVERSE:");
+
+ NDFA 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 myAutomata = new NDFA();
+
+// myAutomata.addTransition(new Transition("0", 'a', "1"));
+// myAutomata.addTransition(new Transition("0", 'a', "2"));
+// myAutomata.addTransition(new Transition("1", 'a', "1"));
+// myAutomata.addTransition(new Transition("1", 'a', "2"));
+// myAutomata.addTransition(new Transition("2", 'b', "1"));
+// myAutomata.addTransition(new Transition("2", 'b', "3"));
+// myAutomata.addTransition(new Transition("3", 'a', "2"));
+// myAutomata.addTransition(new Transition("3", 'a', "1"));
+// myAutomata.defineAsStartState("0");
+// myAutomata.defineAsEndState("0");
+// myAutomata.defineAsEndState("1");
+
+ // Test 2
+// myAutomata.addTransition(new Transition("0", 'a', "1"));
+//
+// myAutomata.addTransition(new Transition("0", 'a', "3"));
+// myAutomata.addTransition(new Transition("0", 'b', "3"));
+//
+// myAutomata.addTransition(new Transition("0", 'a', "2"));
+// myAutomata.addTransition(new Transition("0", 'b', "2"));
+//
+// myAutomata.addTransition(new Transition("1", 'a', "1"));
+// myAutomata.addTransition(new Transition("1", 'b', "3"));
+//
+// myAutomata.addTransition(new Transition("1", 'a', "2"));
+// myAutomata.addTransition(new Transition("1", 'b', "2"));
+//
+// myAutomata.addTransition(new Transition("2", 'b', "2"));
+// myAutomata.addTransition(new Transition("2", 'b', "4"));
+//
+// myAutomata.addTransition(new Transition("2", 'b', "3")); //ja? Ja.
+// myAutomata.addTransition(new Transition("3", 'b', "2"));
+//
+// myAutomata.addTransition(new Transition("3", 'b', "3"));
+//
+// myAutomata.addTransition(new Transition("3", 'a', "4"));
+// myAutomata.addTransition(new Transition("3", 'b', "4"));
+//
+// myAutomata.defineAsStartState("0");
+// myAutomata.defineAsEndState("1");
+
+ // Test 3
+
+// myAutomata.addTransition(new Transition("1", 'a', "2"));
+// myAutomata.addTransition(new Transition("1", 'b', "1"));
+//
+// myAutomata.addTransition(new Transition("2", 'a', "3"));
+// myAutomata.addTransition(new Transition("2", 'b', "2"));
+// myAutomata.addTransition(new Transition("2", Transition.EPSILON, "1"));
+//
+// myAutomata.addTransition(new Transition("3", 'a', "4"));
+// myAutomata.addTransition(new Transition("3", 'b', "3"));
+// myAutomata.addTransition(new Transition("3", Transition.EPSILON, "2"));
+//
+// myAutomata.addTransition(new Transition("4", 'a', "1"));
+// myAutomata.addTransition(new Transition("4", 'b', "4"));
+// myAutomata.addTransition(new Transition("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 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 myAutomata = new DFA();
+ // Test 4 minimalisatie
+
+ myAutomata.addTransition(new Transition("0", 'a', "0"));
+ myAutomata.addTransition(new Transition("0", 'b', "1"));
+
+ myAutomata.addTransition(new Transition("1", 'a', "2"));
+ myAutomata.addTransition(new Transition("1", 'b', "1"));
+
+ myAutomata.addTransition(new Transition("2", 'a', "0"));
+ myAutomata.addTransition(new Transition("2", 'b', "3"));
+
+ myAutomata.addTransition(new Transition("3", 'a', "4"));
+ myAutomata.addTransition(new Transition("3", 'b', "1"));
+
+ myAutomata.addTransition(new Transition