UNPKG

@fauton/cfg

Version:

A package to work with context free grammars and LL1 parsers

57 lines (56 loc) 3.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.removeUnitProduction = exports.findFirstUnitProductionRule = void 0; const populateCfg_1 = require("./utils/populateCfg"); /** * Returns the first occurrence of unit production inside production rules * @param variables Array of variables * @param productionRules Production rules of CFG * @returns A tuple where the first item is the variable which produces unit production, and second item indicates the rule position */ function findFirstUnitProductionRule(variables, productionRules) { const variablesSet = new Set(variables); // Loop through all the variables for (let variableIndex = 0; variableIndex < variables.length; variableIndex += 1) { const variable = variables[variableIndex]; if (productionRules[variable]) { // For each variable, loop through its production rules for (let productionRuleSubstitutionIndex = 0; productionRuleSubstitutionIndex < productionRules[variable].length; productionRuleSubstitutionIndex += 1) { const productionRuleSubstitution = productionRules[variable][productionRuleSubstitutionIndex]; const tokens = productionRuleSubstitution.split(' '); // If the production rule substitution is of length one and its a variable if (tokens.length === 1 && variablesSet.has(productionRuleSubstitution)) { return [variable, productionRuleSubstitutionIndex]; } } } } return null; } exports.findFirstUnitProductionRule = findFirstUnitProductionRule; /** * Modifies the production rules of a cfg to remove unit production rules * @param cfg Variable and production rules of a cfg */ function removeUnitProduction(inputCfg) { const cfg = (0, populateCfg_1.populateCfg)(inputCfg); let unitProductionRule = findFirstUnitProductionRule(cfg.variables, cfg.productionRules); // Only continue if there is any unit production rule while (unitProductionRule) { const [unitProductionVariable, productionRuleSubstitutionIndex] = unitProductionRule; // Get all the production rules of the unit production variable const unitProductionRules = cfg.productionRules[unitProductionVariable]; const unitProducingVariableRules = cfg.productionRules[unitProductionRules[productionRuleSubstitutionIndex]]; // Remove the rule that generates unit production unitProductionRules.splice(productionRuleSubstitutionIndex, 1); // Some variables might not be present in the production rules if (unitProducingVariableRules) { // Making sure there are no duplicate rules cfg.productionRules[unitProductionVariable] = Array.from( // Add all the rules of the unit production rule new Set(unitProductionRules.concat(unitProducingVariableRules))); } unitProductionRule = findFirstUnitProductionRule(cfg.variables, cfg.productionRules); } } exports.removeUnitProduction = removeUnitProduction;