解释器模式(Interperter),给定一个语言,定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,实际开发中EL表达式或者正则表达式的解释器就是采用这种设计模式。其模式结构如下图。本文使用matlab语言,利用解释器模式来实现后缀表达式的解析。
Context.m (环境类,包含解释器之外的一些全局信息)
classdef Context < handle properties variables = containers.Map(); end methods function put(obj,var,expr) obj.variables(char(var)) = expr; end function expr = lookup(obj,var) if(obj.variables.isKey(char(var))) expr = obj.variables(char(var)); else expr = Expression.empty(); end end end end
Expression.m (抽象表达式)
classdef Expression < handle & matlab.mixin.Heterogeneous methods(Abstract) interpret(obj,ctx); end end
Plus.m (非终结表达式,加法类)
classdef Plus < Expression properties left; right; end methods function obj = Plus(left,right) obj.left = left; obj.right = right; end function res = interpret(obj,ctx) res = obj.left.interpret(ctx) + obj.right.interpret(ctx); end end end
Minus.m (非终结表达式,减法类)
classdef Minus < Expression properties left; right; end methods function obj = Minus(left,right) obj.left = left; obj.right = right; end function res = interpret(obj,ctx) res = obj.left.interpret(ctx) - obj.right.interpret(ctx); end end end
Variable.m (非终结表达式,变量类)
classdef Variable < Expression properties name end methods function obj = Variable(name) obj.name = name; end function res = interpret(obj,ctx) if(isempty(ctx.lookup(obj.name))) res = 0; else res = ctx.lookup(obj.name).interpret(ctx); end end end end
Number.m (终结表达式,数字类)
classdef Number < Expression properties number end methods function obj = Number(number) obj.number = number; end function number = interpret(obj,~) number = obj.number; end end end
Evaluator.m (非终结表达式,解析入口类)
classdef Evaluator < Expression properties syntaxTree end methods function obj = Evaluator(expr) exprs = Expression.empty(); tokens = expr.split(" "); for i=1:length(tokens) switch(tokens(i)) case "+" subexpr = Plus(exprs(end-1),exprs(end)); exprs = exprs(1:end-2); exprs(end + 1) = subexpr; case "-" subexpr = Minus(exprs(end-1),exprs(end)); exprs = exprs(1:end-2); exprs(end + 1) = subexpr; otherwise exprs(end + 1) = Variable(tokens(i)); end end obj.syntaxTree = exprs(end); end function res = interpret(obj,ctx) res = obj.syntaxTree.interpret(ctx); end end end
test.m (测试代码)
expr = "w x z + -"; ctx = Context(); ctx.put("w",Number(5)); ctx.put("x",Number(6)); ctx.put("z",Number(4)); eva = Evaluator(expr); res = eva.interpret(ctx); disp(res);
参考资料: