Interpreter: A way to include language elements in a program
Use to implement compile
一些应用提供了内建(Build-In)的脚本或者宏语言来让用户可以定义他们能够在系统
中进行的操作。Interpreter 模式的目的就是使用一个解释器为用户提供一个一门定义语言的
语法表示的解释器,然后通过这个解释器来解释语言中的句子。
This real-world code demonstrates the Interpreter pattern which is used to convert a Roman numeral to a decimal.
The classes and/or objects participating in this pattern are:
- AbstractExpression (Expression)
- declares an interface for executing an operation
- TerminalExpression ( ThousandExpression, HundredExpression, TenExpression, OneExpression )
- implements an Interpret operation associated with terminal symbols in the grammar.
- an instance is required for every terminal symbol in the sentence.
- NonterminalExpression ( not used )
- 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.
- Context (Context)
- contains information that is global to the interpreter
- Client (InterpreterApp)
- 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 -- Real World example
|
using System; using System.Collections;
namespace DoFactory.GangOfFour.Interpreter.RealWorld {
// MainApp test application
class MainApp { static void
Main
() { string roman = "MCMXXVIII"; Context context = new Context(roman);
// Build the 'parse tree' ArrayList tree = new ArrayList(); tree.Add(new ThousandExpression()); tree.Add(new HundredExpression()); tree.Add(new TenExpression()); tree.Add(new OneExpression());
// Interpret foreach (Expression exp in tree) { exp.Interpret(context); }
Console.WriteLine("{0} = {1}", roman, context.Output);
// Wait for user Console.Read(); } }
// "Context"
class Context { private string input; private int output;
// Constructor public Context(string input) { this.input = input; }
// Properties public string Input { get{ return input; } set{ input = value; } }
public int Output { get{ return output; } set{ output = value; } } }
// "AbstractExpression"
abstract class Expression { public void Interpret(Context context) { if (context.Input.Length == 0) return;
if (context.Input.StartsWith(Nine())) { context.Output += (9 * Multiplier()); context.Input = context.Input.Substring(2); } else if (context.Input.StartsWith(Four())) { context.Output += (4 * Multiplier()); context.Input = context.Input.Substring(2); } else if (context.Input.StartsWith(Five())) { context.Output += (5 * Multiplier()); context.Input = context.Input.Substring(1); }
while (context.Input.StartsWith(One())) { context.Output += (1 * Multiplier()); context.Input = context.Input.Substring(1); } }
public abstract string One(); public abstract string Four(); public abstract string Five(); public abstract string Nine(); public abstract int Multiplier(); }
// Thousand checks for the Roman Numeral M // "TerminalExpression"
class ThousandExpression : Expression { public override string One() { return "M"; } public override string Four(){ return " "; } public override string Five(){ return " "; } public override string Nine(){ return " "; } public override int Multiplier() { return 1000; } }
// Hundred checks C, CD, D or CM // "TerminalExpression"
class HundredExpression : Expression { public override string One() { return "C"; } public override string Four(){ return "CD"; } public override string Five(){ return "D"; } public override string Nine(){ return "CM"; } public override int Multiplier() { return 100; } }
// Ten checks for X, XL, L and XC // "TerminalExpression"
class TenExpression : Expression { public override string One() { return "X"; } public override string Four(){ return "XL"; } public override string Five(){ return "L"; } public override string Nine(){ return "XC"; } public override int Multiplier() { return 10; } }
// One checks for I, II, III, IV, V, VI, VI, VII, VIII, IX // "TerminalExpression"
class OneExpression : Expression { public override string One() { return "I"; } public override string Four(){ return "IV"; } public override string Five(){ return "V"; } public override string Nine(){ return "IX"; } public override int Multiplier() { return 1; } } }
|
Output
MCMXXVIII = 1928
|