UNPKG

@light0x00/parser-generator

Version:

A Parser Generator

108 lines (79 loc) 11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FirstSetCalculator = void 0; var _debug = _interopRequireDefault(require("debug")); var _parserDefinition = require("@light0x00/parser-definition"); var _Definition = require("./Definition"); var _Toolkit = require("./Toolkit"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } let debug = (0, _debug.default)("APP:first"); class FirstSetCalculator { constructor(grammar) { _defineProperty(this, "cache", new Map()); _defineProperty(this, "ciclicDector", new _Toolkit.CyclicDepsDector()); _defineProperty(this, "grammar", void 0); this.grammar = grammar; } getFirstSet(target) { if (!(target instanceof _Definition.NonTerminal)) //终结符的first集就是本身 return new Set([target]); let map = this.getFirstMap(target); return new Set(map.keys()); } getFirstMap(target) { if (this.cache.has(target)) return this.cache.get(target); let firstMap = new Map(); //target 的每一个子产生式(候选式) prod for (let i = 0; i < target.prods.length; i++) { let prod = target[i]; //prod 的每一个符号 for (let lm_idx = 0; lm_idx < prod.length; lm_idx++) { let leftMost = prod[lm_idx]; /* 推导First(leftMost) 加入 First(leftMost)-ε - 如果不包含ε,中断. - 如果包含ε,后一个符号作为leftMost,继续推导的First(leftMost),重复同样的过程直到到产生式末尾. - 当到产生式达末尾时,如果还有ε,则将ε加入First(S) */ if (leftMost == target) { //issue 1.自递归 if (lm_idx == 0) //对于左递归文法 给出提示 debug(`Found the left recursive production ${prod}`); break; } if (leftMost instanceof _Definition.NonTerminal) { if (this.ciclicDector.registerAndCheckCycl(target, leftMost)) { //issue 3.循环依赖 跳过 debug(`Cyclic dependencies are detected between the non-terminal ${target} and ${leftMost} when calculating the first set of ${target}!`); continue; } } //加入 First(leftMost)-ε let lm_first_set = this.getFirstSet(leftMost); for (let a of lm_first_set) { if (a != _parserDefinition.NIL) firstMap.set(a, prod); } //不包含ε if (!lm_first_set.has(_parserDefinition.NIL)) { break; } //包含ε else { //到达最后一个仍包含ε 加入ε if (lm_idx == prod.length - 1) firstMap.set(_parserDefinition.NIL, prod); } } } this.cache.set(target, firstMap); return firstMap; } getFirstTable() { let firstTable = new Map(); for (let prod of this.grammar.NTS()) { let firstMap = this.getFirstMap(prod); firstTable.set(prod.name, firstMap); } return firstTable; } } exports.FirstSetCalculator = FirstSetCalculator; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9GaXJzdC50cyJdLCJuYW1lcyI6WyJkZWJ1ZyIsIkZpcnN0U2V0Q2FsY3VsYXRvciIsImNvbnN0cnVjdG9yIiwiZ3JhbW1hciIsIk1hcCIsIkN5Y2xpY0RlcHNEZWN0b3IiLCJnZXRGaXJzdFNldCIsInRhcmdldCIsIk5vblRlcm1pbmFsIiwiU2V0IiwibWFwIiwiZ2V0Rmlyc3RNYXAiLCJrZXlzIiwiY2FjaGUiLCJoYXMiLCJnZXQiLCJmaXJzdE1hcCIsImkiLCJwcm9kcyIsImxlbmd0aCIsInByb2QiLCJsbV9pZHgiLCJsZWZ0TW9zdCIsImNpY2xpY0RlY3RvciIsInJlZ2lzdGVyQW5kQ2hlY2tDeWNsIiwibG1fZmlyc3Rfc2V0IiwiYSIsIk5JTCIsInNldCIsImdldEZpcnN0VGFibGUiLCJmaXJzdFRhYmxlIiwiTlRTIiwibmFtZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7QUFDQSxJQUFJQSxLQUFLLEdBQUcsb0JBQVUsV0FBVixDQUFaOztBQU1PLE1BQU1DLGtCQUFOLENBQXlCO0FBSS9CQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBb0I7QUFBQSxtQ0FIZixJQUFJQyxHQUFKLEVBR2U7O0FBQUEsMENBRlIsSUFBSUMseUJBQUosRUFFUTs7QUFBQTs7QUFDOUIsU0FBS0YsT0FBTCxHQUFlQSxPQUFmO0FBQ0E7O0FBRURHLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBRCxFQUEyQjtBQUNyQyxRQUFJLEVBQUVBLE1BQU0sWUFBWUMsdUJBQXBCLENBQUosRUFBc0M7QUFDckMsYUFBTyxJQUFJQyxHQUFKLENBQVEsQ0FBQ0YsTUFBRCxDQUFSLENBQVA7QUFDRCxRQUFJRyxHQUFHLEdBQUcsS0FBS0MsV0FBTCxDQUFpQkosTUFBakIsQ0FBVjtBQUNBLFdBQU8sSUFBSUUsR0FBSixDQUFRQyxHQUFHLENBQUNFLElBQUosRUFBUixDQUFQO0FBQ0E7O0FBRURELEVBQUFBLFdBQVcsQ0FBQ0osTUFBRCxFQUFnQztBQUMxQyxRQUFJLEtBQUtNLEtBQUwsQ0FBV0MsR0FBWCxDQUFlUCxNQUFmLENBQUosRUFDQyxPQUFPLEtBQUtNLEtBQUwsQ0FBV0UsR0FBWCxDQUFlUixNQUFmLENBQVA7QUFFRCxRQUFJUyxRQUFRLEdBQUcsSUFBSVosR0FBSixFQUFmLENBSjBDLENBTTFDOztBQUNBLFNBQUssSUFBSWEsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR1YsTUFBTSxDQUFDVyxLQUFQLENBQWFDLE1BQWpDLEVBQXlDRixDQUFDLEVBQTFDLEVBQThDO0FBQzdDLFVBQUlHLElBQWdCLEdBQUdiLE1BQU0sQ0FBQ1UsQ0FBRCxDQUE3QixDQUQ2QyxDQUU3Qzs7QUFDQSxXQUFLLElBQUlJLE1BQU0sR0FBRyxDQUFsQixFQUFxQkEsTUFBTSxHQUFHRCxJQUFJLENBQUNELE1BQW5DLEVBQTJDRSxNQUFNLEVBQWpELEVBQXFEO0FBQ3BELFlBQUlDLFFBQWdCLEdBQUdGLElBQUksQ0FBQ0MsTUFBRCxDQUEzQjtBQUNBOzs7Ozs7OztBQU9BLFlBQUlDLFFBQVEsSUFBSWYsTUFBaEIsRUFBd0I7QUFBRTtBQUN6QixjQUFJYyxNQUFNLElBQUksQ0FBZCxFQUFpQjtBQUNoQnJCLFlBQUFBLEtBQUssQ0FBRSx1Q0FBc0NvQixJQUFLLEVBQTdDLENBQUw7QUFDRDtBQUNBOztBQUNELFlBQUlFLFFBQVEsWUFBWWQsdUJBQXhCLEVBQXFDO0FBQ3BDLGNBQUksS0FBS2UsWUFBTCxDQUFrQkMsb0JBQWxCLENBQXVDakIsTUFBdkMsRUFBK0NlLFFBQS9DLENBQUosRUFBOEQ7QUFBRztBQUNoRXRCLFlBQUFBLEtBQUssQ0FBRSw2REFBNERPLE1BQU8sUUFBT2UsUUFBUyx1Q0FBc0NmLE1BQU8sR0FBbEksQ0FBTDtBQUNBO0FBQ0E7QUFDRCxTQW5CbUQsQ0FvQnBEOzs7QUFDQSxZQUFJa0IsWUFBWSxHQUFHLEtBQUtuQixXQUFMLENBQWlCZ0IsUUFBakIsQ0FBbkI7O0FBQ0EsYUFBSyxJQUFJSSxDQUFULElBQWNELFlBQWQsRUFBNEI7QUFDM0IsY0FBSUMsQ0FBQyxJQUFJQyxxQkFBVCxFQUNDWCxRQUFRLENBQUNZLEdBQVQsQ0FBYUYsQ0FBYixFQUFnQk4sSUFBaEI7QUFDRCxTQXpCbUQsQ0EwQnBEOzs7QUFDQSxZQUFJLENBQUNLLFlBQVksQ0FBQ1gsR0FBYixDQUFpQmEscUJBQWpCLENBQUwsRUFBNEI7QUFDM0I7QUFDQSxTQUZELENBR0E7QUFIQSxhQUlLO0FBQ0o7QUFDQSxnQkFBSU4sTUFBTSxJQUFJRCxJQUFJLENBQUNELE1BQUwsR0FBYyxDQUE1QixFQUNDSCxRQUFRLENBQUNZLEdBQVQsQ0FBYUQscUJBQWIsRUFBa0JQLElBQWxCO0FBQ0Q7QUFDRDtBQUNEOztBQUNELFNBQUtQLEtBQUwsQ0FBV2UsR0FBWCxDQUFlckIsTUFBZixFQUF1QlMsUUFBdkI7QUFDQSxXQUFPQSxRQUFQO0FBQ0E7O0FBRURhLEVBQUFBLGFBQWEsR0FBRztBQUNmLFFBQUlDLFVBQVUsR0FBRyxJQUFJMUIsR0FBSixFQUFqQjs7QUFDQSxTQUFLLElBQUlnQixJQUFULElBQWlCLEtBQUtqQixPQUFMLENBQWE0QixHQUFiLEVBQWpCLEVBQXFDO0FBQ3BDLFVBQUlmLFFBQVEsR0FBRyxLQUFLTCxXQUFMLENBQWlCUyxJQUFqQixDQUFmO0FBQ0FVLE1BQUFBLFVBQVUsQ0FBQ0YsR0FBWCxDQUFlUixJQUFJLENBQUNZLElBQXBCLEVBQTBCaEIsUUFBMUI7QUFDQTs7QUFDRCxXQUFPYyxVQUFQO0FBQ0E7O0FBMUU4QiIsInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0IHJvb3REZWJ1ZyBmcm9tIFwiZGVidWdcIjtcbmltcG9ydCB7IE5JTCB9IGZyb20gXCJAbGlnaHQweDAwL3BhcnNlci1kZWZpbml0aW9uXCI7XG5pbXBvcnQgeyBUZXJtaW5hbCwgUHJvZHVjdGlvbiwgTm9uVGVybWluYWwsIFN5bWJvbCwgSUdyYW1tYXIgfSBmcm9tIFwiQC9EZWZpbml0aW9uXCI7XG5pbXBvcnQgeyBDeWNsaWNEZXBzRGVjdG9yIH0gZnJvbSBcIi4vVG9vbGtpdFwiO1xubGV0IGRlYnVnID0gcm9vdERlYnVnKFwiQVBQOmZpcnN0XCIpO1xuXG5leHBvcnQgdHlwZSBGaXJzdE1hcCA9IE1hcDxUZXJtaW5hbCwgUHJvZHVjdGlvbj5cbmV4cG9ydCB0eXBlIEZpcnN0U2V0ID0gU2V0PFRlcm1pbmFsPlxuZXhwb3J0IHR5cGUgRmlyc3RUYWJsZSA9IE1hcDxzdHJpbmcsIE1hcDxUZXJtaW5hbCwgUHJvZHVjdGlvbj4+XG5cbmV4cG9ydCBjbGFzcyBGaXJzdFNldENhbGN1bGF0b3Ige1xuXHRwcml2YXRlIGNhY2hlID0gbmV3IE1hcDxOb25UZXJtaW5hbCwgRmlyc3RNYXA+KClcblx0cHJpdmF0ZSBjaWNsaWNEZWN0b3IgPSBuZXcgQ3ljbGljRGVwc0RlY3RvcjxOb25UZXJtaW5hbD4oKVxuXHRwcml2YXRlIGdyYW1tYXI6IElHcmFtbWFyXG5cdGNvbnN0cnVjdG9yKGdyYW1tYXI6IElHcmFtbWFyKSB7XG5cdFx0dGhpcy5ncmFtbWFyID0gZ3JhbW1hcjtcblx0fVxuXG5cdGdldEZpcnN0U2V0KHRhcmdldDogU3ltYm9sKTogRmlyc3RTZXQge1xuXHRcdGlmICghKHRhcmdldCBpbnN0YW5jZW9mIE5vblRlcm1pbmFsKSkgLy/nu4jnu5PnrKbnmoRmaXJzdOmbhuWwseaYr+acrOi6q1xuXHRcdFx0cmV0dXJuIG5ldyBTZXQoW3RhcmdldF0pO1xuXHRcdGxldCBtYXAgPSB0aGlzLmdldEZpcnN0TWFwKHRhcmdldCk7XG5cdFx0cmV0dXJuIG5ldyBTZXQobWFwLmtleXMoKSk7XG5cdH1cblxuXHRnZXRGaXJzdE1hcCh0YXJnZXQ6IE5vblRlcm1pbmFsKTogRmlyc3RNYXAge1xuXHRcdGlmICh0aGlzLmNhY2hlLmhhcyh0YXJnZXQpKVxuXHRcdFx0cmV0dXJuIHRoaXMuY2FjaGUuZ2V0KHRhcmdldCkhO1xuXG5cdFx0bGV0IGZpcnN0TWFwID0gbmV3IE1hcDxUZXJtaW5hbCwgUHJvZHVjdGlvbj4oKTtcblxuXHRcdC8vdGFyZ2V0IOeahOavj+S4gOS4quWtkOS6p+eUn+W8jyjlgJnpgInlvI8pIHByb2Rcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRhcmdldC5wcm9kcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0bGV0IHByb2Q6IFByb2R1Y3Rpb24gPSB0YXJnZXRbaV07XG5cdFx0XHQvL3Byb2Qg55qE5q+P5LiA5Liq56ym5Y+3XG5cdFx0XHRmb3IgKGxldCBsbV9pZHggPSAwOyBsbV9pZHggPCBwcm9kLmxlbmd0aDsgbG1faWR4KyspIHtcblx0XHRcdFx0bGV0IGxlZnRNb3N0OiBTeW1ib2wgPSBwcm9kW2xtX2lkeF07XG5cdFx0XHRcdC8qXG4gICAgICAgICAgICAgICAg5o6o5a+8Rmlyc3QobGVmdE1vc3QpXG4gICAgICAgICAgICAgICAgICAgIOWKoOWFpSBGaXJzdChsZWZ0TW9zdCktzrVcbiAgICAgICAgICAgICAgICAgICAgLSDlpoLmnpzkuI3ljIXlkKvOtSzkuK3mlq0uXG4gICAgICAgICAgICAgICAgICAgIC0g5aaC5p6c5YyF5ZCrzrUs5ZCO5LiA5Liq56ym5Y+35L2c5Li6bGVmdE1vc3Qs57un57ut5o6o5a+855qERmlyc3QobGVmdE1vc3QpLOmHjeWkjeWQjOagt+eahOi/h+eoi+ebtOWIsOWIsOS6p+eUn+W8j+acq+Wwvi5cbiAgICAgICAgICAgICAgICAgICAgLSDlvZPliLDkuqfnlJ/lvI/ovr7mnKvlsL7ml7Ys5aaC5p6c6L+Y5pyJzrUs5YiZ5bCGzrXliqDlhaVGaXJzdChTKVxuICAgICAgICAgICAgICAgICovXG5cdFx0XHRcdGlmIChsZWZ0TW9zdCA9PSB0YXJnZXQpIHsgLy9pc3N1ZSAxLuiHqumAkuW9klxuXHRcdFx0XHRcdGlmIChsbV9pZHggPT0gMCkgLy/lr7nkuo7lt6bpgJLlvZLmlofms5Ug57uZ5Ye65o+Q56S6XG5cdFx0XHRcdFx0XHRkZWJ1ZyhgRm91bmQgdGhlIGxlZnQgcmVjdXJzaXZlIHByb2R1Y3Rpb24gJHtwcm9kfWApO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChsZWZ0TW9zdCBpbnN0YW5jZW9mIE5vblRlcm1pbmFsKSB7XG5cdFx0XHRcdFx0aWYgKHRoaXMuY2ljbGljRGVjdG9yLnJlZ2lzdGVyQW5kQ2hlY2tDeWNsKHRhcmdldCwgbGVmdE1vc3QpKSB7ICAvL2lzc3VlIDMu5b6q546v5L6d6LWWIOi3s+i/h1xuXHRcdFx0XHRcdFx0ZGVidWcoYEN5Y2xpYyBkZXBlbmRlbmNpZXMgYXJlIGRldGVjdGVkIGJldHdlZW4gdGhlIG5vbi10ZXJtaW5hbCAke3RhcmdldH0gYW5kICR7bGVmdE1vc3R9ICB3aGVuIGNhbGN1bGF0aW5nIHRoZSBmaXJzdCBzZXQgb2YgJHt0YXJnZXR9IWApO1xuXHRcdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdC8v5Yqg5YWlIEZpcnN0KGxlZnRNb3N0KS3OtVxuXHRcdFx0XHRsZXQgbG1fZmlyc3Rfc2V0ID0gdGhpcy5nZXRGaXJzdFNldChsZWZ0TW9zdCk7XG5cdFx0XHRcdGZvciAobGV0IGEgb2YgbG1fZmlyc3Rfc2V0KSB7XG5cdFx0XHRcdFx0aWYgKGEgIT0gTklMKVxuXHRcdFx0XHRcdFx0Zmlyc3RNYXAuc2V0KGEsIHByb2QpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8v5LiN5YyF5ZCrzrVcblx0XHRcdFx0aWYgKCFsbV9maXJzdF9zZXQuaGFzKE5JTCkpIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0XHQvL+WMheWQq861XG5cdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdC8v5Yiw6L6+5pyA5ZCO5LiA5Liq5LuN5YyF5ZCrzrUg5Yqg5YWlzrVcblx0XHRcdFx0XHRpZiAobG1faWR4ID09IHByb2QubGVuZ3RoIC0gMSlcblx0XHRcdFx0XHRcdGZpcnN0TWFwLnNldChOSUwsIHByb2QpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuY2FjaGUuc2V0KHRhcmdldCwgZmlyc3RNYXApO1xuXHRcdHJldHVybiBmaXJzdE1hcDtcblx0fVxuXG5cdGdldEZpcnN0VGFibGUoKSB7XG5cdFx0bGV0IGZpcnN0VGFibGUgPSBuZXcgTWFwPHN0cmluZywgTWFwPFRlcm1pbmFsLCBQcm9kdWN0aW9uPj4oKTtcblx0XHRmb3IgKGxldCBwcm9kIG9mIHRoaXMuZ3JhbW1hci5OVFMoKSkge1xuXHRcdFx0bGV0IGZpcnN0TWFwID0gdGhpcy5nZXRGaXJzdE1hcChwcm9kKTtcblx0XHRcdGZpcnN0VGFibGUuc2V0KHByb2QubmFtZSwgZmlyc3RNYXApO1xuXHRcdH1cblx0XHRyZXR1cm4gZmlyc3RUYWJsZTtcblx0fVxufVxuIl19