设计模式-解释器模式

  解释器(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语言中对bool表达式进行操作和求值。

  在这个语言中终结符是bool变量,也就是常量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'

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

 

源代码 

package Interpreter

/**
 * 抽像表达式角色
 * */
abstract class Expression {
    /**
     * 以环境为准,本方法解释给定的任何一个表达式
     * */
    abstract fun interpret(context: Context): Boolean

    /**
     * 检验两个表达式在结构上是否相同
     * */
    abstract fun equal(other: Any?): Boolean

    /**
     * 返回表达式的hash code
     * */
    abstract fun hash_code(): Int

    /**
     * 将表达式转换成字符串
     * */
    abstract fun to_string(): String
}
package Interpreter

/**
 * 一个Constant对象代表一个布尔常量
 * */
class Constant constructor(value: Boolean) : Expression() {

    var value = false

    init {
        this.value = value
    }

    override fun interpret(context: Context): Boolean {
        return value
    }

    override fun equal(other: Any?): Boolean {
        if (other != null && other is Constant) {
            return this.value == other.value
        }
        return false
    }

    override fun hash_code(): Int {
        return to_string().hashCode()
    }

    override fun to_string(): String {
        return value.toString()
    }
}
package Interpreter

/**
 * 一个Variable对象代表一个有名变量
 * */
class Variable constructor(name: String) : Expression() {

    var name = ""

    init {
        this.name = name
    }

    override fun interpret(context: Context): Boolean {
        return context.lookup(this)
    }

    override fun equal(other: Any?): Boolean {
        if (other != null && other is Variable) {
            return this.name == other.name
        }
        return false
    }

    override fun hash_code(): Int {
        return to_string().hashCode()
    }

    override fun to_string(): String {
        return name
    }

}
package Interpreter

/**
 * 代表逻辑"与"操作的And类,表示由两个bool表达式通过逻辑"与"操作给出一个新的bool表达式的操作
 * */
class And constructor(left: Expression, right: Expression) : Expression() {

    private var left: Expression? = null
    private var right: Expression? = null

    init {
        this.left = left
        this.right = right
    }

    override fun interpret(context: Context): Boolean {
        return left!!.interpret(context) && right!!.interpret(context)
    }

    override fun equal(other: Any?): Boolean {
        if (other != null && other is And) {
            return left!!.equal(other.left) && right!!.equal(other.right)
        }
        return false
    }

    override fun hash_code(): Int {
        return to_string().hashCode()
    }

    override fun to_string(): String {
        return "(${left!!.to_string()} AND ${right!!.to_string()})"
    }
}
package Interpreter

/**
 * 代表逻辑"或"操作的Or类,代表由两个bool表达式通过逻辑"或"操作给出一个新的bool表达式的操作
 * */
class Or constructor(left: Expression, right: Expression) : Expression() {

    private var left: Expression? = null
    private var right: Expression? = null

    init {
        this.left = left
        this.right = right
    }

    override fun interpret(context: Context): Boolean {
        return left!!.interpret(context) || right!!.interpret(context)
    }

    override fun equal(other: Any?): Boolean {
        if (other != null && other is Or) {
            return left!!.equal(other.left) && right!!.equal(other.right)
        }
        return false
    }

    override fun hash_code(): Int {
        return to_string().hashCode()
    }

    override fun to_string(): String {
        return "(${left!!.to_string()} OR ${right!!.to_string()})"
    }
}
package Interpreter

/**
 * 代表逻辑"非"操作的Not类,代表一个由bool值表达式通过逻辑"非"操作给出一个新的bool表达式的操作
 * */
class Not constructor(expression: Expression) : Expression() {

    private var exp: Expression? = null

    init {
        this.exp = expression
    }

    override fun interpret(context: Context): Boolean {
        return !exp!!.interpret(context)
    }

    override fun equal(other: Any?): Boolean {
        if (other != null && other is Not) {
            return exp!!.equal(other.exp)
        }
        return false
    }

    override fun hash_code(): Int {
        return to_string().hashCode()
    }

    override fun to_string(): String {
        return "(Not ${exp!!.to_string()})"
    }
}
package Interpreter


/**
 * 环境类,定义出从变量到布尔值的一个影射
 * */
class Context {

    private val map = HashMap<Variable, Boolean>()

    fun assign(variable: Variable, value: Boolean) {
        map.put(variable, value)
    }

    @Throws(IllegalArgumentException::class)
    fun lookup(variable: Variable): Boolean {
        return map[variable] ?: throw IllegalArgumentException()
    }
}

代码测试 

val context = Context()
val x = Variable("x")
val y = Variable("y")
val true_ = Constant(true)
context.assign(x, false)
context.assign(y, true)
val expression = Or(And(true_,x), And(y,Not(x)))
println("x:${x.interpret(context)}")
println("y:${y.interpret(context)}")
println("${expression.to_string()} = ${expression.interpret(context)}")

 结果

x:false
y:true
((true AND x) OR (y AND (Not x))) = true

 

posted @ 2021-01-27 12:18  johnny_zhao  阅读(118)  评论(0编辑  收藏  举报