行为模式:Interpreter(解释器)

来源:互联网 发布:实时定量pcr数据分析 编辑:程序博客网 时间:2024/06/04 18:49



The following Reverse Polish notation example illustrates the interpreter pattern. The grammar
expression ::= plus | minus | variable | number
plus ::= expression expression '+'
minus ::= expression expression '-'
variable  ::= 'a' | 'b' | 'c' | ... | 'z'
digit = '0' | '1' | ... '9'
number ::= digit | digit number

defines a language which contains reverse Polish expressions like:
a b +
a b c + -
a b + c a - -

Following the interpreter pattern there is a class for each grammar rule.

import java.util.Map; interface Expression {    public int interpret(Map<String,Expression> variables);} class Number implements Expression {    private int number;    public Number(int number)       { this.number = number; }    public int interpret(Map<String,Expression> variables)  { return number; }} class Plus implements Expression {    Expression leftOperand;    Expression rightOperand;    public Plus(Expression left, Expression right) {         leftOperand = left;         rightOperand = right;    }     public int interpret(Map<String,Expression> variables)  {         return leftOperand.interpret(variables) + rightOperand.interpret(variables);    }} class Minus implements Expression {    Expression leftOperand;    Expression rightOperand;    public Minus(Expression left, Expression right) {         leftOperand = left;         rightOperand = right;    }     public int interpret(Map<String,Expression> variables)  {         return leftOperand.interpret(variables) - rightOperand.interpret(variables);    }} class Variable implements Expression {    private String name;    public Variable(String name)       { this.name = name; }    public int interpret(Map<String,Expression> variables)  {         if(null==variables.get(name)) return 0; //Either return new Number(0).        return variables.get(name).interpret(variables);     }}

While the interpreter pattern does not address parsing[2] a parser is provided for completeness.

import java.util.Map;import java.util.Stack; class Evaluator implements Expression {    private Expression syntaxTree;     public Evaluator(String expression) {        Stack<Expression> expressionStack = new Stack<Expression>();        for (String token : expression.split(" ")) {            if  (token.equals("+")) {                Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());                expressionStack.push( subExpression );            }            else if (token.equals("-")) {                // it's necessary remove first the right operand from the stack                Expression right = expressionStack.pop();                // ..and after the left one                Expression left = expressionStack.pop();                Expression subExpression = new Minus(left, right);                expressionStack.push( subExpression );            }            else                                        expressionStack.push( new Variable(token) );        }        syntaxTree = expressionStack.pop();    }     public int interpret(Map<String,Expression> context) {        return syntaxTree.interpret(context);    }}

Finally evaluating the expression "w x z - +" with w = 5, x = 10, and z = 42.

import java.util.Map;import java.util.HashMap; public class InterpreterExample {    public static void main(String[] args) {        String expression = "w x z - +";        Evaluator sentence = new Evaluator(expression);        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));        int result = sentence.interpret(variables);        System.out.println(result);    }}

原创粉丝点击