模式定义
给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子
类图
要点总结
- Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”才适合使用Interpreter模式
- 使用interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法
- Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具
Go语言代码实现
工程目录
Interpretor.go
package Interpreter
import "strings"
type Expression interface {
Interpret(variables map[string]Expression)int
}
type Interger struct {
integer int
}
func (n *Interger) Interpret(variables map[string]Expression) int {
return n.integer
}
type Plus struct {
leftOperand Expression
rightOperand Expression
}
func (p *Plus) Interpret(variables map[string]Expression) int {
return p.leftOperand.Interpret(variables) + p.rightOperand.Interpret(variables)
}
func (e Evaluator) Interpret(variable map[string]Expression)int{
return e.syntaxTree.Interpret(variable)
}
type Variable struct {
name string
}
type Node struct {
value interface{}
next *Node
}
type Stack struct {
top *Node
size int
}
func (s *Stack) Push (value interface{}){
s.top= &Node{
value: value,
next: s.top,
}
}
func (v *Variable) Interpret(variable map[string]Expression)int {
value, found := variable[v.name]
if !found {
return 0
}
return value.Interpret(variable)
}
func (s *Stack) Pop() interface{} {
if s.size == 0{
return nil
}
value := s.top.value
s.top = s.top.next
s.size--
return value
}
type Evaluator struct {
syntaxTree Expression
}
func NewEvaluator(expression string) *Evaluator{
expressionStack := new(Stack)
for _, token := range strings.Split(expression, " ") {
switch token {
case "+":
right := expressionStack.Pop().(Expression)
left := expressionStack.Pop().(Expression)
subExpression := &Plus{left, right}
expressionStack.Push(subExpression)
default:
expressionStack.Push(&Variable{token})
}
}
syntaxTree := expressionStack.Pop().(Expression)
return &Evaluator{syntaxTree: syntaxTree}
}
Interpretor_test.go
package Interpreter
import (
"fmt"
"testing"
)
func TestInterger(t *testing.T) {
expression := "w x z +"
sentence := NewEvaluator(expression)
variables := make(map[string]Expression)
variables["w"] = &Interger{6}
variables["x"] = &Interger{10}
variables["z"] = &Interger{41}
result := sentence.Interpret(variables)
fmt.Println(result)
}