一、解釋器模式簡介(Brief Introduction)
解釋器模式(Interpreter Pattern),給定一個語言,定義它的文法的一種表示,並定 義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。使用了解釋器模式,可以很容 易地改變和擴展文法,因為該模式使用類來表示文法規則,可以使用繼承來改變或擴展該文 法。也比較容易實現文法,因為定義抽象語法樹中各個節點的類的實現大體類似,這些類容 易直接編寫。
二、解決的問題(What To Solve)
如果一種特定類型的問題發生的頻率足夠高,那麼可能就值得將該問題的各個實例表述 為一個簡單語言中的句子,這樣就可以構建一個解釋器,該解釋器通過解釋這些句子來解決 問題。
三、解釋器模式分析(Analysis)
1、解釋器模式結構
AbstractExpression抽象類:聲明一個接口,用於執行一個操作。
TerminalExpression類:終結符表達式,實現與文法中的終結符相關的解釋操作。
NonterminalExpression類:非終結符表達式,為文法中的非終結符實現解釋操作。對文 法中每一條規則R1、R2.......RN都需要一個具體的非終結符表達式類。
Context類:包含解釋器之外的一些全局信息。
2、源代碼
1、抽象表達式AbstractExpression
public abstract class AbstractExpression
{
public abstract void Interpret(Context context);
}
2、終結符表達式TerminalExpression
public class TerminalExpression:AbstractExpression
{
public override void Interpret(Context context)
{
Console.WriteLine("調用終止符表達式Terminal.Interpret ()");
}
}
3、非終結符表達式NonterminalExpression
public class NonterminalExpression:AbstractExpression
{
public override void Interpret(Context context)
{
Console.WriteLine("調用非終止符表達式 Nonterminal.Interpret ()");
}
}
4、上下文類Context
public class Context
{
}
5、客戶端代碼
static void Main(string[] args)
{
Context context = new Context();
ArrayList list = new ArrayList();
//填充語法樹
list.Add(new TerminalExpression());
list.Add(new NonterminalExpression());
list.Add(new TerminalExpression());
list.Add(new TerminalExpression());
//解析
foreach (AbstractExpression abstractExpression in list)
{
abstractExpression.Interpret(context);
}
Console.ReadKey();
}
3、程序運行結果
四.解釋器模式案例分析(Example)
1、場景
羅馬字符轉換為十進制數字,如下圖所示
Expression抽象類:抽象表達式,聲明一個抽象的解釋器操作,這個抽象類為抽象語法 樹中所有的節點所共享。
ThousandExpression類:用來核對羅馬字符中的 M ;
HundredExpression類:用來核對羅馬字符中的C, CD, D or CM;
TenExpression類:用來核對羅馬字附中的X, XL, L and XC;
OneExpression類:用來核對羅馬字附中的I, II, III, IV, V, VI, VI, VII, VIII, IX 。
2、代碼
1、上下文類Context
class Context
{
private string _input;
private int _output;
public Context(string input)
{
this._input = input;
}
public string Input
{
get { return _input; }
set { _input = value; }
}
public int Output
{
get { return _output; }
set { _output = value; }
}
}
2、抽象表達式類Expression
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();
}
3、終止符表達式類ThousandExpression、HundredExpression、TenExpression等
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// 用來核對羅馬字符中的 M
/// </remarks>
/// </summary>
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; }
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// 用來核對羅馬字符中的C, CD, D or CM;
/// </remarks>
/// </summary>
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; }
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// 用來核對羅馬字附中的X, XL, L and XC
/// </remarks>
/// </summary>
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; }
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// 用來核對羅馬字附中的I, II, III, IV, V, VI, VI, VII, VIII, IX
/// </remarks>
/// </summary>
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; }
}
4、客戶端代碼
static void Main(string[] args)
{
string roman = "MCMXXVIII";
Context context = new Context(roman);
// Build the 'parse tree'
List<Expression> tree = new List<Expression>();
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);
Console.ReadKey();
}
3、運行結果
五、總結(Summary)
解釋器模式(Interpreter Pattern),給定一個語言,定義它的文法的一種表示,並定 義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。當有一個語言需要解釋執行, 並且你可將該語言中的句子表示為一個抽象的語法樹時,可以考慮使用解釋器模式。
參考資料:http://www.dofactory.com/Patterns/PatternInterpreter.aspx
出處:http://www.cnblogs.com/ywqu