解释器模式(Interpreter design pattern),它用来描述如何构建一个简单的“语言”解释器。比起命令模式,解释器模式更加小众,只在一些特定的领域会被用到,比如编译器、规则引擎、正则表达式。
1. 解释器模式的原理
解释器模式为某个语言定义它的语法(或者叫文法)表示,并定义一个解释器用来处理这个语法。
Interpreter pattern is used to defines a grammatical representation for a language and provides an interpreter to deal with this grammar.
要想了解“语言”表达的信息,就必须定义相应的语法规则。这样,书写者就可以根据语法规则来书写“句子”(专业点的叫法应该是“表达式”),阅读者根据语法规则来阅读“句子”,这样才能做到信息的正确传递。解释器模式,其实就是用来实现根据语法规则解读“句子”的解释器。
它的代码实现的核心思想,就是将语法解析的工作拆分到各个小类中,以此来避免大而全的解析类。一般的做法是,将语法规则拆分一些小的独立的单元,然后对每个单元进行解析,最终合并为对整个语法规则的解析。
2. 解释器模式的实现
type Expression interface {
interpreter() int
}
type NumberExpression struct {
number int
}
func NewNumberExpression(num string) *NumberExpression {
number, _ := strconv.Atoi(num)
return &NumberExpression{number}
}
func (n *NumberExpression) interpreter() int {
return n.number
}
type AdditionExpression struct {
exp1, exp2 Expression
}
func NewAdditionExpression(exp1, exp2 Expression) *AdditionExpression {
return &AdditionExpression{exp1, exp2}
}
func (a *AdditionExpression) interpreter() int {
return a.exp1.interpreter() + a.exp2.interpreter()
}
type SubtractionExpression struct {
exp1, exp2 Expression
}
func NewSubtractionExpression(exp1, exp2 Expression) *SubtractionExpression {
return &SubtractionExpression{exp1, exp2}
}
func (s *SubtractionExpression) interpreter() int {
return s.exp1.interpreter() + s.exp2.interpreter()
}
type MultiplicationExpression struct {
exp1, exp2 Expression
}
func NewMultiplicationExpression(exp1, exp2 Expression) *MultiplicationExpression {
return &MultiplicationExpression{exp1, exp2}
}
func (m *MultiplicationExpression) interpreter() int {
return m.exp1.interpreter() + m.exp2.interpreter()
}
type DivisionExpression struct {
exp1, exp2 Expression
}
func NewDivisionExpression(exp1, exp2 Expression) *DivisionExpression {
return &DivisionExpression{exp1, exp2}
}
func (d *DivisionExpression) interpreter() int {
return d.exp1.interpreter() + d.exp2.interpreter()
}
/*
运算符只包含加、减、乘、除,并且没有优先级的概念;
表达式(也就是前面提到的“句子”)中,先书写数字,后书写运算符,空格隔开;
按照先后顺序,取出两个数字和一个运算符计算结果,结果重新放入数字的最头部位置,循环上述过程,直到只剩下一个数字,这个数字就是表达式最终的计算结果。
*/
type ExpressionInterpreter struct {
}
func (e *ExpressionInterpreter) interpreter(expression string) (int, error) {
elements := strings.Split(expression, " ")
var numExpression []Expression
for i := 0; i < (len(elements)+1)>>1; i++ {
numExpression = append(numExpression, NewNumberExpression(elements[i]))
}
var exp Expression
for i := (len(elements) + 1) >> 1; i < len(elements); i++ {
exp1, exp2 := numExpression[len(numExpression)-1], numExpression[len(numExpression)-2]
numExpression = numExpression[:len(numExpression)-2]
switch elements[i] {
case "+":
exp = NewAdditionExpression(exp1, exp2)
case "-":
exp = NewSubtractionExpression(exp1, exp2)
case "*":
exp = NewMultiplicationExpression(exp1, exp2)
case "/":
exp = NewDivisionExpression(exp1, exp2)
default:
return 0, errors.New("invalid operator")
}
numExpression = append(numExpression, exp)
}
return numExpression[0].interpreter(), nil
}
// 客户端使用
func TestInterpreter(t *testing.T) {
expression := "8 3 2 4 - + *"
expInterpreter := &ExpressionInterpreter{}
result, err := expInterpreter.interpreter(expression)
t.Error(err)
t.Log(result)
}