1. 程式人生 > >Design Pattern - Interpreter(C#)

Design Pattern - Interpreter(C#)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!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"/>.