首页 > 后端开发 > Golang > 正文

如何使用Golang实现解释器语法解析_使用Interpreter Pattern分析表达式

P粉602998670
发布: 2025-12-20 17:43:02
原创
139人浏览过
Go用Interpreter模式实现表达式解释器:先Lexer将字符串转为Token流,再Parser按优先级递归下降构建AST,最后通过Expr接口的Eval方法递归求值,支持扩展运算符且无需修改现有逻辑。

如何使用golang实现解释器语法解析_使用interpreter pattern分析表达式

用 Go 实现解释器模式解析表达式,核心是把字符串形式的算术表达式(如 "3 + 5 * 2")拆解成树结构,再递归求值。不依赖第三方 parser,纯手工构建词法分析(Lexer)+ 语法分析(Parser),符合 Interpreter Pattern 的经典四要素:抽象表达式、终结符、非终结符、上下文。

词法分析:把输入切分成 Token

先定义基础 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 终止

语法分析:构造抽象语法树(AST)

按优先级自顶向下递归下降(Recursive Descent)。推荐实现三个层级函数:

  • ParseExpression():处理 +-(最低优先级),调用 ParseTerm
  • ParseTerm():处理 */(中等优先级),调用 ParseFactor
  • ParseFactor():处理数字、括号(最高优先级),遇到 ( 就递归调用 ParseExpression

每个函数返回一个实现了 Expr 接口的 AST 节点。例如:

Supermeme
Supermeme

Supermeme是一个AI驱动的Meme生成器,可以快速生成有趣的Meme梗图

Supermeme 114
查看详情 Supermeme

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")
  }
}

解释执行:调用 Eval() 递归求值

AST 构建完成后,只需对根节点调用 .Eval()。所有运算逻辑封装在各 Expr 实现里,完全符合 Interpreter Pattern 的“让语言的语法结构由多个类分别表示,每个类负责解释对应部分”的思想。

  • 无需 switch 判断节点类型,靠接口多态自动分发
  • 扩展新运算符(如 -/)只需新增 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中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号