简单表达式解析器
使用纯 Lua 为算术表达式构建递归下降解析器。
简单表达式解析器 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
目标:解析算术表达式
使用纯 Lua 构建递归下降解析器,解析并计算类似 3 + 4 * (2 - 1) 的表达式,同时遵循运算符优先级。
词法分析器
首先,将输入拆分为数字、运算符和括号。
local function tokenize(expr)
local tokens = {}
for tok in expr:gmatch("[%d%.]+|[%+%-%*/%(%)%^]|%S") do
tokens[#tokens+1] = tok
end
return tokens
end改进的词法分析器
使用匹配模式的更稳健的词法分析器。
local function tokenize(expr)
local tokens = {}
for tok in expr:gmatch("%d+%.?%d*|[%+%-%*/%(%)%^]") do
tokens[#tokens+1] = tok
end
return tokens
end解析器状态
解析器会携带一个令牌列表和一个位置。辅助函数 peek 和 consume 会逐步遍历令牌。
local function newParser(tokens)
local pos = 1
local function peek() return tokens[pos] end
local function consume() pos = pos + 1; return tokens[pos-1] end
return {peek=peek, consume=consume}
end表达式语法
该语法遵循优先级:
- 表达式 = 项 ((+ | -) 项)*
- 项 = 因子 ((* | /) 因子)*
- 因子 = 数字 | (表达式) | -因子
解析项
通过解析各项并从左到右合并 +/- 运算结果,解析加法和减法表达式。
local parseExpr, parseTerm, parseFactor
parseExpr = function(p)
local val = parseTerm(p)
while p.peek() == "+" or p.peek() == "-" do
local op = p.consume()
local right = parseTerm(p)
if op == "+" then val = val + right
else val = val - right end
end
return val
end解析因子
解析乘法表达式,包括幂运算。
parseTerm = function(p)
local val = parseFactor(p)
while p.peek() == "*" or p.peek() == "/" do
local op = p.consume()
local right = parseFactor(p)
if op == "*" then val = val * right
else val = val / right end
end
return val
end解析数字和括号
解析基本单元:字面量、带括号的子表达式和一元取负。
parseFactor = function(p)
local tok = p.peek()
if tok == "(" then
p.consume() -- (
local val = parseExpr(p)
p.consume() -- )
return val
elseif tok == "-" then
p.consume()
return -parseFactor(p)
else
return tonumber(p.consume())
end
end综合运用
对表达式进行词法分析、解析和求值。
local function eval(expr)
local tokens = tokenize(expr)
local parser = newParser(tokens)
return parseExpr(parser)
end
print(eval("3 + 4 * 2")) -- 11
print(eval("(3 + 4) * 2")) -- 14
print(eval("2 ^ 10")) -- 1024 (if ^ is supported)扩展解析器
通过扩展语法并向 parseFactor 添加新的分支,加入变量、函数、比较运算符和字符串字面量。
错误报告
在词法分析器中跟踪行和列。引发有意义的错误:"Expected ')' at position 7, got '+'".
解析器生成器
对于复杂语法,请使用解析器生成器,例如 LPEG(解析表达式语法)。对于大型语法,LPEG 比手写的递归下降解析器强大得多,表达能力也更强。
解析器问题
递归下降解析器使用什么机制来确保运算符优先级?
回顾:简单表达式解析器
递归下降解析器为每条语法规则使用一个函数,并通过调用层次自然地确保运算符优先级。先进行词法分析,then 实现表达式 → 项 → 因子函数。加入变量和函数后,就能构建完整的表达式语言。
常见问题解答
「简单表达式解析器」课时是免费的吗?
是的 — 「简单表达式解析器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「简单表达式解析器」这节课中我会学到什么?
使用纯 Lua 为算术表达式构建递归下降解析器。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「简单表达式解析器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。