UNPKG

@parser-generator/core

Version:

A Parser Generator that supports LL,SLR,LR1,LALR

75 lines (72 loc) 2.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const utils_1 = require("../utils"); const shim_1 = require("@light0x00/shim"); const debug_1 = __importDefault(require("debug")); let debug = debug_1.default("PG:lr-parser"); class LRParser { constructor(parsingTable) { this.parsingTable = parsingTable; } parse(lexer) { let stateStack = new shim_1.Stack(); stateStack.push(0); let astStack = new shim_1.Stack(); let lookahead = lexer.peek(); while (1) { let topSta = stateStack.peek(); let op = this.parsingTable.get(topSta, lookahead.key()); if (op == undefined) throw new utils_1.MismatchError(this.parsingTable.getExpectedTokens(topSta), lookahead); if (op.isShift()) { astStack.push(lexer.next()); stateStack.push(op.nextStateId); lookahead = lexer.peek(); } else if (op.isGoto()) { stateStack.push(op.nextStateId); lookahead = lexer.peek(); } else if (op.isReduce()) { /* 此次归约产生的AST节点所需的元素 */ let eles = []; // 动作: 归约完成后将符号对应的状态弹出 // 每个状态都由输入一个符号得到 因此每个状态都一个对应的符号 详见:P158 for (let i = 0; i < op.prod.body.length; i++) { stateStack.pop(); eles.unshift(astStack.pop()); //issue AST元素的顺序问题 } astStack.push(op.prod.postAction(eles, astStack)); //issue ASTNode的元素的顺序问题 debug(`reduce ${op.prod}, make ast: ${astStack.peek()}`); lookahead = op.prod.head; } else if (op.isAccept()) { debug(`accept!`); break; } debug(`${astStack.join(" ")}`); } return astStack.pop(); } } exports.LRParser = LRParser; /* 1. ASTNode的元素的顺序问题 考虑如下文法 S->E E->E+T | E-T | T T->T*F | T/F |F F->(E) | NUM 假设输入: 1 + 2 / 3 必然在某一时刻 Ast Stack中的元素为: ENode + TNode / FNode 此时,即将要执行的动作是将 TNode / FNode 归约为T,创建一个TNode: new TNode([TNode,'/',FNode]) 这时要注意的是,传给TNode的集合应该保持与产生式中定义的符号顺序保持一致. 假如传入的是 [FNode,'/',TNode], 那么原本的2/3的含义将变为3/2 */ //# sourceMappingURL=lr-parser.js.map