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

2.3 类图

11-03 02:39