Programming - Interpreter Behavioral Design Pattern
Given a language, define a representation for its grammar
along with an interpreter that uses the representation to
interpret sentences in the language.
The classes and/or objects participating in this pattern
are:
-
AbstractExpression
- declares an interface for executing an operation
-
TerminalExpression
- implements an Interpret operation associated with
terminal symbols in the grammar.
- an instance is required for every terminal symbol in
the sentence.
-
NonterminalExpressionand
- one such class is required for every rule R ::=
R1R2...Rn in the grammar
- maintains instance variables of type
AbstractExpression for each of the symbols R1 through
Rn.
- implements an Interpret operation for nonterminal
symbols in the grammar. Interpret typically calls itself
recursively on the variables representing R1 through
Rn.
-
Contextand
- contains information that is global to the
interpreter
-
Clientand
- builds (or is given) an abstract syntax tree
representing a particular sentence in the language that
the grammar defines. The abstract syntax tree is
assembled from instances of the NonterminalExpression and
TerminalExpression classes
- invokes the Interpret operation
|
// Interpreter pattern -- Structural example
|
|
using System;
using System.Collections;
namespace
DoFactory.GangOfFour.Interpreter.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
Context context
= new Context();
// Usually a
tree
ArrayList list =
new ArrayList();
// Populate
'abstract syntax tree'
list.Add(new
TerminalExpression());
list.Add(new
NonterminalExpression());
list.Add(new
TerminalExpression());
list.Add(new
TerminalExpression());
//
Interpret
foreach
(AbstractExpression exp in list)
{
exp.Interpret(context);
}
// Wait for
user
Console.Read();
}
}
// "Context"
class Context
{
}
// "AbstractExpression"
abstract class AbstractExpression
{
public abstract void
Interpret(Context context);
}
// "TerminalExpression"
class TerminalExpression :
AbstractExpression
{
public override void
Interpret(Context context)
{
Console.WriteLine("Called
Terminal.Interpret()");
}
}
// "NonterminalExpression"
class NonterminalExpression :
AbstractExpression
{
public override void
Interpret(Context context)
{
Console.WriteLine("Called
Nonterminal.Interpret()");
}
}
}
Output expected:
Called Terminal.Interpret()
Called Nonterminal.Interpret()
Called Terminal.Interpret()
Called Terminal.Interpret()
|