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("======== 解释器模式结束 ========") }