UNPKG

fauton

Version:

A library to test any finite automaton with arbitrary alphabets

88 lines (87 loc) 4.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.normalize = void 0; const utils_1 = require("../../../utils"); function expandCharacterRangesForArray(characterRanges, appendedString) { const uniqueSymbols = new Set(); characterRanges.forEach((characterRange) => { (0, utils_1.expandCharacterRanges)(characterRange.toString()).forEach((expandedCharacterRange) => { uniqueSymbols.add((appendedString ?? '') + expandedCharacterRange); }); }); return Array.from(uniqueSymbols); } function normalize(finiteAutomaton) { const appendedString = finiteAutomaton.append ?? ''; if (appendedString) { delete finiteAutomaton.append; } finiteAutomaton.final_states = expandCharacterRangesForArray(finiteAutomaton.final_states, appendedString); finiteAutomaton.alphabets = expandCharacterRangesForArray(finiteAutomaton.alphabets); finiteAutomaton.states = expandCharacterRangesForArray(finiteAutomaton.states, appendedString); finiteAutomaton.start_state = appendedString + finiteAutomaton.start_state.toString(); if (finiteAutomaton.epsilon_transitions) { Object.entries(finiteAutomaton.epsilon_transitions).forEach(([epsilonTransitionStartState, epsilonTransitionTargetStates]) => { const newEpsilonTransitionTargetStates = new Set(); epsilonTransitionTargetStates.forEach((epsilonTransitionTargetState) => { (0, utils_1.expandCharacterRanges)(epsilonTransitionTargetState.toString()).forEach((stateString) => { newEpsilonTransitionTargetStates.add(stateString.toString()); }); }); finiteAutomaton.epsilon_transitions[epsilonTransitionStartState] = Array.from(newEpsilonTransitionTargetStates); }); } function attachToStateRecord(transitionStateRecord, alphabetIndex, state) { if (!transitionStateRecord[finiteAutomaton.alphabets[alphabetIndex]]) { transitionStateRecord[finiteAutomaton.alphabets[alphabetIndex]] = [state]; } else { transitionStateRecord[finiteAutomaton.alphabets[alphabetIndex]].push(state); } } Object.entries(finiteAutomaton.transitions).forEach(([transitionKey, transitionStates]) => { const transitionStateRecord = {}; if (typeof transitionStates !== 'string' && Array.isArray(transitionStates)) { transitionStates.forEach((transitionState, transitionStateIndex) => { if (transitionState !== null && transitionState !== undefined) { const newEpsilonTransitionTargetStates = new Set(); if (Array.isArray(transitionState)) { transitionState.forEach((state) => { (0, utils_1.expandCharacterRanges)(state.toString()).forEach((stateString) => { newEpsilonTransitionTargetStates.add(stateString); }); }); if (!transitionStateRecord[finiteAutomaton.alphabets[transitionStateIndex]]) { transitionStateRecord[finiteAutomaton.alphabets[transitionStateIndex]] = Array.from(newEpsilonTransitionTargetStates); } else { transitionStateRecord[finiteAutomaton.alphabets[transitionStateIndex]].push(...Array.from(newEpsilonTransitionTargetStates)); } } else { (0, utils_1.expandCharacterRanges)(transitionState.toString()).forEach((expandedState) => { attachToStateRecord(transitionStateRecord, transitionStateIndex, appendedString + expandedState.toString()); }); } } }); finiteAutomaton.transitions[appendedString + transitionKey] = transitionStateRecord; if (appendedString) { delete finiteAutomaton.transitions[transitionKey]; } } else if (transitionStates === 'loop') { finiteAutomaton.alphabets.forEach((_, alphabetIndex) => { attachToStateRecord(transitionStateRecord, alphabetIndex, appendedString + transitionKey.toString()); }); finiteAutomaton.transitions[appendedString + transitionKey] = transitionStateRecord; if (appendedString) { delete finiteAutomaton.transitions[transitionKey]; } } }); return finiteAutomaton; } exports.normalize = normalize;