解释器模式(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.