Go用Interpreter模式实现表达式解释器:先Lexer将字符串转为Token流,再Parser按优先级递归下降构建AST,最后通过Expr接口的Eval方法递归求值,支持扩展运算符且无需修改现有逻辑。

用 Go 实现解释器模式解析表达式,核心是把字符串形式的算术表达式(如 "3 + 5 * 2")拆解成树结构,再递归求值。不依赖第三方 parser,纯手工构建词法分析(Lexer)+ 语法分析(Parser),符合 Interpreter Pattern 的经典四要素:抽象表达式、终结符、非终结符、上下文。
先定义基础 Token 类型:
type TokenType string
const (
TOKEN_NUMBER TokenType = "NUMBER"
TOKEN_PLUS = "PLUS"
TOKEN_STAR = "STAR"
TOKEN_LPAREN = "LPAREN"
TOKEN_RPAREN = "RPAREN"
)
type Token struct { Type TokenType; Value string }
Lexer 遍历字符串,跳过空格,识别数字(支持多位)、运算符和括号。关键点:
立即学习“go语言免费学习笔记(深入)”;
- 是减号还是负号——简单场景可暂不支持负数,或结合 Parser 处理[]Token,末尾加一个 TOKEN_EOF 方便 Parser 终止按优先级自顶向下递归下降(Recursive Descent)。推荐实现三个层级函数:
+ 和 -(最低优先级),调用 ParseTerm* 和 /(中等优先级),调用 ParseFactor( 就递归调用 ParseExpression每个函数返回一个实现了 Expr 接口的 AST 节点。例如:
type Expr interface { Eval() int }
type NumberExpr struct { Value int }
func (n NumberExpr) Eval() int { return n.Value }
type BinaryExpr struct { Left, Right Expr; Op string }
func (b BinaryExpr) Eval() int {
switch b.Op {
case "+": return b.Left.Eval() + b.Right.Eval()
case "*": return b.Left.Eval() * b.Right.Eval()
default: panic("unknown op")
}
}
AST 构建完成后,只需对根节点调用 .Eval()。所有运算逻辑封装在各 Expr 实现里,完全符合 Interpreter Pattern 的“让语言的语法结构由多个类分别表示,每个类负责解释对应部分”的思想。
-、/)只需新增 Expr 实现,不修改现有逻辑Eval() 方法中传入 map[string]int 环境参数入口函数示例:
func Evaluate(input string) int {
tokens := Lexer(input)
parser := &Parser{Tokens: tokens, Pos: 0}
expr := parser.ParseExpression()
return expr.Eval()
}
注意 Parser 中维护当前 token 下标 Pos,每次 consume 后递增;遇到错误(如括号不匹配、意外 token)应 panic 或返回 error。
基本上就这些。Go 的接口和结构体组合让 Interpreter Pattern 写起来干净利落,没有冗余抽象,也不用反射或代码生成。重点是把 Token 流稳稳转成树,剩下的就是自然的递归计算。
以上就是如何使用Golang实现解释器语法解析_使用Interpreter Pattern分析表达式的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号