设计模式之Interpreter解释器模式
来源:互联网 发布:c语言实现ftp文件传输 编辑:程序博客网 时间:2024/05/01 07:51
意图intent:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
适用性:
- 当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:
- 该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间。
- 效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下, 转换器仍可用解释器模式实现, 该模式仍是有用的。
Definition:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
participants
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模式其实也是非常简单的,主要就是用了一个interface,然后client利用interface可以通过具体的class来进行操作,从而得到具体、实际的结果。TerminalExpression和NonTerminalExpression都实现了AbstractionExpression的interpret函数。在下面的real world代码中没有用到NonTerminalExpression这个类,实际上是一样的,主要就是实现了那个interpret类。Over。
sample code in C#
This structural code demonstrates the Interpreter patterns, which using a defined grammer, provides the interpreter that processes parsed statements.
// 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 Called
Terminal.Interpret()
Called Nonterminal.Interpret()
Called Terminal.Interpret()
Called Terminal.Interpret()
This real-world code demonstrates the Interpreter pattern which is used to convert a Roman numeral to a decimal.
// 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
- 设计模式之Interpreter解释器模式
- 设计模式之解释器模式,interpreter
- 设计模式之解释器模式(interpreter)
- 设计模式之:解释器模式(Interpreter)
- 设计模式之解释器模式(Interpreter)
- 设计模式之Interpreter(解释器)
- 设计模式之Interpreter(解释器)
- 设计模式之Interpreter(解释器)
- 设计模式之Interpreter(解释器)
- GOF设计模式之INTERPRETER(解释器)
- Interpreter(解释器)设计模式
- 设计模式读书笔记之解释器模式(Interpreter pattern)
- 设计模式之(十六)- 解释器模式(interpreter)
- 23种设计模式之解释器模式(Interpreter)
- 设计模式之(二十)解释器模式Interpreter
- 设计模式之解释器模式(Interpreter Pattern)
- 设计模式之解释器模式(Interpreter)
- 设计模式之解释器模式(Interpreter)
- Appfuse 开发环境搭建
- 11月17日spring mvc入门培训
- 回忆2
- 文本比较算法剖析(1)-如何确定最大匹配率
- 程序员应该做的事
- 设计模式之Interpreter解释器模式
- 水煮三国(一) 创业时代的七堂必修课
- KNN,TC(text category)基本算法
- HOOK启思录---前言:HOOK是一种思想
- 爱情与婚姻
- ASP.NET中Datagrid常见错误
- 水煮三国(二) 能把梳子卖给和尚吗
- 佛与蜘蛛
- 关于ViewState