【Go-设计模式】解释器模式 详解

概念;
解释器模式 定义一套 语言文法,并设计该 语言解释器,使用户能使用 特定文法 控制解释器行为
在 编译原理 中,一个 算术表达式 通过 词法分析器 形成 词法单元,
而后这些词法单元再通过 语法分析器 构建 语法分析树,最终形成一颗 抽象的语法分析树。
这里的 词法分析器 和 语法分析器 都可以看做是 解释器
解释器模式(Interpreter Pattern):是指给定一个 语言(表达式),定义它的 文法 的一种表示,
并定义一个 解释器, 使用该解释器来解释 语言中的句子(表达式)
解释器模式 的 意义 在于,它 分离多种复杂功能的实现,每个功能 只需 关注自身的解释
对于 调用者 不用关心 内部的解释器的工作,只需要用 简单的方式组合命令 就可以。

UML:

- Context:
环境角色,含有 解释器之外的全局信息 - AbstractExpression:
抽象表达式, 声明一个 抽象的解释操作,这个方法为 抽象语法树 中 所有的节点所共享 - TerminalExpression:
为 终结符表达式,实现与文法中的 终结符相关的解释操作 - NonTermialExpression:
为 非终结符表达式,为文法中的 非终结符实现解释操作
示例:
语法树节点 接口:
type Node interface {
Interpret() int64
}
具体的 语法树节点:
数值 语法树节点:
type ValNode struct {
val int64
}
func (this *ValNode) Interpret() int64 {
return this.val
}
加法 语法树节点:
type AddNode struct {
leftNode Node
rightNode Node
}
func (this *AddNode) Interpret() int64 {
return this.leftNode.Interpret() + this.rightNode.Interpret()
}
减法 语法树节点:
type SubNode struct {
leftNode Node
rightNode Node
}
func (this *SubNode) Interpret() int64 {
return this.leftNode.Interpret() - this.rightNode.Interpret()
}
语法分析器:
type GrammarParser struct {
expression []string
index int64
prevNode Node
}
func (this *GrammarParser) newValNode() Node {
value, _ := strconv.ParseInt(this.expression[this.index], 10, 64)
this.index++
return &ValNode{
val: value,
}
}
func (this *GrammarParser) newAddNode() Node {
this.index++
return &AddNode{
leftNode: this.prevNode,
rightNode: this.newValNode(),
}
}
func (this *GrammarParser) newSubNode() Node {
this.index++
return &SubNode{
leftNode: this.prevNode,
rightNode: this.newValNode(),
}
}
func (this *GrammarParser) Parse(exp string) {
this.expression = strings.Split(exp, " ")
for {
if this.index >= int64(len(this.expression)) {
return
}
switch this.expression[this.index] {
case "加":
this.prevNode = this.newAddNode()
case "减":
this.prevNode = this.newSubNode()
default:
this.prevNode = this.newValNode()
}
}
}
func (this *GrammarParser) Result() Node {
return this.prevNode
}
func NewGrammarParser() *GrammarParser {
return &GrammarParser{
expression: []string{},
index: 0,
prevNode: nil,
}
}
测试:
package main
import (
"fmt"
"DemoProject/design/base23/interpreter" // 根据自己的项目路径定制
)
func main() {
// interpreter
grammarParser := interpreter.NewGrammarParser()
exp := "666 加 777 减 7"
grammarParser.Parse(exp)
result := grammarParser.Result().Interpret()
fmt.Println("表达式【", exp, "】的结果为:", result)
}
注意事项:
应用场景:
- 可以将一个 需要解释执行的语言中的句子 表示为一个 抽象语法树
- 一些 重复出现的问题 可以用一种 简单的语言 来表达
- 一个 简单语法 需要 解释的场景
例如:编译器、运算表达式计算、正则表达式、机器人...
缺点:
解释器模式 会引起 类膨胀、
解释器模式 采用 递归调用方法,将会导致 调试非常复杂、效率可能降低

浙公网安备 33010602011771号