Skip to content

Instantly share code, notes, and snippets.

@kotosha-real
Created May 10, 2021 18:27
Show Gist options
  • Save kotosha-real/57dee4f3bc50692639880d0ae682827d to your computer and use it in GitHub Desktop.
Save kotosha-real/57dee4f3bc50692639880d0ae682827d to your computer and use it in GitHub Desktop.
Deterministic finite-state acceptor
/**
* Thanks for this FSM implementation to Zakhar Ovcharov (https://www.linkedin.com/in/zakhar-ovcharov-a657a4197/)
* I did small adjustments to meet requirements of the specific task
*/
class FSM {
/**
* Each instance of this class will have a certain alphabet, a list of states and transitions, and could be used to test some value against these params
* @param {String} alphabet
* @param {String[]} states
* @param {String} startState
* @param {String[]} finiteStates
* @param {Object} transitions
*/
constructor(alphabet, states, startState, finiteStates, transitions) {
this.alphabet = alphabet
this.states = states
this.startState = startState
this.transitions = transitions
this.finiteStates = finiteStates
this.currentState = null
}
/**
* Check if the symbol belongs to the specified alphabet
* @param {String} symbol
* @returns {Boolean}
*/
_checkIsBelongAlphabet(symbol) {
return this.alphabet.includes(symbol)
}
/**
* Change the current state depending on the symbol. FSM should abort if there is no transition for the current symbol on the current state
* @param {String} symbol
*/
_changeState(symbol) {
if (
this.transitions[this.currentState] &&
this.transitions[this.currentState][symbol]
) {
this.currentState = this.transitions[this.currentState][symbol]
} else {
throw new Error(`No transition from ${this.currentState} by ${symbol}`)
}
}
/**
* Test some value against specified params. Accepts value if the finiteStates array includes the last current state and rejects otherwise
* @param {String} value
* @returns {String}
*/
test(value) {
this.currentState = this.startState
for (let symbol of value) {
if (this._checkIsBelongAlphabet(symbol)) {
this._changeState(symbol)
} else {
return false
}
}
return this.finiteStates.includes(this.currentState)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment