定义:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子-
UML:
- AbstractExpression:定义解释器的接口,约定解释器的解释操作。
- TerminalExpression:终结符解释器,用来实现语法规则中和终结符相关的操作,不再包含其他的解释器。
- NonterminalExpression:非终结符解释器,用来实现语法规则中非终结符相关的操作,通常一个解释器对应一个语法规则,可以包含其他解释器。
- Context:上下文,通常包含各个解释器需要的数据或是公共的功能。
- Client:客户端,指的是使用解释器的客户端,通常在这里将按照语言的语法做的表达式转换成使用解释器对象描述的抽象语法树,然后调用解释操作。
模型:四则运算+-实现
先使用巴科斯范式定义加减的语法:
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
a b c + - ->a - b + c
a b + c a - - ->a+b-c-a
抽象语句
interface Expression {
public int interpret(final Map<String, Expression> variables);
}
+语句处理类:
class Plus implements Expression {
//要记录前后表达式
Expression leftOperand;
Expression rightOperand;
public Plus(final Expression left, final Expression right) {
leftOperand = left;
rightOperand = right;
}
public int interpret(final Map<String, Expression> variables) {
//具体操作前后表达式
return leftOperand.interpret(variables) + rightOperand.interpret(variables);
}
}
-语句处理类:
class Minus implements Expression {
Expression leftOperand;
Expression rightOperand;
public Minus(final Expression left, final Expression right) {
leftOperand = left;
rightOperand = right;
}
public int interpret(final Map<String, Expression> variables) {
return leftOperand.interpret(variables) - rightOperand.interpret(variables);
}
}
数字类:
class Number implements Expression {
private int number;
public Number(final int number) { this.number = number; }
public int interpret(final Map<String, Expression> variables) { return number; }
}
变量处理类:
class Variable implements Expression {
private String name;
public Variable(final String name) { this.name = name; }
public int interpret(final Map<String, Expression> variables) {
if (null == variables.get(name)) return 0; // Either return new Number(0).
return variables.get(name).interpret(variables);
}
}
设计一个能够处理=-运算的计算器Client:
class Evaluator implements Expression {
//输入的逆波兰式语句
private Expression syntaxTree;
public Evaluator(final String expression) {
final Stack<Expression> expressionStack = new Stack<Expression>();
for (final String token : expression.split(" ")) {
if (token.equals("+")) {
//将前两个表达式出栈生成新的+表达式
final Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());
expressionStack.push(subExpression);
} else if (token.equals("-")) {
final Expression right = expressionStack.pop();
final Expression left = expressionStack.pop();
final Expression subExpression = new Minus(left, right);
expressionStack.push(subExpression);
} else
//将终结表达式入栈
expressionStack.push(new Variable(token));
}
syntaxTree = expressionStack.pop();
}
public int interpret(final Map<String, Expression> context) {
return syntaxTree.interpret(context);
}
}
测试:
public class InterpreterExample {
public static void main(final String[] args) {
final String expression = "w x z - +";
final Evaluator sentence = new Evaluator(expression);
final Map<String, Expression> variables = new HashMap<String, Expression>();
variables.put("w", new Number(5));
variables.put("x", new Number(10));
variables.put("z", new Number(42));
final int result = sentence.interpret(variables);
System.out.println(result);
}
}
输出:-27 ,执行的是 5 + 10 - 42 = -27