解釋器模式(Interpreter) 定義 解釋器模式(Interpreter),給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。 類圖 描述 Expression:抽象表達式,聲明一個所有的具體表達式都需要實現的抽象介面;這個介面主要是一個inter ...
解釋器模式(Interpreter)
定義
解釋器模式(Interpreter),給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
類圖
描述
Expression:抽象表達式,聲明一個所有的具體表達式都需要實現的抽象介面;這個介面主要是一個interpret()方法,稱做解釋操作。
Terminal Expression:終結符表達式,實現了抽象表達式所要求的介面;文法中的每一個終結符都有一個具體終結表達式與之相對應。比如公式R=R1+R2,R1和R2就是終結符,對應的解析R1和R2的解釋器就是終結符表達式。
Nonterminal Expression:非終結符表達式,文法中的每一條規則都需要一個具體的非終結符表達式,非終結符表達式一般是文法中的運算符或者其他關鍵字,比如公式R=R1+R2中,“+"就是非終結符,解析“+”的解釋器就是一個非終結符表達式。
Context:環境,它的任務一般是用來存放文法中各個終結符所對應的具體值,比如R=R1+R2,給R1賦值100,給R2賦值200,這些信息需要存放到環境中。
應用場景
首先輸入一個加減或乘除的運算公式,比如a+b-c+a或a*b/c*a,再給每個參數賦值,最後根據公式完成運算並得到結果。
/// <summary> /// 環境 /// </summary> public class Context { private Dictionary<char, double> variable; public Dictionary<char, double> Variable { get { if (this.variable == null) { this.variable = new Dictionary<char, double>(); } return this.variable; } } } /// <summary> /// 抽象表達式 /// </summary> public abstract class Expression { public abstract double Interpret(Context context); } /// <summary> /// 變數,終結符表達式 /// </summary> public class VariableExpression : Expression { private char key; public VariableExpression(char key) { this.key = key; } public override double Interpret(Context context) { return context.Variable[this.key]; } } /// <summary> /// 操作符,非終結符表達式 /// </summary> public abstract class OperatorExpression : Expression { protected Expression left; protected Expression right; public OperatorExpression(Expression left, Expression right) { this.left = left; this.right = right; } } public class AddExpression : OperatorExpression { public AddExpression(Expression left, Expression right) : base(left, right) { } public override double Interpret(Context context) { return this.left.Interpret(context) + this.right.Interpret(context); } } public class SubExpression : OperatorExpression { public SubExpression(Expression left, Expression right) : base(left, right) { } public override double Interpret(Context context) { return this.left.Interpret(context) - this.right.Interpret(context); } } public class MulExpression: OperatorExpression { public MulExpression(Expression left, Expression right) : base(left, right) { } public override double Interpret(Context context) { return this.left.Interpret(context) * this.right.Interpret(context); } } public class DivExpression: OperatorExpression { public DivExpression(Expression left, Expression right) : base(left, right) { } public override double Interpret(Context context) { return this.left.Interpret(context) / this.right.Interpret(context); } } public class Calculator { private string expression; private Context context; public Calculator(string expression) { this.expression = expression; this.context = new Context(); } public double Calculate() { char[] vars = this.expression.ToCharArray(); foreach (char c in vars) { if (c == '+' || c == '-' || c == '*' || c == '/') { continue; } if (!this.context.Variable.ContainsKey(c)) { Console.Write(c + "="); this.context.Variable.Add(c, double.Parse(Console.ReadLine())); } } Expression left = new VariableExpression(vars[0]); Expression right = null; Stack<Expression> stack = new Stack<Expression>(); stack.Push(left); for (int i = 1; i < vars.Length; i += 2) { left = stack.Pop(); right = new VariableExpression(vars[i + 1]); switch (vars[i]) { case '+': stack.Push(new AddExpression(left, right)); break; case '-': stack.Push(new SubExpression(left, right)); break; case '*': stack.Push(new MulExpression(left, right)); break; case '/': stack.Push(new DivExpression(left, right)); break; } } double value = stack.Pop().Interpret(this.context); stack.Clear(); return value; } }
輸入公式:a+b-c+a
賦值:
a=10
b=5
c=3
運算結果:22