解釋器模式(Interperter),給定一個語言,定義一個語言的文法,而且創建一個解釋器來解釋該語言中的句子,實際開發中EL表達式或者正則表達式的解釋器就是採用這種設計模式。其模式結構以下圖。本文使用matlab語言,利用解釋器模式來實現後綴表達式的解析。html
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 (非終結表達式,減法類)lua
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 (終結表達式,數字類)htm
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 (非終結表達式,解析入口類) blog
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 (測試代碼)token
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);
參考資料:開發