@fauton/cfg
Version:
A package to work with context free grammars and LL1 parsers
53 lines (52 loc) • 2.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateLR0ParsingTable = exports.augmentCfg = exports.generateClosureOfLR0Item = exports.addDotToProductionRule = void 0;
const populateCfg_1 = require("./utils/populateCfg");
const dotSymbol = "$.$";
function addDotToProductionRule(productionRules, productionVariable) {
const rulesForVariable = productionRules[productionVariable];
// Loop through all the rules for the variable
rulesForVariable.forEach((rule, ruleIndex) => {
// Add the dot symbol to the left
rulesForVariable[ruleIndex] = `${dotSymbol} ${rule}`;
});
}
exports.addDotToProductionRule = addDotToProductionRule;
function generateClosureOfLR0Item(cfg, productionVariable) {
const { productionRules, variables } = cfg;
// Creating a set of variables for faster membership lookup
const variablesSet = new Set(variables);
const rules = productionRules[productionVariable];
rules.forEach(rule => {
const tokens = rule.split(" ");
for (let tokenNumber = 0; tokenNumber < tokens.length - 1; tokenNumber += 1) {
const token = tokens[tokenNumber];
// We wont overflow the tokens array so its safe
const nextToken = tokens[tokenNumber + 1];
// Using $.$ as its a lot less common than regular .
// Check if the next token is a variable
if (token === dotSymbol && variablesSet.has(nextToken)) {
// Add dotSymbol to the left of all the substitution for the variable
addDotToProductionRule(productionRules, nextToken);
// Generate closure of the next variable
generateClosureOfLR0Item(cfg, nextToken);
}
}
});
}
exports.generateClosureOfLR0Item = generateClosureOfLR0Item;
function augmentCfg(inputCfg) {
const cfg = (0, populateCfg_1.populateCfg)(inputCfg);
const { productionRules, startVariable, variables } = cfg;
// Create the augmented grammar
const newStartVariable = `${startVariable}'`;
variables.unshift(newStartVariable);
productionRules[newStartVariable] = [startVariable];
cfg.startVariable = newStartVariable;
return cfg;
}
exports.augmentCfg = augmentCfg;
function generateLR0ParsingTable(inputCfg) {
augmentCfg(inputCfg);
}
exports.generateLR0ParsingTable = generateLR0ParsingTable;