解释器模式-c#实现

1.模式定义:

  给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

  Given a language,define a representation for its grammar along with an interpreter that uses representation to interpret sentences in the language.

2.结构:

  AbstractExpression(抽象表达式):在抽象表达式声明了抽象的解释操作,它是所有终结表达式和非终结表达式的公共父类。

  TerminalExpression(终结符表达式):终结符表达式是抽象表达式的子类,它实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例。通常,在一个解释器模式中只有少数几个终结符表达式类,它们的实例可以通过非终结符表达式组成较为复杂的句子。

  NonterminalExpression(非终结符表达式):它实现了文法中非终结符的解释操作,由于在非终结符表达式中可以包含终结符表达式,也可以继续包含非终结符表达式,因此其解释操作一般通过递归的方式来完成。

  Context(环境类):又称上下文类,它用于存储解释器之外的一些全局信息,通常零食存储了需要解释的语句。

3.实现(抽象代码):

  //抽象表达式类

  abstract class AbstractExpression{

    public abstract void Interprete(Context ctx);

  }

  //终结符表达式类

  class TerminalExpression:AbstractExpression

  {

    public override void Interpret(Context ctx){...}

  }

  //非终结符表达式类

  class NonterminalExpression:AbstractExpression

  {

    private AbstractExpression left;

    private AbstractExpression right;

    public NonterminalExpression(AbstractExpression left,AbstractExpression right){

      this.left=left;

      this.right=right;

    }

    public override void Interpret(Context ctx){

    //递归调用每一个组成部分的Interpret()方法

    //在递归的同时指定组成部分的连接方式,即非终结符的功能。

    }

  }

  //环境类

  using System.Collection;

  class Context{

    private Hashtable ht=new Hashtable();

    //给集合对象设值

    public void Assign(string key,string value){

      ht.Add(key,value);

  }

  //获取存储在集合对象中的值

  public string Lookup(string key){

    return (string)ht[key];

    }

  }

  环境类Context的对象通常作为参数被传递到所有表达式的解释方法Interpret()中,可以在环境类对象中存储和访问表达式解释器的状态,向表达式解释器提供一些全局的,公共的数据,此外,还可以在环境类中增加一些所有表达式解释器都共有的功能,以减轻解释器的职责。当系统无须提供全局公共信息时可以省略环境类,根据实际情况决定是否需要环境类。

4.案例代码:

  //抽象表达式角色:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterPretreSample
{
  abstract class AbstractNode
  {
    public abstract string Interpret();
  }
}

//And节点类,充当非终结符表达式角色:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterPretreSample
{
  class AndNode:AbstractNode
  {
    private AbstractNode left;
    private AbstractNode right;
    public AndNode(AbstractNode left,AbstractNode right) {
      this.left = left;
      this.right = right;
    }
  public override string Interpret()
  {
    return left.Interpret() + "再" + right.Interpret();
    //throw new NotImplementedException();
  }
  }
}

  

//简单句子节点类,充当非终结符表达式角色:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterPretreSample
{
  class SentenceNode:AbstractNode
  {
    private AbstractNode direction;
    private AbstractNode action;
    private AbstractNode distance;
    public SentenceNode(AbstractNode direction,AbstractNode action,AbstractNode distance) {
      this.direction = direction;
      this.action = action;
      this.distance = distance;
    }
  public override string Interpret()
  {
    return direction.Interpret() + action.Interpret() + distance.Interpret();
    //throw new NotImplementedException();
  }
  }
}

  

//方向节点类,充当终结符表达式角色

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterPretreSample
{
  class DirectionNode:AbstractNode
  {
    private string direction;
    public DirectionNode(string direction) {
      this.direction = direction;
    }
    public override string Interpret()
    { 
    if (direction=="up") {
      return "向上";
    }
    else if (direction=="down") {
    return "向下";
    }
    else if (direction=="left") {
    return "向左";
    }
    else if (direction=="right")
    {
    return "right";
    }
    else {
    return "无效指令";
    }
    //throw new NotImplementedException();
  }
}
}

  

//动作节点类,充当终结符表达式角色类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterPretreSample
{
class ActionNode:AbstractNode
{
private string action;
public ActionNode(string action) {
this.action = action;
}
public override string Interpret()
{
if (action=="move") {
return "移动";
}
else if (action=="run")
{
return "快速移动";
}
else {
return "无效指令";
}
//throw new NotImplementedException();
}
}
}

  

//距离节点类,充当终结符表达式角色

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterPretreSample
{
class DistanceNode:AbstractNode
{
private string distance;
public DistanceNode(string distance) {
this.distance = distance;
}
public override string Interpret()
{
return this.distance;
//throw new NotImplementedException();
}
}
}

  

//指令处理类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterPretreSample
{
class InstructionHandler
{
private AbstractNode node;

public void Handle(string instruction)
{
AbstractNode left = null, right = null;
//Stack stack = new Stack();
AbstractNode direction = null, action = null, distance = null;
Stack<AbstractNode> stack = new Stack<AbstractNode>();
string[] words = instruction.Split(' ');
for (int i = 0; i < words.Length; i++)
{
if (words[i].Equals("end"))
{
left = (AbstractNode)stack.Pop();
string word1 = words[i];
direction = new DirectionNode(word1);
string word2 = words[i];
action = new ActionNode(word2);
string word3 = words[i];
distance = new DistanceNode(word3);
right = new SentenceNode(direction, action, distance);
stack.Push(new AndNode(left, right));
}
else
{
string word1 = words[i];
direction = new DirectionNode(word1);
string word2 = words[i];
action = new ActionNode(word2);
string word3 = words[i];
distance = new DistanceNode(word3);
left = new SentenceNode(direction, action, distance);
stack.Push(left);
}
}
this.node = (AbstractNode)stack.Pop();
}
public string Output()
{
string result = node.Interpret();
return result;
}
}
}

//客户端测试类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterPretreSample
{
class InstructionHandler
{
private AbstractNode node;

public void Handle(string instruction)
{
AbstractNode left = null, right = null;
//Stack stack = new Stack();
AbstractNode direction = null, action = null, distance = null;
Stack<AbstractNode> stack = new Stack<AbstractNode>();
string[] words = instruction.Split(' ');
for (int i = 0; i < words.Length; i++)
{
if (words[i].Equals("end"))
{
left = (AbstractNode)stack.Pop();
string word1 = words[i];
direction = new DirectionNode(word1);
string word2 = words[i];
action = new ActionNode(word2);
string word3 = words[i];
distance = new DistanceNode(word3);
right = new SentenceNode(direction, action, distance);
stack.Push(new AndNode(left, right));
}
else
{
string word1 = words[i];
direction = new DirectionNode(word1);
string word2 = words[i];
action = new ActionNode(word2);
string word3 = words[i];
distance = new DistanceNode(word3);
left = new SentenceNode(direction, action, distance);
stack.Push(left);
}
}
this.node = (AbstractNode)stack.Pop();
}
public string Output()
{
string result = node.Interpret();
return result;
}
}
}

  

运行截图:

醉了,结果和书上的不一样,代码好像没有什么不一样,希望路过的大侠指点一下。。

原文地址:https://www.cnblogs.com/Lightmen/p/4946316.html