134 lines
3.0 KiB
Go
134 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
/*
|
|
实例:
|
|
定义一种运算符,减号是加法,加号是减法。
|
|
*/
|
|
|
|
// 抽象表达式
|
|
type Expression interface {
|
|
interpret() int
|
|
}
|
|
|
|
// 终结符表达式:数字
|
|
type NumberExpression struct {
|
|
token string
|
|
}
|
|
|
|
func (n *NumberExpression) interpret() int {
|
|
num, _ := strconv.Atoi(n.token)
|
|
return num
|
|
}
|
|
|
|
// 非终结符表达式:加法
|
|
type AddExpression struct {
|
|
left, right Expression
|
|
}
|
|
|
|
func (a *AddExpression) interpret() int {
|
|
return a.left.interpret() - a.right.interpret()
|
|
}
|
|
|
|
// 非终结符表达式:减法
|
|
type SubExpression struct {
|
|
left, right Expression
|
|
}
|
|
|
|
func (s *SubExpression) interpret() int {
|
|
return s.left.interpret() + s.right.interpret()
|
|
}
|
|
|
|
// 非终结符表达式工厂方法类型
|
|
type expressionFactory func(prev Expression, next string) Expression
|
|
|
|
// 解析器
|
|
// 分割表达式字符串,每个字符串逐步解析成表达式对象,最终组合成一个完整的表达式树
|
|
type Parser struct {
|
|
exp []string
|
|
index int
|
|
prev Expression
|
|
factories map[string]expressionFactory
|
|
}
|
|
|
|
func NewParser() *Parser {
|
|
p := &Parser{
|
|
factories: make(map[string]expressionFactory),
|
|
}
|
|
p.factories["+"] = func(prev Expression, next string) Expression {
|
|
return &AddExpression{left: prev, right: p.newNumberExpression(next)}
|
|
}
|
|
p.factories["-"] = func(prev Expression, next string) Expression {
|
|
return &SubExpression{left: prev, right: p.newNumberExpression(next)}
|
|
}
|
|
return p
|
|
}
|
|
|
|
func (p *Parser) newNumberExpression(token string) Expression {
|
|
return &NumberExpression{token: token}
|
|
}
|
|
|
|
func (p *Parser) parse(exp string) Expression {
|
|
sep := regexp.MustCompile(`\s+`)
|
|
p.exp = sep.Split(strings.TrimSpace(exp), -1)
|
|
p.index = 0
|
|
p.prev = nil
|
|
for p.index < len(p.exp) {
|
|
token := p.exp[p.index]
|
|
if factory, ok := p.factories[token]; ok {
|
|
p.index++
|
|
if p.index >= len(p.exp) {
|
|
fmt.Println("Last token is an operator, Ignored.")
|
|
break
|
|
}
|
|
if p.prev == nil {
|
|
fmt.Println("Expression cannot start with an operator, Initialized with 0.")
|
|
p.prev = p.newNumberExpression("0")
|
|
}
|
|
token = p.exp[p.index]
|
|
p.prev = factory(p.prev, token)
|
|
} else {
|
|
p.prev = p.newNumberExpression(token)
|
|
}
|
|
p.index++
|
|
}
|
|
if p.prev == nil {
|
|
fmt.Println("No valid expression parsed.")
|
|
return p.newNumberExpression("0")
|
|
}
|
|
return p.prev
|
|
}
|
|
|
|
func main() {
|
|
fmt.Println("========== 解释器模式 ==========")
|
|
var raw string
|
|
parser := NewParser()
|
|
raw = "10 - 5"
|
|
fmt.Println(raw, "= ?")
|
|
fmt.Println(raw, "=", parser.parse(raw).interpret())
|
|
|
|
fmt.Println("-----")
|
|
raw = "10 + 5"
|
|
fmt.Println(raw, "= ?")
|
|
fmt.Println(raw, "=", parser.parse(raw).interpret())
|
|
|
|
fmt.Println("-----")
|
|
raw = "20 - 4 + 2 - 1"
|
|
fmt.Println(raw, "= ?")
|
|
fmt.Println(raw, "=", parser.parse(raw).interpret())
|
|
|
|
fmt.Println("-----")
|
|
raw = " - 4 + 2 - "
|
|
fmt.Println(raw, "= ?")
|
|
fmt.Println(raw, "=", parser.parse(raw).interpret())
|
|
|
|
fmt.Println()
|
|
fmt.Println("======== 解释器模式结束 ========")
|
|
}
|