Added finite state machines.
This commit is contained in:
parent
48a69e4bb3
commit
6d0ef8c6d2
3
pom.xml
3
pom.xml
|
@ -17,9 +17,8 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.18</version>
|
<version>1.18.20</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,63 @@
|
||||||
|
package nl.andrewlalis.grammar_tool.machine;
|
||||||
|
|
||||||
|
import nl.andrewlalis.grammar_tool.grammar.Symbol;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class FiniteStateMachine {
|
||||||
|
private final Set<Symbol> alphabet;
|
||||||
|
private final Set<State> states;
|
||||||
|
private final Set<State> finalStates;
|
||||||
|
private final State startState;
|
||||||
|
private final Set<Transition> transitions;
|
||||||
|
|
||||||
|
public FiniteStateMachine(Set<Symbol> alphabet, Set<State> states, Set<State> finalStates, State startState, Set<Transition> transitions) {
|
||||||
|
this.alphabet = alphabet;
|
||||||
|
this.states = states;
|
||||||
|
this.finalStates = finalStates;
|
||||||
|
this.startState = startState;
|
||||||
|
this.transitions = transitions;
|
||||||
|
this.ensureValidElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureValidElements() {
|
||||||
|
if (!this.states.contains(this.startState)) {
|
||||||
|
throw new IllegalArgumentException("Start state is not an element of the whole set of states.");
|
||||||
|
}
|
||||||
|
if (!this.states.containsAll(this.finalStates)) {
|
||||||
|
throw new IllegalArgumentException("Not all final states belong to the whole set of states.");
|
||||||
|
}
|
||||||
|
if (this.finalStates.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("No final states. There must be at least one final state.");
|
||||||
|
}
|
||||||
|
for (Transition t : this.transitions) {
|
||||||
|
if (!this.states.contains(t.getStartState())) {
|
||||||
|
throw new IllegalArgumentException("Start state of transition does not belong to the whole set of states: " + t);
|
||||||
|
}
|
||||||
|
if (!this.states.contains(t.getEndState())) {
|
||||||
|
throw new IllegalArgumentException("End state of transition does not belong to the whole set of states: " + t);
|
||||||
|
}
|
||||||
|
if (!this.alphabet.contains(t.getAcceptingSymbol())) {
|
||||||
|
throw new IllegalArgumentException("Accepting symbol of transition is not in the alphabet: " + t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
FiniteStateMachine that = (FiniteStateMachine) o;
|
||||||
|
return alphabet.equals(that.alphabet) &&
|
||||||
|
states.equals(that.states) &&
|
||||||
|
finalStates.equals(that.finalStates) &&
|
||||||
|
startState.equals(that.startState) &&
|
||||||
|
transitions.equals(that.transitions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(alphabet, states, finalStates, startState, transitions);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package nl.andrewlalis.grammar_tool.machine;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class State {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public State(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
State state = (State) o;
|
||||||
|
return name.equals(state.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package nl.andrewlalis.grammar_tool.machine;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import nl.andrewlalis.grammar_tool.grammar.Symbol;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class Transition {
|
||||||
|
private final State startState;
|
||||||
|
private final Symbol acceptingSymbol;
|
||||||
|
private final State endState;
|
||||||
|
|
||||||
|
public Transition(State startState, Symbol acceptingSymbol, State endState) {
|
||||||
|
this.startState = startState;
|
||||||
|
this.acceptingSymbol = acceptingSymbol;
|
||||||
|
this.endState = endState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Transition that = (Transition) o;
|
||||||
|
return startState.equals(that.startState) &&
|
||||||
|
acceptingSymbol.equals(that.acceptingSymbol) &&
|
||||||
|
endState.equals(that.endState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(startState, acceptingSymbol, endState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%s (%s) -> %s", this.startState, this.acceptingSymbol, this.endState);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue