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; } } }
运行截图:
醉了,结果和书上的不一样,代码好像没有什么不一样,希望路过的大侠指点一下。。