What is the Interpreter Pattern?
The Interpreter Pattern is a behavioral design pattern that:
Defines a representation for a grammar and an interpreter that uses this representation to interpret sentences in the language.
It is often used when you want to evaluate custom languages, expressions, or rules.
When to Use
- When you have a simple grammar and want to interpret expressions.
- For configuration languages, rules engines, or mini DSLs.
- When you need to evaluate expressions repeatedly.
Real-World Analogy
Think of a calculator:
- You type
3 + 5 - 2. - The calculator interprets the expression according to rules (grammar).
- Then, it gives you the result.
The Interpreter Pattern formalizes this process in code.
Key Participants
| Role | Responsibility |
|---|---|
| AbstractExpression | Defines an interface for interpreting expressions |
| TerminalExpression | Represents atomic (final) values in the grammar |
| NonTerminalExpression | Represents composite rules (e.g., addition, subtraction) |
| Context | Stores global information (like variables, environment) |
| Client | Builds and interprets the expression tree |
Dart Example: Simple Math Expression Interpreter
We’ll build a tiny interpreter that can evaluate expressions like:
Edit(5 + 3) - 2
Step 1: Define Expression Interface
abstract class Expression {
int interpret();
}
Step 2: Create Terminal Expression (Numbers)
class NumberExpression implements Expression {
final int number;
NumberExpression(this.number);
@override
int interpret() => number;
}
Step 3: Create Non-Terminal Expressions
class AddExpression implements Expression {
final Expression left;
final Expression right;
AddExpression(this.left, this.right);
@override
int interpret() => left.interpret() + right.interpret();
}
class SubtractExpression implements Expression {
final Expression left;
final Expression right;
SubtractExpression(this.left, this.right);
@override
int interpret() => left.interpret() - right.interpret();
}
Step 4: Client Code
void main() {
// Build the expression: (5 + 3) - 2
Expression expression = SubtractExpression(
AddExpression(NumberExpression(5), NumberExpression(3)),
NumberExpression(2),
);
print("Result: ${expression.interpret()}");
}
Output
Result: 6
Benefits
| Benefit | Description |
|---|---|
| Extensible Grammar | Easy to add new operations (e.g., multiplication, divide) |
| Readable Representation | Expression trees mirror actual grammar |
| Useful for DSLs | Helps implement rule engines, scripting, parsing |
Drawbacks
- Complexity grows quickly if grammar is large.
- Performance issues for very large or nested expressions.
- May require additional parsing logic to convert text → expression tree.
Summary
| Concept | Dart Example |
|---|---|
| Expression | Expression (interface) |
| TerminalExpr | NumberExpression |
| NonTerminalExpr | AddExpression, SubtractExpression |
| Context | (Not needed here, but useful for variables) |



