Interpreter
Category
Behavioral pattern
Problem
Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. Useful for simple grammars or DSLs.
Solution
- Define a grammar as a class hierarchy (each rule is a class)
- Each class implements an
interpret()method - Build an abstract syntax tree representing the sentence
- Call
interpret()on the root node to evaluate the sentence
Structure
- AbstractExpression: Declares an
interpret()method - TerminalExpression: Implements
interpret()for terminal grammar rules - NonterminalExpression: Implements
interpret()for non-terminal rules; holds child expressions - Context: Contains global information needed by the interpreter
- Client: Builds the abstract syntax tree representing a sentence in the language
Key Benefits
- Easy to change/extend grammar — New rules are new classes
- Clear grammar representation — Grammar is expressed as classes
Trade-offs
- Performance — Interpreting can be slow compared to compiled code
- Scalability — Grammar complexity grows quadratically with the number of rules
When to Use
- The grammar is simple enough to be implemented manually
- Efficiency is not a critical concern
- You need to represent a language as an object model
Examples
- SQL query parsers interpret SQL grammar
- Regex engines interpret regular expression grammar
- Python
andexec()` as interpreters - Configuration file parsers (YAML, JSON, XML)
- Domain-specific languages in Ruby On Rails