天天看點

設計模式-解釋器模式

  解釋器(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      

繼續閱讀