What It Is
The Interpreter pattern evaluates sentences in a small language by building a tree of expression objects — each node knows how to interpret itself. Numbers interpret to themselves; an addition node interprets its two sides and adds them.
It fits small languages: filters, formulas, simple rules. Real languages deserve real parser tools.
Example: A Tiny Calculator
The input 3 + 4 - 2 becomes a tree of Number, Add and Subtract nodes. One call to interpret() on the root evaluates the whole expression.
Every node interprets itself
parse builds the tree left to right; interpret() walks it. Supporting * would be one new node class — the existing ones stay untouched.
Output: PHP script
<?php
// Every node knows how to interpret itself.
interface Expression {
public function interpret(): int;
}
class Number implements Expression {
public function __construct(private int $value) {}
public function interpret(): int {
return $this->value;
}
}
class Add implements Expression {
public function __construct(
private Expression $left,
private Expression $right,
) {}
public function interpret(): int {
return $this->left->interpret() + $this->right->interpret();
}
}
class Subtract implements Expression {
public function __construct(
private Expression $left,
private Expression $right,
) {}
public function interpret(): int {
return $this->left->interpret() - $this->right->interpret();
}
}
function parse(string $input): Expression {
$parts = explode(" ", $input);
$expr = new Number((int) $parts[0]);
for ($i = 1; $i < count($parts); $i += 2) {
$number = new Number((int) $parts[$i + 1]);
$expr = $parts[$i] === "+" ? new Add($expr, $number) : new Subtract($expr, $number);
}
return $expr;
}
$input = "3 + 4 - 2";
echo $input, " = ", parse($input)->interpret(), "\n";
When to Use It
Use it when users or configs express logic in a small language of your design: search filters, pricing formulas, validation rules.
Skip it when the "language" is three fixed options (use a match) — or a real language (use a parser generator or an existing engine).
Pros and Cons
Pros: the grammar maps one-to-one onto small classes; new operations are new node classes; expression trees can be built, checked and reused.
Cons: grows painful as the grammar grows; parsing itself still has to be written; performance is modest compared to compiled logic.