Added finite state machines.
This commit is contained in:
parent
48a69e4bb3
commit
6d0ef8c6d2
3
pom.xml
3
pom.xml
|
@ -17,9 +17,8 @@
|
|||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.18</version>
|
||||
<version>1.18.20</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</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