1. 概述
解释器模式(Interpreter)是用于表达语言语法树和封装语句解释(或运算)行为的对象。
1.1 角色
- AbstractExpression(抽象表达式):具体表达式的一个抽象接口,交由具体子类进行具体解释
- TerminalExpression(终结符表达式):实现文法中与终结符有关的解释操作
- NonTerminalExpression(非终结符表达式):实现文法中与非终结符有关的解释操作
- Context(上下文环境类):解释器上下文环境类
- Client :持有上下文和抽象表达式,
1.2 类图
1.3 优缺点
- 优点
- 可拓展性高,灵活
- 易于实现简单的文法
- 缺点
- 可使用场景少
- 对于复杂的文法较难维护
- 会引起类膨胀
2. 代码示例
2.1 设计
- 定义一个上下文,用来对字串做表达前的处理。
- 本例中只需要将字串切割成字符列表备用。
- 定义一个抽象表达式
- 它由加、减两、数值三个具体表达式分别实现
- 只是一个表达式,被客户端组装之后才能显示它的实际作用。
- 它由加、减两、数值三个具体表达式分别实现
- 定义一个客户端
- 持有上下文,意味着他可以实例化一个上下文来对COS的字串做表达前的处理。
- 持有表达式,意味着它可以实例化并组装一个表达式
2.2 代码
- 代码
package main
import (
"fmt"
"strconv"
"strings"
)
// 定义一个抽象表达式
type Node interface {
Interpreter() int
}
// 定义终结表达式
type ValNode struct {
val int
}
func (v *ValNode) Interpreter() int {
return v.val
}
// 定义非终结表达式——加法
type AddNode struct {
left Node
right Node
}
func (a *AddNode) Interpreter() int {
return a.left.Interpreter() + a.right.Interpreter()
}
// 定义非终结表达式——减法
type SubNode struct {
left Node
right Node
}
func (s *SubNode) Interpreter() int {
return s.left.Interpreter() - s.right.Interpreter()
}
// 定义上下文
type Context struct {
exp []string
index int
}
// 它的方法负解释前的所有处理
func (c *Context) GetList(exp string) {
c.exp = strings.Split(exp, " ")
}
// 定义客户端,它持有上下文和解释器
type Client struct {
context Context
prev Node
}
// 构造表达式
func (p *Client) CreateNode(expString string) Node {
p.context = Context{}
p.context.GetList(expString)
for {
if p.context.index >= len(p.context.exp) {
return p.prev
}
switch p.context.exp[p.context.index] {
case "+":
p.prev = p.CreateAddNode()
case "-":
p.prev = p.CreateSubNode()
default:
p.prev = p.CreateValNode()
}
}
}
// 三个方法用来创建node并参与表达式的拼装
func (p *Client) CreateAddNode() Node {
p.context.index++
return &AddNode{left: p.prev, right: p.CreateValNode()}
}
func (p *Client) CreateSubNode() Node {
p.context.index++
return &SubNode{left: p.prev, right: p.CreateValNode()}
}
func (p *Client) CreateValNode() Node {
v, _ := strconv.Atoi(p.context.exp[p.context.index])
p.context.index++
return &ValNode{v}
}
func main() {
//实例化一个客户端
p := &Client{}
//拼装表达式
node := p.CreateNode("1 + 5 - 3")
//调用表达式得到结果
result := node.Interpreter()
//验证结果(实际应用中应该由客户端验证,我们这里打印出来口算验证一下好了。)
fmt.Println(result)
}
- 输出
3