解釋器(Interpreter)模式是類的行為模式。給定一個語言之後,解釋器模式可以定義出其文法的一種表示,并同時提供一個解釋器。用戶端可以使用這個解釋器來解釋這個語言中的句子。(學習)
解釋器模式的結構
下面就以一個示意性的系統為例,讨論解釋器模式的結構。系統的結構圖如下:
模式所涉及的角色如下所示:
- 抽象表達式(Expression)角色:聲明一個所有的具體表達式角色都需要實作的抽象接口。這個接口主要是一個interpret()方法,稱做解釋操作。
- 終結符表達式(Terminal Expression)角色:實作了抽象表達式角色所要求的接口,主要是一個interpret()方法;文法中的每一個終結符都有一個具體終結表達式與之相對應。比如有一個簡單的公式R=R1+R2,在裡面R1和R2就是終結符,對應的解析R1和R2的解釋器就是終結符表達式。
- 非終結符表達式(Nonterminal Expression)角色:文法中的每一條規則都需要一個具體的非終結符表達式,非終結符表達式一般是文法中的運算符或者其它關鍵字,比如公式R=R1+R2中,“+”就是非終結符,解析“+”的解釋器就是一個非終結符表達式。
- 環境(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