add code for interpreter patten

This commit is contained in:
Edward 2020-05-05 00:01:23 +08:00
parent 3ce5fda804
commit ca8d427d89
3 changed files with 134 additions and 55 deletions

View File

@ -1,9 +1,19 @@
# 解释器模式 # 解释器模式
解释器模式就是自己定一套规则,自己解析执行,常见的自定义协议,私有协议,就是一个中解释器模式的概念,使用者按照协议的规则做事。 解释器模式就是自己定一套规则、语言、表达方式,也就是所谓的DSL(Domain Specific Language)然后按照定义解析执行DSL,常见的自定义协议,私有协议,就是一个中解释器模式的概念,使用者按照协议的规则做事。
解释器模式的意义在于,它分离多种复杂功能的实现,每个功能只需关注自身的解释。 解释器模式的意义在于,它分离多种复杂功能的实现,每个功能只需关注自身的解释。
对于调用者不用关心内部的解释器的工作,只需要用简单的方式组合命令。 对于调用者不用关心内部的解释器的工作,只需要用简单的方式组合命令。
常见的redis协议就是一个很好解释器模式实现通过redis-cli可以发送各种指令给到redis-server执行后返回结果。 常见的redis协议就是一个很好解释器模式实现通过redis-cli可以发送各种指令给到redis-server服务端解释执行后返回结果。
我们常说的计算器,是一个很典型的解释器模式,它用来解释执行加减乘除的运行规则,现实生活中,哑语翻译、音乐乐谱、摩尔斯电码,道路交通指示系统,等都是解释器模式的好例子。
我们来设计一个简单交流标识系统,来表达会议中两个人交流时候的谈话方式,以代替冗长的语言表述.
A "->" B 表示 A说B听,此时B不能发言。
A "<-" B 表示 B说A听,此时B不能发言
A "<->" B 表示 A 和 B 可以自由发言。
A "-" B 表示 A 和 B 都不能发言,只能倾听。

View File

@ -5,82 +5,65 @@ import (
"strings" "strings"
) )
type Node interface { //用会议交流的例子
Interpret() int // A表示左边发言者B表示右边发言者
// A "->" B 表示 A说B听,此时B不能发言。
// A "<-" B 表示 B说A听,此时B不能发言。
// A "<->" B 表示 A 和 B 可以自由发言。
// A "-" B 表示 A 和 B 都不能发言,只能倾听。
type IActionInterpret interface {
Interpret()
} }
type ValNode struct { //Speaker 发言者
val int type Speaker struct {
Name string
Age int
} }
func (n *ValNode) Interpret() int { func (s *Speaker) Interpret() {
return n.val
} }
type AddNode struct { //LeftIntroduce A向B介绍自己
left, right Node type LeftIntroduce struct {
leftSpeaker, rightSpeaker Speaker
} }
func (n *AddNode) Interpret() int {
return n.left.Interpret() + n.right.Interpret() func (l *LeftIntroduce) Interpret() {
} }
type MinNode struct { //RightIntroduce B向A介绍自己
left, right Node type RightIntroduce struct {
leftSpeaker, rightSpeaker Speaker
} }
func (n *MinNode) Interpret() int { func (n *MinNode) Interpret() int {
return n.left.Interpret() - n.right.Interpret() return n.left.Interpret() - n.right.Interpret()
} }
type Parser struct { //标识解析器
exp []string type SignParser struct {
index int actionsMark []string
prev Node
} }
func (p *Parser) Parse(exp string) { //Parse 标识解析器进行解析
func (p *SignParser) Parse(exp string) {
p.exp = strings.Split(exp, " ") p.exp = strings.Split(exp, " ")
for { s := p.actionsMark[0]
if p.index >= len(p.exp) { for len(s) >0 {
return switch s.actionsMark[0] {
}
switch p.exp[p.index] {
case "+":
p.prev = p.newAddNode()
case "-":
p.prev = p.newMinNode()
default:
p.prev = p.newValNode()
} }
} }
} }
func (p *Parser) newAddNode() Node {
p.index++
return &AddNode{
left: p.prev,
right: p.newValNode(),
}
}
func (p *Parser) newMinNode() Node {
p.index++
return &MinNode{
left: p.prev,
right: p.newValNode(),
}
}
func (p *Parser) newValNode() Node {
v, _ := strconv.Atoi(p.exp[p.index])
p.index++
return &ValNode{
val: v,
}
}
func (p *Parser) Result() Node {
return p.prev
}

View File

@ -0,0 +1,86 @@
package interpreter
import (
"strconv"
"strings"
)
type Node interface {
Interpret() int
}
type ValNode struct {
val int
}
func (n *ValNode) Interpret() int {
return n.val
}
type AddNode struct {
left, right Node
}
func (n *AddNode) Interpret() int {
return n.left.Interpret() + n.right.Interpret()
}
type MinNode struct {
left, right Node
}
func (n *MinNode) Interpret() int {
return n.left.Interpret() - n.right.Interpret()
}
type Parser struct {
exp []string
index int
prev Node
}
func (p *Parser) Parse(exp string) {
p.exp = strings.Split(exp, " ")
for {
if p.index >= len(p.exp) {
return
}
switch p.exp[p.index] {
case "+":
p.prev = p.newAddNode()
case "-":
p.prev = p.newMinNode()
default:
p.prev = p.newValNode()
}
}
}
func (p *Parser) newAddNode() Node {
p.index++
return &AddNode{
left: p.prev,
right: p.newValNode(),
}
}
func (p *Parser) newMinNode() Node {
p.index++
return &MinNode{
left: p.prev,
right: p.newValNode(),
}
}
func (p *Parser) newValNode() Node {
v, _ := strconv.Atoi(p.exp[p.index])
p.index++
return &ValNode{
val: v,
}
}
func (p *Parser) Result() Node {
return p.prev
}