13 April 2014

Interpreter -- Design Pattern

     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:
  • Abstract Expression(Expression)
     Declares an interface for executing an operation Terminal Expression  ( Thousand Expression, Hundred Expression, Ten Expression, One Expression )

     Implements an Interpret operation associated with terminal symbols in the grammar. 

     An instance is required for every terminal symbol in the sentence.
  • Non-terminal Expression(not used )
     One such class is required for every rule R ::= R1R2...Rn in the grammar maintains instance variables of type Abstract Expression for each of the symbols R1 through Rn.

     Implements an Interpret operation for non-terminal 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 (Interpreter App)
     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 Non-terminal Expression and Terminal Expression classes invokes the Interpret operation

Example for Interpreter Design Pattern

using System;
using System.Collections; 
namespace Interpreter.Structural
{
  /// <summary>
  /// MainApp startup class for Structural
  /// Interpreter Design Pattern.
  /// </summary>
  class MainApp
  {
    /// <summary>
    /// Entry point into console application.
    /// </summary>
    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.ReadKey();
    }
  } 
  /// <summary>
  /// The 'Context' class
  /// </summary>
  class Context
  {
  } 
  /// <summary>
  /// The 'AbstractExpression' abstract class
  /// </summary>
  abstract class AbstractExpression
  {
    public abstract void Interpret(Context context);
  } 
  /// <summary>
  /// The 'TerminalExpression' class
  /// </summary>
  class TerminalExpression : AbstractExpression
  {
    public override void Interpret(Context context)
    {
      Console.WriteLine("Called Terminal.Interpret()");
    }
  } 
  /// <summary>
  /// The 'NonterminalExpression' class
  /// </summary>
  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()


No comments:

Post a Comment