Skip to content
fsm.js 1.81 KiB
Newer Older
var fsm = function () {
    const debugging = false;

    const debug = function (msg) {
	if (debugging) {
	    console.log(msg);
	}
    };

    /**
     * a fsm that tries to match string "abb". see function
     * matchesSubstringAbb.
     */
    const matchAbbMachine = function () {
	this.stateWaitForA = "wait for a";
	this.stateWaitForFirstB = "wait for 1st b";
	this.stateWaitForSecondB = "wait for 2nd b";
	this.stateSucceed = "succeed";

	this.currentState = "wait for a";
	this.readch = function (ch) {
	    switch (this.currentState) {
	    case this.stateWaitForA:
		if (ch === 'a') {
		    this.currentState = this.stateWaitForFirstB;
		} else {
		    this.currentState = this.stateWaitForA;
		}
		break;
	    case this.stateWaitForFirstB:
		if (ch === 'b') {
		    this.currentState = this.stateWaitForSecondB;
		} else if (ch === 'a') {
		    // do nothing, keep current state.
		} else {
		    this.currentState = this.stateWaitForA;
		}
		break;
	    case this.stateWaitForSecondB:
		if (ch === 'b') {
		    this.currentState = this.stateSucceed;
		} else if (ch === 'a') {
		    this.currentState = this.stateWaitForFirstB;
		} else {
		    this.currentState = this.stateWaitForA;
		}
		break;
	    case this.succeed:
		// do nothing, keep current state.
		break;
	    }
	    debug("readch " + ch + ", currentState is " + this.currentState);
	    return this.currentState;
	};
    };

    /**
     * return true if given string has substring "abb" in it.
     * implemented using fsm.
     */
    const matchesSubstringAbb = function (str) {
	var machine = new matchAbbMachine();
	for (i = 0; i < str.length; ++i) {
	    machine.readch(str[i]);
	    if (machine.currentState === "succeed") {
		// console.log("matches");
		return true;
	    }
	}
	return false;
    };

    return {
	matchesSubstringAbb: matchesSubstringAbb
    };
}();