Applied Design Patterns with Java
Behavioral :: Interpreter (243) {C ch 18}
Intent
Given a language, define a represention for its grammar along with
an Interpreter
that uses the representation to interpret sentences in the language.
Motivation
If a particular problem occurs often, it might
be worthwhile to express instances of the problem as sentences in a simple language, and then build an interpreter
that solves the problem by interpreting these sentences. Searching for strings that match a pattern is a common
problem. Regular expressions are a standard language for specifying patterns of strings. Rather than building custom
algorithms to match each pattern against strings, search algorithms could interpret a regular expression that specifies
a set of strings to match.
The Interpreter pattern describes how to define a grammar for simple languages, represent sentences in the language, and
interpret these sentences. The pattern describes how to define a grammar for regular expressions, represent a particular
regular expression, and how to interpret that regular expression. Suppose the following grammar defines the regular
expressions:
expression ::= literal | alternation | sequence | repetition |
'(' expression ')'
alternation ::= expression '|' expression
sequence ::= expression '&' expression
repetition ::= expression '*'
literal ::= 'a' | 'b' | 'c' | ... { 'a' | 'b' | 'c' | ... }*
The symbol expression is the start symbol, and literal is a terminal symbol defining simple words. The Interpreter
pattern uses a class to represent each grammar rule. Symbols on the right-hand side of the rule are instance variables
of these classes. The grammar above is represented by five classes: an abstract class RegularExpression and its four subclasses LiteralExpression,
AlternationExpression, SequenceExpression, and RepetitionExpression. The last three classes define variables that
hold subexpressions.
Every regular expression defined by this grammar is represented by an abstract syntax
tree made up of instances of these classes. This abstract syntax tree
represents the regular expression
raining & (dogs | cats) *
Create an interpreter for these regular expressions by defining the Interpret operation on each subclass of RegularExpression.
Interpret takes as an argument the context in which to interpret the expression. The context contains the input
string and information on how much of it has been matched so far. Each subclass of RegularExpression implements
Interpret to match the next part of the input string based on the current context. For example: