Middle+
What is the 'Interpreter' design pattern?
sobes.tech AI
Answer from AI
The "Interpreter" design pattern is used to define a grammatical representation for a language and provides an interpreter for this representation. The pattern is useful when there is a simple language and a frequent need to interpret it.
Main components of the pattern:
- Abstract Expression: Declares an abstract
interpretoperation that is common to all nodes in the abstract syntax tree. - Terminal Expression: Implements the
interpretoperation for terminal symbols of the grammar. Each terminal symbol corresponds to one or more instances of theTerminalExpressionclass. - Nonterminal Expression: Implements the
interpretoperation for nonterminal symbols of the grammar. Each grammar rule can be represented by such a class. TheNonterminalExpressionclass usually holds references to otherAbstractExpressionobjects (terminal or nonterminal). - Context: Contains information common to the interpreter. It may hold state or operands for interpretation.
- Client: Builds (or receives) an abstract syntax tree using the
TerminalExpressionandNonterminalExpressionclasses, and calls theinterpretoperation.
Example usage: parsing and evaluating simple arithmetic expressions.
# Abstract Expression
class Expression:
def interpret(self, context):
pass
# Terminal Expression: numbers
class Number(Expression):
def __init__(self, value):
self.value = value
def interpret(self, context):
return self.value
# Nonterminal Expression: addition
class Add(Expression):
def __init__(self, left, right):
self.left = left
self.right = right
def interpret(self, context):
return self.left.interpret(context) + self.right.interpret(context)
# Nonterminal Expression: subtraction
class Subtract(Expression):
def __init__(self, left, right):
self.left = left
self.right = right
def interpret(self, context):
return self.left.interpret(context) - self.right.interpret(context)
# Context (can be a simple dictionary for variables, etc.)
class Context:
pass
# Client code
context = Context()
tree = Add(Number(5), Subtract(Number(10), Number(2))) # 5 + (10 - 2)
result = tree.interpret(context)
print(result) # Output: 13
Advantages:
- Easy to add new interpretations or extend the grammar.
- Grammar is represented as classes, which makes it easier to understand.
Disadvantages:
- Can become complex if the grammar is very large or complicated. In such cases, other parsing methods might be preferable.