解释器模式通过构建抽象语法树(AST)解析小型语言或规则,如条件表达式;其核心组件包括表达式接口、终结符与非终结符表达式、上下文及解析器;示例中实现了变量、常量、比较和逻辑操作的表达式,并通过Parse函数将字符串转为AST,结合上下文执行求值,适用于简单语法场景,复杂语法建议结合go/parser等工具。
在go语言中实现解释器模式来解析特定语法,适合处理小型语言或规则引擎场景,比如条件表达式、配置规则、DSL(领域特定语言)等。解释器模式的核心是构建抽象语法树(AST),每个节点对应一个解释操作。
解释器模式基本结构
解释器模式包含以下几个关键部分:
- 抽象表达式(Expression):定义解释方法 interpret() 接口
- 终结符表达式(TerminalExpression):如变量、常量,最基础的语法单元
- 非终结符表达式(Non-terminalExpression):如逻辑与、或、比较等,组合其他表达式
- 上下文(Context):存储变量值或运行时信息
- 解析器:将字符串转换为AST
示例:实现简单的条件表达式解析
假设我们要解析类似 age > 18 and city == “beijing” 的表达式。
1. 定义表达式接口
立即学习“go语言免费学习笔记(深入)”;
type Expression Interface {
Interpret(ctx map[String]interface{}) bool
}
2. 终结符表达式:变量和常量
type VariableExpression Struct {
Name string
}
func (v *VariableExpression) Interpret(ctx map[string]interface{}) bool {
if val, ok := ctx[v.Name]; ok {
return val != nil
}
return false
}
type ValueExpression struct {
Value interface{}
}
func (v *ValueExpression) Interpret(ctx map[string]interface{}) bool {
return v.Value != nil
}
3. 比较表达式(如 ==, >)
type CompareExpression struct {
Left *VariableExpression
Right *ValueExpression
operator string // “eq”, “gt”, etc.
}
func (c *CompareExpression) Interpret(ctx map[string]interface{}) bool {
leftVal, ok := ctx[c.Left.Name]
if !ok {
return false
}
switch c.Operator {
case “eq”:
return leftVal == c.Right.Value
case “gt”:
return leftVal.(int) > c.Right.Value.(int)
default:
return false
}
}
4. 逻辑表达式(and, or)
type LogicalExpression struct {
Left Expression
Right Expression
Operator string // “and”, “or”
}
func (l *LogicalExpression) Interpret(ctx map[string]interface{}) bool {
switch l.Operator {
case “and”:
return l.Left.Interpret(ctx) && l.Right.Interpret(ctx)
case “or”:
return l.Left.Interpret(ctx) || l.Right.Interpret(ctx)
default:
return false
}
}
5. 简易解析器实现(词法 + 语法分析)
这里用字符串分割简化处理,实际可用 go/scanner 或 parser 包做更复杂解析。
func Parse(expression string) Expression {
parts := strings.Split(expression, ” “)
if len(parts) == 3 {
return &CompareExpression{
Left: &VariableExpression{Name: parts[0]},
Right: &ValueExpression{Value: parseValue(parts[2])},
Operator: mapOp(parts[1]),
}
} else if len(parts) == 5 && parts[2] == “and” {
left := strings.Join(parts[0:3], ” “)
right := strings.Join(parts[3:5], ” “)
return &LogicalExpression{
Left: Parse(left),
Right: Parse(right[3:]), // 去掉 “and “
Operator: “and”,
}
}
return nil
}
使用示例
ctx := map[string]interface{}{“age”: 20, “city”: “beijing”}
expr := Parse(“age > 18”)
result := expr.Interpret(ctx) // true
解释器模式适合语法简单、扩展性强的场景。对于复杂语法,建议结合 go/parser 或使用 YACC/Bison 生成解析器。
基本上就这些,核心是把语法拆成可组合的表达式对象,通过树结构解释执行。