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