解释器模式
发布者:admin 发表于:416天前 阅读数:663 评论:0

解释器模式定义一套语言文法,并设计该语言解释器,使用户能使用特定文法控制解释器行为。

解释器模式的意义在于,它分离多种复杂功能的实现,每个功能只需关注自身的解释。

对于调用者不用关心内部的解释器的工作,只需要用简单的方式组合命令就可以。

interpreter.go

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
}

interpreter_test.go

package interpreter

import "testing"

func TestInterpreter(t *testing.T) {
    p := &Parser{}
    p.Parse("1 + 2 + 3 - 4 + 5 - 6")
    res := p.Result().Interpret()
    expect := 1
    if res != expect {
        t.Fatalf("expect %d got %d", expect, res)
    }
}