Design Pattern - Interpreter(C#)
2010-12-02 20:12
525 查看
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
Sample Code in C#
Thisstructural code demonstrates the Interpreter patterns, which using a defined grammer, provides the interpreter that processes parsed statements.
// --------------------------------------------------------------------------------------------------------------------
// <copyright company="Chimomo's Company" file="Program.cs">
// Respect the work.
// </copyright>
// <summary>
// Structural Interpreter Design Pattern.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace CSharpLearning
{
using System;
using System.Collections;
/// <summary>
/// Startup class for Structural Interpreter Design Pattern.
/// </summary>
internal static class Program
{
#region Methods
/// <summary>
/// Entry point into console application.
/// </summary>
private static void Main()
{
var context = new Context();
// Usually a tree
var list = new ArrayList
{
new TerminalExpression(),
new NonterminalExpression(),
new TerminalExpression(),
new TerminalExpression()
};
// Interpret
foreach (AbstractExpression exp in list)
{
exp.Interpret(context);
}
}
#endregion
}
/// <summary>
/// The 'Context' class
/// </summary>
internal class Context
{
}
/// <summary>
/// The 'AbstractExpression' abstract class
/// </summary>
internal abstract class AbstractExpression
{
#region Public Methods and Operators
/// <summary>
/// The interpret.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
public abstract void Interpret(Context context);
#endregion
}
/// <summary>
/// The 'TerminalExpression' class
/// </summary>
internal class TerminalExpression : AbstractExpression
{
#region Public Methods and Operators
/// <summary>
/// The interpret.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
public override void Interpret(Context context)
{
Console.WriteLine("Called Terminal.Interpret()");
}
#endregion
}
/// <summary>
/// The 'NonterminalExpression' class
/// </summary>
internal class NonterminalExpression : AbstractExpression
{
#region Public Methods and Operators
/// <summary>
/// The interpret.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
public override void Interpret(Context context)
{
Console.WriteLine("Called Nonterminal.Interpret()");
}
#endregion
}
}
// 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.
// --------------------------------------------------------------------------------------------------------------------
// <copyright company="Chimomo's Company" file="Program.cs">
// Respect the work.
// </copyright>
// <summary>
// Real-World Interpreter Design Pattern.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace CSharpLearning
{
using System;
using System.Collections.Generic;
/// <summary>
/// Startup class for Real-World Interpreter Design Pattern.
/// </summary>
internal static class Program
{
#region Methods
/// <summary>
/// Entry point into console application.
/// </summary>
private static void Main()
{
const string Roman = "MCMXXVIII";
var context = new Context(Roman);
// Build the 'parse tree'
var tree = new List<Expression>
{
new ThousandExpression(),
new HundredExpression(),
new TenExpression(),
new OneExpression()
};
// Interpret
foreach (Expression exp in tree)
{
exp.Interpret(context);
}
Console.WriteLine("{0} = {1}", Roman, context.Output);
}
#endregion
}
/// <summary>
/// The 'Context' class
/// </summary>
internal class Context
{
// Constructor
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="Context"/> class.
/// </summary>
/// <param name="input">
/// The input.
/// </param>
public Context(string input)
{
this.Input = input;
}
#endregion
// Gets or sets input
#region Public Properties
/// <summary>
/// Gets or sets the input.
/// </summary>
public string Input { get; set; }
// Gets or sets output
/// <summary>
/// Gets or sets the output.
/// </summary>
public int Output { get; set; }
#endregion
}
/// <summary>
/// The 'AbstractExpression' class
/// </summary>
internal abstract class Expression
{
#region Public Methods and Operators
/// <summary>
/// The five.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public abstract string Five();
/// <summary>
/// The four.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public abstract string Four();
/// <summary>
/// The interpret.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
public void Interpret(Context context)
{
if (context.Input.Length == 0)
{
return;
}
if (context.Input.StartsWith(this.Nine()))
{
context.Output += 9 * this.Multiplier();
context.Input = context.Input.Substring(2);
}
else if (context.Input.StartsWith(this.Four()))
{
context.Output += 4 * this.Multiplier();
context.Input = context.Input.Substring(2);
}
else if (context.Input.StartsWith(this.Five()))
{
context.Output += 5 * this.Multiplier();
context.Input = context.Input.Substring(1);
}
while (context.Input.StartsWith(this.One()))
{
context.Output += 1 * this.Multiplier();
context.Input = context.Input.Substring(1);
}
}
/// <summary>
/// The multiplier.
/// </summary>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
public abstract int Multiplier();
/// <summary>
/// The nine.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public abstract string Nine();
/// <summary>
/// The one.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public abstract string One();
#endregion
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// Thousand checks for the Roman Numeral M
/// </remarks>
/// </summary>
internal class ThousandExpression : Expression
{
#region Public Methods and Operators
/// <summary>
/// The five.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Five()
{
return " ";
}
/// <summary>
/// The four.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Four()
{
return " ";
}
/// <summary>
/// The multiplier.
/// </summary>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
public override int Multiplier()
{
return 1000;
}
/// <summary>
/// The nine.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Nine()
{
return " ";
}
/// <summary>
/// The one.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string One()
{
return "M";
}
#endregion
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// Hundred checks C, CD, D or CM
/// </remarks>
/// </summary>
internal class HundredExpression : Expression
{
#region Public Methods and Operators
/// <summary>
/// The five.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Five()
{
return "D";
}
/// <summary>
/// The four.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Four()
{
return "CD";
}
/// <summary>
/// The multiplier.
/// </summary>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
public override int Multiplier()
{
return 100;
}
/// <summary>
/// The nine.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Nine()
{
return "CM";
}
/// <summary>
/// The one.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string One()
{
return "C";
}
#endregion
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// Ten checks for X, XL, L and XC
/// </remarks>
/// </summary>
internal class TenExpression : Expression
{
#region Public Methods and Operators
/// <summary>
/// The five.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Five()
{
return "L";
}
/// <summary>
/// The four.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Four()
{
return "XL";
}
/// <summary>
/// The multiplier.
/// </summary>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
public override int Multiplier()
{
return 10;
}
/// <summary>
/// The nine.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Nine()
{
return "XC";
}
/// <summary>
/// The one.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string One()
{
return "X";
}
#endregion
}
/// <summary>
/// A 'TerminalExpression' class
/// <remarks>
/// One checks for I, II, III, IV, V, VI, VI, VII, VIII, IX
/// </remarks>
/// </summary>
internal class OneExpression : Expression
{
#region Public Methods and Operators
/// <summary>
/// The five.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Five()
{
return "V";
}
/// <summary>
/// The four.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Four()
{
return "IV";
}
/// <summary>
/// The multiplier.
/// </summary>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
public override int Multiplier()
{
return 1;
}
/// <summary>
/// The nine.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string Nine()
{
return "IX";
}
/// <summary>
/// The one.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string One()
{
return "I";
}
#endregion
}
}
// Output:
/*
MCMXXVIII = 1928
*/
相关文章推荐
- (原創) 我的Design Pattern之旅[4]:使用Generic改進Strategy Pattern (OO) (Design Pattern) (.NET) (C#)
- Design Pattern - Factory Method(C#)
- C# 版本设计模式(Design Pattern)(转)
- Design Pattern - Prototype(C#)
- Design Pattern - IDisposable Pattern(C#)
- [导入]C#面向对象设计模式纵横谈(16):(行为型模式) Interpreter 解释器模式.zip(9.14 MB)
- (原創) 我的Design Pattern之旅[1]:Strategy Pattern (OO) (Design Pattern) (C/C++) (template) (.NET) (C#)
- Design Pattern - Abstract Factory(C#)
- Design Pattern - Adapter(C#)
- (轉貼) C#與Design Pattern的視頻教學 (OO) (Design Pattern) (.NET) (C#)
- C#设计模式之Interpreter
- (原創) 我的Design Pattern之旅[6] : Adapter Pattern (OO) (Design Pattern) (C/C++) (.NET) (C#) (C++/CLI) (VB)
- Design Pattern - Composite(C#)
- Design Pattern学习(C#) ---- Singleton
- 关于C#交互式窗口(C# Shell REPL Interpreter Interactive)
- 设计模式(Design Pattern) - 行为型模式(Behavioral Pattern) - 解释器模式(Interpreter) - Java实现
- Design Pattern - Decorator(C#)
- (原創) 我的Design Pattern之旅[7]:使用泛型改進Adapter Pattern (OO) (Design Pattern) (C/C++) (template) (.NET) (C#) (C++/CLI) (VB)
- Design Pattern - Template Method(C#)
- Design Pattern - Chain of Responsibility(C#)