Behavioral pattern
Interpreter
Model each rule of a tiny grammar as a class that knows how to interpret() itself — an expression becomes a tree of objects, not a tangle of if-else.
✗ The problem
Ad-hoc parsing turns into spaghetti
Evaluating "5 + 3 - 2" by hand-walking tokens with nested if-else works —
until the grammar grows a third operator, then parentheses, then precedence…
function evaluate(expr) {
const tokens = expr.split(' ');
let result = Number(tokens[0]);
for (let i = 1; i < tokens.length; i += 2) {
if (tokens[i] === '+') result += Number(tokens[i+1]);
else if (tokens[i] === '-') result -= Number(tokens[i+1]);
// new operator? edit this function again…
}
return result;
}
No structure — every new rule tangles the parser further.
✓ The pattern
↑
↑
Every grammar rule becomes a class
Terminal rules (numbers) and non-terminal rules (operators) all implement the same
interpret() contract. An expression is just a tree of them.
class NumberExpr {
constructor(n) { this.n = n; }
interpret() { return this.n; }
}
class AddExpr {
constructor(left, right) { this.left = left; this.right = right; }
interpret() { return this.left.interpret() + this.right.interpret(); }
}
// SubtractExpr mirrors AddExpr, with a "-"
Tree for (5 + 3) - 2
−
SubtractExpr (non-terminal)
+
AddExpr (non-terminal)
5
NumberExpr
3
NumberExpr
2
NumberExpr
✓ See it live
↑
↑
Build the tree, then interpret() it bottom-up
Pick an expression. It builds real NumberExpr / AddExpr /
SubtractExpr objects, then interpret() resolves leaves first, then parents.
Pick an expression above ↑
?
interpret()
?
interpret()
?
NumberExpr
?
NumberExpr
?
NumberExpr
Result: —
✓ Takeaway
A tree of self-evaluating rules
- Each grammar rule is one class implementing
interpret()— the expression itself is a tree of these objects. - Great fit for small DSLs: config rules, query filters, feature-flag expressions.
- Caution: it does not scale to complex grammars — reach for a real parser / AST tool once rules multiply.
🎯 Principle applied: each grammar rule owns its own evaluation (SRP) and new rules are new classes (Open/Closed); the tree of expressions is itself a Composite.
Back to all topics →