CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
高级技巧语法算法996引擎

Lua调度场进阶:带括号的完整转换

2026-09-27 23:30 作者:996 技术组 996引擎Lua教程传奇脚本高级技巧语法算法996引擎

【语法】
一、机制原理
线上事故:表达式计算器宣布支持括号,用户立刻敲出"(2 + 3) * 4",期望 20,界面稳稳当当给出 14——括号被当成普通运算符进了运算符栈,右括号到了无人认领,乘加次序全乱。调度场算法处理括号只需补两条规则:左括号无条件进运算符栈;右括号到来时不断弹出栈顶运算符送进输出,直到弹出左括号本身——这对括号双双消失,中间已经输出的就是括号内的高优先级结果。同时给运算符入栈的弹栈条件补一条护栏:弹到左括号必须停手,左括号是墙,任何运算符都不越墙弹栈。上一轮的基础版只处理加减乘除四则的平铺,这一版补齐括号后,四则混合带任意层嵌套的表达式都能一次转对。
二、错误写法

lua
-- 错误:括号当普通记号进栈,右括号无人处理
for _, tk in ipairs(tokens) do
    ops[#ops + 1] = tk
end

三、正确写法

lua
local PRI = {["+"] = 1, ["-"] = 1, ["*"] = 2, ["/"] = 2}
local function toRPN(tokens)
    local out, ops = {}, {}
    for _, tk in ipairs(tokens) do
        if tonumber(tk) then
            out[#out + 1] = tonumber(tk)
        elseif tk == "(" then
            ops[#ops + 1] = tk
        elseif tk == ")" then
            while ops[#ops] ~= "(" do
                out[#out + 1] = table.remove(ops)
            end
            table.remove(ops)
        else
            while ops[#ops] ~= nil
                and ops[#ops] ~= "("
                and PRI[ops[#ops]] >= PRI[tk] do
                out[#out + 1] = table.remove(ops)
            end
            ops[#ops + 1] = tk
        end
    end
    while #ops > 0 do
        out[#out + 1] = table.remove(ops)
    end
    return out
end
local function evalRPN(rpn)
    local st = {}
    for _, tk in ipairs(rpn) do
        if type(tk) == "number" then
            st[#st + 1] = tk
        else
            local b = table.remove(st)
            local a = table.remove(st)
            if tk == "+" then st[#st + 1] = a + b end
            if tk == "-" then st[#st + 1] = a - b end
            if tk == "*" then st[#st + 1] = a * b end
            if tk == "/" then st[#st + 1] = a / b end
        end
    end
    return st[1]
end
local expr = {"(", "2", "+", "3", ")", "*", "4"}
local label = panel:getChildByName("calcText")
label:setString(tostring(evalRPN(toRPN(expr))))

四、引擎验证
带括号表达式转出的后缀串为 2、3、+、4、,求值得 20;嵌套括号"(1+(23))"转出 1、2、3、*、+,求值得 7;无括号的基础表达式与上一版结果逐项一致。
五、FAQ
问:弹栈遇到左括号为什么停?
答:括号是作用域的墙,墙外的运算符不许越过墙参与排序。
问:右括号处理后栈里还剩什么?
答:只剩墙外的运算符与更早的左括号,流程继续。
问:括号不配对会怎样?
答:右括号弹空栈会取到 nil,入口先做配对校验即可。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →