Design Pattern - Interpreter(C#)
阿新 • • 發佈:2018-11-02
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
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#
This structural 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"/>.