@light0x00/parser-generator
Version:
A Parser Generator
108 lines (79 loc) • 11 kB
JavaScript
;
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