Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。
当有一个语言需要解释执行, 并且可以将语言中的句子表示为一个抽象的表达式树时, 可以使用解释器模式。
以逆波兰表示法为例, 其语法为:
expression ::= plus | minus | variable | number
plus ::= expression expression '+'
minus ::= expression expression '-'
variable ::= 'a' | 'b' | 'c' | ... | 'z'
digit = '0' | '1' | ... '9'
number ::= digit | digit number
波兰表示法的例子:
a b +
a b c + -
a b + c a - -
以下是逆波兰表示法的解释器实现 :
public interface IExpression {
int Interpret(Dictionary<string, IExpression> variables);
}
public class Number : IExpression {
private readonly int _number;
public Number(int number) {
this._number = number;
}
public int Interpret(Dictionary<string, IExpression> variables) {
return this._number;
}
}
public class Variable : IExpression {
private readonly string _name;
public Variable(string name) {
this._name = name;
}
public int Interpret(Dictionary<string, IExpression> variables) {
if (string.IsNullOrEmpty(this._name)) {
return 0;
}
return variables[this._name].Interpret(variables);
}
}
public class Plus : IExpression {
private readonly IExpression _leftOperand;
private readonly IExpression _rightOperand;
public Plus(IExpression leftOperand, IExpression rightOperand) {
this._leftOperand = leftOperand;
this._rightOperand = rightOperand;
}
public int Interpret(Dictionary<string, IExpression> variables) {
return this._leftOperand.Interpret(variables) + this._rightOperand.Interpret(variables);
}
}
public class Minus : IExpression {
private readonly IExpression _leftOperand;
private readonly IExpression _rightOperand;
public Minus(IExpression leftOperand, IExpression rightOperand) {
this._leftOperand = leftOperand;
this._rightOperand = rightOperand;
}
public int Interpret(Dictionary<string, IExpression> variables) {
return this._leftOperand.Interpret(variables) - this._rightOperand.Interpret(variables);
}
}
public class Evaluator : IExpression {
private readonly IExpression _expressionTree;
public Evaluator(string expression) {
var stack = new Stack<IExpression>();
foreach (var token in expression.Split(' ')) {
if (token == "+") {
stack.Push(new Plus(stack.Pop(), stack.Pop()));
}
else if (token == "-") {
var right = stack.Pop();
var left = stack.Pop();
stack.Push(new Minus(left, right));
}
else {
stack.Push(new Variable(token));
}
}
this._expressionTree = stack.Pop();
}
public int Interpret(Dictionary<string, IExpression> variables) {
return this._expressionTree.Interpret(variables);
}
}
class Client {
static void Main(string[] args) {
const string expression = "w x z - +";
var evaluator = new Evaluator(expression);
var sentence = new Dictionary<string, IExpression>();
sentence["w"] = new Number(5);
sentence["x"] = new Number(10);
sentence["z"] = new Number(42);
var result = evaluator.Interpret(sentence);
Console.WriteLine(result);
Console.ReadKey();
}
}