Simple Expression Parser
Build a recursive descent parser for arithmetic expressions in pure Lua.
Simple Expression Parser is a free Lua Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Goal: Parse Arithmetic Expressions
Build a recursive descent parser in pure Lua that parses and evaluates expressions like 3 + 4 * (2 - 1), respecting operator precedence.
Tokenizer
First, tokenize the input into numbers, operators, and parentheses.
local function tokenize(expr)
local tokens = {}
for tok in expr:gmatch("[%d%.]+|[%+%-%*/%(%)%^]|%S") do
tokens[#tokens+1] = tok
end
return tokens
endImproved Tokenizer
A more robust tokenizer using gmatch patterns.
local function tokenize(expr)
local tokens = {}
for tok in expr:gmatch("%d+%.?%d*|[%+%-%*/%(%)%^]") do
tokens[#tokens+1] = tok
end
return tokens
endParser State
The parser carries a token list and a position. Helper functions peek and consume advance through tokens.
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}
endGrammar for Expressions
The grammar respects precedence:
- expr = term ((+ | -) term)*
- term = factor ((* | /) factor)*
- factor = number | (expr) | -factor
Parsing Terms
Parse additive expressions by parsing terms and folding +/- left to right.
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
endParsing Factors
Parse multiplicative expressions, including exponentiation.
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
endParsing Numbers and Parentheses
Parse atoms: literals, parenthesized sub-expressions, and unary negation.
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
endPutting It Together
Tokenize, parse, and evaluate an expression.
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)Extending the Parser
Add variables, functions, comparison operators, and string literals by extending the grammar and adding new cases to parseFactor.
Error Reporting
Track line and column in the tokenizer. Raise meaningful errors: "Expected ')' at position 7, got '+'".
Parser Generators
For complex grammars, use parser generators like LPEG (Parsing Expression Grammars). LPEG is much more powerful and expressive than hand-written recursive descent for large grammars.
Parser Question
What does a recursive descent parser use to enforce operator precedence?
Recap: Simple Expression Parser
A recursive descent parser uses one function per grammar rule, naturally enforcing operator precedence through the call hierarchy. Tokenize first, then implement expr → term → factor functions. Extend with variables and functions for a full expression language.
Frequently asked questions
Is the “Simple Expression Parser” lesson free?
Yes — the full text of “Simple Expression Parser” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.
What will I learn in “Simple Expression Parser”?
Build a recursive descent parser for arithmetic expressions in pure Lua. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Lua Academy?
No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Simple Expression Parser” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Lua Academy lesson?
Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- DSL Design Principles in Lua
- Operator Overloading for DSL Fluency
- Building a Config DSL
- Simple Expression Parser