PEG.js仅支持单次输出问题咨询:如何实现多输出功能
问题原因及修复方案
仅输出单次结果的原因
- 栈执行逻辑顺序错误:你当前的
evalStack函数从栈尾倒序遍历执行,和你输入代码的书写执行顺序完全相反,导致变量赋值和输出的先后逻辑错乱,最终返回值被覆盖为较早的执行结果。 - 输出没有统一收集:你用单个
result变量存储输出值,每次执行表达式都会覆盖之前的结果,且函数仅返回单个值,自然无法得到多轮输出。 - PEG.js默认仅返回根规则的最终返回值:如果你的语法规则没有把所有顶层表达式的执行结果收集为数组返回,最终只能拿到解析完成后的最后一个返回值。
修复步骤
1. 调整栈执行逻辑,收集所有输出
修改evalStack为正序遍历栈,同时用数组存储所有输出结果:
function evalStack() { const outputs = []; // 正序遍历,和输入代码的执行顺序保持一致 for (var i = 0; i < stack.length; i++) { const execRes = stack[i](); // 仅收集非赋值类的表达式执行结果 if (execRes !== undefined) { outputs.push(execRes); } } return outputs; }
2. 修改PEG.js语法规则
在根规则中匹配所有顶层语句,把所有语句的执行结果收集为数组返回,参考规则如下:
start = "start"? stmts:statement* { return stmts.filter(item => item !== undefined) } statement = assignStmt / exprStmt assignStmt = id:[A-Za-z]+ "=" num:[0-9]+ ";" { /* 这里放你的变量赋值逻辑,返回undefined */ } exprStmt = id:[A-Za-z]+ { /* 这里返回变量对应的存储值 */ }
3. 结果输出
调用PEG.js生成的解析器拿到返回的输出数组后,逐行打印即可得到你期望的4、8输出。
多输出功能替代方案
如果不想自行维护栈的结果收集逻辑,可以在解析过程中直接调用自定义打印函数,每遇到顶层表达式就直接输出结果:
// 提前定义全局打印方法 const customPrint = val => console.log(val); // 在PEG.js的exprStmt规则中直接触发打印 exprStmt = id:[A-Za-z]+ { customPrint(getVariable(id)) }
解析运行过程中就会依次输出所有表达式的结果,不需要等全部解析完成后再统一处理返回值。
内容的提问来源于stack exchange,提问作者Taslima Akhter
相关产品推荐
相关产品推荐

