design patterns · behavioral
Interpreter
Defines a grammar for a language and provides an interpreter to evaluate sentences in that language.
Pattern
Overview
Intent
Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
Real-World Analogy
A calculator - each number is a terminal expression, each operator is a non-terminal expression that evaluates its sub-expressions.
When you need to interpret sentences in a simple language (math expressions, SQL clauses, config rules), model each grammar rule as a class and build a parse tree of expression objects.
Terminal expressions represent atomic values (numbers, variables). Non-terminal expressions represent grammar rules and hold references to sub-expressions. Each class implements interpret() which recursively evaluates sub-expressions.
When to use
Simple DSLs, SQL clause parsing, regular expression engines, mathematical expression evaluators, configuration file parsers with a defined grammar.
When not to
Complex grammars - use parser generators (ANTLR, JavaCC) instead. Performance-critical parsing.
Participants
Key Insights
- Interpreter is essentially Composite applied to a parse tree
- Each grammar rule becomes a class - terminal rules are leaves, non-terminal rules are composites
- The interpret() method is recursive - non-terminals call interpret() on their children
- Visitor pattern is often used with Interpreter to add operations to the expression tree