-
-
Save kotosha-real/57dee4f3bc50692639880d0ae682827d to your computer and use it in GitHub Desktop.
Deterministic finite-state acceptor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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