Golang设计模式——18解释器模式

本文详细介绍了解释器模式,一种设计模式,用于创建能解释特定语言的程序。通过实例展示了如何使用解释器模式来解析加法表达式,包括创建表达式接口、整数类、加法类等。文章还提到了解释器模式的优点,如易于扩展,以及缺点,如可能导致深递归。此外,给出了一个简单的测试用例来验证解释器的正确性。解释器模式适用于需要频繁解析特定语言的问题场景。

解释器模式

定义

给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

优点

  1. 扩展性强,若要新增乘,除,添加相应的非终结表达式,修改计算逻辑即可。

缺点

  1. 需要建大量的类,因为每一种语法都要建一个非终结符的类。
  2. 解释的时候采用递归调用方法,导致有时候函数的深度会很深,影响效率。

场景

如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

代码

在这里插入图片描述

package Interpreter

import "strings"

type Expression interface {
	Interpret(variables map[string]Expression) int
}
type Integer struct {
	integer int
}

func (n *Integer) Interpret(variables map[string]Expression) int {
	return n.integer
}

type Plus struct {
	leftOperand  Expression
	rightOperand Expression
}

func (p *Plus) Interpret(variables map[string]Expression) int {
	return p.leftOperand.Interpret(variables) + p.rightOperand.Interpret(variables)
}

func (e *Evaluator) Interpret(context map[string]Expression) int {
	return e.syntaxTree.Interpret(context)
}

type Variable struct {
	name string
}
type Node struct {
	value interface{}
	next  *Node
}
type Stack struct {
	top  *Node
	size int
}

func (s *Stack) Push(value interface{}) {
	s.top = &Node{
		value: value,
		next:  s.top,
	}
	s.size++
}
func (s *Stack) Pop() interface{} {
	if s.size == 0 {
		return nil
	}
	value := s.top.value
	s.top = s.top.next
	s.size--
	return value
}
func (v *Variable) Interpret(variables map[string]Expression) int {
	value, found := variables[v.name]
	if !found {
		return 0
	}
	return value.Interpret(variables)
}

type Evaluator struct {
	syntaxTree Expression
}

func NewEvaluator(expression string) *Evaluator {
	expressionStack := new(Stack)
	for _, token := range strings.Split(expression, " ") {
		switch token {
		case "+":
			right := expressionStack.Pop().(Expression)
			left := expressionStack.Pop().(Expression)
			subExpression := &Plus{left, right}
			expressionStack.Push(subExpression)
		default:
			expressionStack.Push(&Variable{token})
		}
	}
	syntaxTree := expressionStack.Pop().(Expression)
	return &Evaluator{syntaxTree: syntaxTree}
}

package Interpreter

import "testing"
import "github.com/stretchr/testify/assert"

func TestInterpret(t *testing.T) {
	expression := "w x z +"
	sentence := NewEvaluator(expression)
	variable := make(map[string]Expression)
	variable["w"] = &Integer{6}
	variable["x"] = &Integer{10}
	variable["z"] = &Integer{41}
	result := sentence.Interpret(variable)
	assert.Equal(t, 51, result)

}

其他设计模式

设计模式Git源代码
00简单工厂模式
01工厂方法模式
02抽象工厂模式
03外观模式
04建造者模式
05桥接模式
06命令模式
07迭代器模式
08模板模式
09访问者模式
10备忘录模式
11责任链模式
12中介模式
13原型模式
14状态模式
15策略模式
16享元模式
17组合模式
18解释器模式
19单例模式
20适配器模式
21代理模式
22装饰器模式
23观察者模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cheems~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值