在阎宏博士的《JAVA与模式》一书中开头是这样描述解释器(Interpreter)模式的:

  解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。

解释器模式的结构

  下面就以一个示意性的系统为例,讨论解释器模式的结构。系统的结构图如下所示:

  模式所涉及的角色如下所示:

  (1)抽象表达式(Expression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称做解释操作。

  (2)终结符表达式(Terminal Expression)角色:实现了抽象表达式角色所要求的接口,主要是一个interpret()方法;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。

  (3)非终结符表达式(Nonterminal Expression)角色:文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。

  (4)环境(Context)角色:这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。

  为了说明解释器模式的实现办法,这里给出一个最简单的文法和对应的解释器模式的实现,这就是模拟Java语言中对布尔表达式进行操作和求值。

  在这个语言中终结符是布尔变量,也就是常量true和false。非终结符表达式包含运算符and,or和not等布尔表达式。这个简单的文法如下:

    Expression  ::= Constant | Variable | Or | And | Not

    And     ::= Expression 'AND' Expression

    Or     ::= Expression 'OR' Expression

    Not     ::= 'NOT' Expression

    Variable  ::= 任何标识符

    Constant    ::= 'true' | 'false'

  解释器模式的结构图如下所示:

  

  源代码

  抽象表达式角色

public abstract class Expression {
/**
* 以环境为准,本方法解释给定的任何一个表达式
*/
public abstract boolean interpret(Context ctx);
/**
* 检验两个表达式在结构上是否相同
*/
public abstract boolean equals(Object obj);
/**
* 返回表达式的hash code
*/
public abstract int hashCode();
/**
* 将表达式转换成字符串
*/
public abstract String toString();
}

  一个Constant对象代表一个布尔常量

public class Constant extends Expression{

    private boolean value;

    public Constant(boolean value){
this.value = value;
} @Override
public boolean equals(Object obj) { if(obj != null && obj instanceof Constant){
return this.value == ((Constant)obj).value;
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) { return value;
} @Override
public String toString() {
return new Boolean(value).toString();
} }

  一个Variable对象代表一个有名变量

public class Variable extends Expression {

    private String name;

    public Variable(String name){
this.name = name;
}
@Override
public boolean equals(Object obj) { if(obj != null && obj instanceof Variable)
{
return this.name.equals(
((Variable)obj).name);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public String toString() {
return name;
} @Override
public boolean interpret(Context ctx) {
return ctx.lookup(this);
} }

  代表逻辑“与”操作的And类,表示由两个布尔表达式通过逻辑“与”操作给出一个新的布尔表达式的操作

public class And extends Expression {

    private Expression left,right;

    public And(Expression left , Expression right){
this.left = left;
this.right = right;
}
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof And)
{
return left.equals(((And)obj).left) &&
right.equals(((And)obj).right);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) { return left.interpret(ctx) && right.interpret(ctx);
} @Override
public String toString() {
return "(" + left.toString() + " AND " + right.toString() + ")";
} }

  代表逻辑“或”操作的Or类,代表由两个布尔表达式通过逻辑“或”操作给出一个新的布尔表达式的操作

public class Or extends Expression {
private Expression left,right; public Or(Expression left , Expression right){
this.left = left;
this.right = right;
}
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof Or)
{
return this.left.equals(((Or)obj).left) && this.right.equals(((Or)obj).right);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) {
return left.interpret(ctx) || right.interpret(ctx);
} @Override
public String toString() {
return "(" + left.toString() + " OR " + right.toString() + ")";
} }

  代表逻辑“非”操作的Not类,代表由一个布尔表达式通过逻辑“非”操作给出一个新的布尔表达式的操作

public class Not extends Expression {

    private Expression exp;

    public Not(Expression exp){
this.exp = exp;
}
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof Not)
{
return exp.equals(
((Not)obj).exp);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) {
return !exp.interpret(ctx);
} @Override
public String toString() {
return "(Not " + exp.toString() + ")";
} }

  环境(Context)类定义出从变量到布尔值的一个映射

public class Context {

    private Map<Variable,Boolean> map = new HashMap<Variable,Boolean>();

    public void assign(Variable var , boolean value){
map.put(var, new Boolean(value));
} public boolean lookup(Variable var) throws IllegalArgumentException{
Boolean value = map.get(var);
if(value == null){
throw new IllegalArgumentException();
}
return value.booleanValue();
}
}

  客户端类

public class Client {

    public static void main(String[] args) {
Context ctx = new Context();
Variable x = new Variable("x");
Variable y = new Variable("y");
Constant c = new Constant(true);
ctx.assign(x, false);
ctx.assign(y, true); Expression exp = new Or(new And(c,x) , new And(y,new Not(x)));
System.out.println("x=" + x.interpret(ctx));
System.out.println("y=" + y.interpret(ctx));
System.out.println(exp.toString() + "=" + exp.interpret(ctx));
} }

  运行结果如下:aaarticlea/png;base64,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" alt="" />

最新文章

  1. Symantec Backup Exec 2012 Agent For Linux安装
  2. 帆软报表FineReport SQLServer数据库连接失败常见解决方案
  3. ElasticSearch 命令行管理工具Curator
  4. CentOS7 win7 u盘装双系统 修复系统
  5. 使用virtualenvwrapper隔离python环境
  6. Winform ComboBox控件高亮显示
  7. (转)20 个大大节省你时间的 HTML5 开发工具
  8. 在Wamp 添加站点和域名
  9. HNOI2018 滚粗记
  10. JAVA基础复习与总结&lt;一&gt; 对象与类的概念_内部类_继承与多态
  11. python基础之Day22
  12. Python_day5
  13. C#反射遍历/查询类中的属性以及值
  14. SQLserver 字符串转换日期,日期转换成为字符串
  15. CentOS 7 NAT软路由
  16. 将实体类、匿名对象转换为SqlParameter列表
  17. 转:Linux网卡驱动程序编写
  18. NSDictionary的分类
  19. 了解ASP.NET Core框架的本质
  20. 定制二选一按钮SwitchButton

热门文章

  1. 832. Flipping an Image
  2. 2019.02.09 bzoj4710: [Jsoi2011]分特产(容斥原理)
  3. 2018.11.24 poj3693Maximum repetition substring(后缀数组)
  4. UVa 11762 Race to 1 (数学期望 + 记忆化搜索)
  5. 深入理解,函数声明、函数表达式、匿名函数、立即执行函数、window.onload的区别.
  6. WordPress-Word图片上传插件整合教程-Xproer.WordPaster
  7. reload maven project&#39; has encountered a proble&quot; 问题
  8. Visual C++实现局域网IP多播
  9. DOS下如何打开程序
  10. 移动端 - Android客户端性能测试常见指标