@fauton/cfg
Version:
A package to work with context free grammars and LL1 parsers
47 lines (46 loc) • 2.56 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeUnreachableProduction = void 0;
const linked_list_1 = require("@datastructures-js/linked-list");
const populateCfg_1 = require("./utils/populateCfg");
const setOperations_1 = require("./utils/setOperations");
/**
* Removes unreachable variables and production of a cfg
* @param cfg Production rules, start variable and variables array of cfg
* @returns A new production rule record and variables with unreachable variable and rules removed
*/
function removeUnreachableProduction(inputCfg) {
var _a;
const cfg = (0, populateCfg_1.populateCfg)(inputCfg);
const { productionRules, startVariable, variables } = cfg;
const variablesSet = new Set(variables);
const unvisitedVariables = new linked_list_1.LinkedList();
unvisitedVariables.insertFirst(startVariable);
const visitedVariables = new Set();
visitedVariables.add(startVariable);
// While we have unvisited variables
while (unvisitedVariables.count()) {
const unvisitedVariable = unvisitedVariables.removeFirst();
// For each of the unvisited variable, check which variables we can reach
(_a = productionRules[unvisitedVariable.getValue()]) === null || _a === void 0 ? void 0 : _a.forEach((productionRuleSubstitution) => {
const tokens = productionRuleSubstitution.split(' ');
for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex += 1) {
const token = tokens[tokenIndex];
// If the letter is a variable, and we haven't visited the variable yet
if (variablesSet.has(token) && !visitedVariables.has(token)) {
visitedVariables.add(token);
unvisitedVariables.insertLast(token);
}
}
});
}
// The difference between the variables set and visited variables set will return the variables which couldn't be reached
const nonReachableVariables = Array.from((0, setOperations_1.setDifference)(variablesSet, visitedVariables));
// Delete the production rules for each of the unreachable variables
nonReachableVariables.forEach((nonReachableVariable) => {
delete productionRules[nonReachableVariable];
});
// There is no need to update the production rules as unreachable variables are not referenced there
return Array.from(visitedVariables);
}
exports.removeUnreachableProduction = removeUnreachableProduction;