设计模式——解释器模式

来源:互联网 发布:淘宝店铺图标设计 编辑:程序博客网 时间:2024/05/01 23:03

解释器模式:定义一个语法, 定义一个解释器,该解释器处理该语法句子将某些复杂问题,表达为某种语法规则,然后构建解释器来解释处理这类句子
优点:
容易修改,修改语法规则只要修改相应非终结符即可
扩展方便,扩展语法,只要增加非终结符类即可
缺点:
对于复杂语法的表示会产生复杂的类层次结构,不便管理和维护
解释器采用递归方式,效率会受影响
注意事项:
尽量不要在重要的模块中使用解释器模式
解释器模式在实际的系统开发中使用的非常少
可以考虑一下Expression4J、MESP、Jep等开源的解析工具包
适用场合:
当你有一个简单语法,而且效率不是问题的时候
一些数据分析工具、报表设计工具、科学计算工具等

计算模型按正常算术方式书写,解释器处理语法逻辑
计算模型里有两类符号:数据和计算符
用逆波兰算法分析算式语法
用解释器模式处理数据

AbstractExpresstion .class

import java.util.HashMap;public abstract class AbstractExpresstion {    public abstract Float interpreter(HashMap<String, Float> var);}

VarExpresstion .class

import java.util.HashMap;public class VarExpresstion extends AbstractExpresstion {    private String key;    public VarExpresstion(String _key) {        this.key = _key;    }    @Override    public Float interpreter(HashMap<String, Float> var) {        // TODO Auto-generated method stub        return var.get(this.key);    }}

SymbolExpresstion .class

import java.util.HashMap;public abstract class SymbolExpresstion extends AbstractExpresstion {    protected AbstractExpresstion left;    protected AbstractExpresstion right;    public SymbolExpresstion(AbstractExpresstion _left,            AbstractExpresstion _right) {        this.left = _left;        this.right = _right;    }}

DivExpresstion .class

import java.util.HashMap;public class DivExpresstion extends SymbolExpresstion {    public DivExpresstion(AbstractExpresstion _left, AbstractExpresstion _right) {        super(_left, _right);        // TODO Auto-generated constructor stub    }    @Override    public Float interpreter(HashMap<String, Float> var) {        // TODO Auto-generated method stub        return super.left.interpreter(var) / super.right.interpreter(var);    }}

SubExpresstion .class

import java.util.HashMap;public class SubExpresstion extends SymbolExpresstion {    public SubExpresstion(AbstractExpresstion _left, AbstractExpresstion _right) {        super(_left, _right);        // TODO Auto-generated constructor stub    }    @Override    public Float interpreter(HashMap<String, Float> var) {        // TODO Auto-generated method stub        return super.left.interpreter(var) - super.right.interpreter(var);    }}

MultiExpresstion .class

import java.util.HashMap;public class MultiExpresstion extends SymbolExpresstion {    public MultiExpresstion(AbstractExpresstion _left,            AbstractExpresstion _right) {        super(_left, _right);        // TODO Auto-generated constructor stub    }    @Override    public Float interpreter(HashMap<String, Float> var) {        // TODO Auto-generated method stub        return super.left.interpreter(var) * super.right.interpreter(var);    }}

AddExpresstion .class

import java.util.HashMap;public class AddExpresstion extends SymbolExpresstion {    public AddExpresstion(AbstractExpresstion _left, AbstractExpresstion _right) {        super(_left, _right);        // TODO Auto-generated constructor stub    }    @Override    public Float interpreter(HashMap<String, Float> var) {        // TODO Auto-generated method stub        return super.left.interpreter(var) + super.right.interpreter(var);    }}

RPN .class

import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.Stack;import java.util.StringTokenizer;public class RPN {    private ArrayList<String> expression = new ArrayList<String>();// 存储中序表达式    private ArrayList<String> right = new ArrayList<String>();// 存储右序表达式    private AbstractExpresstion result;// 结果    // 依据输入信息创建对象,将数值与操作符放入ArrayList中    public RPN(String input) {        StringTokenizer st = new StringTokenizer(input, "+-*/()", true);        while (st.hasMoreElements()) {            expression.add(st.nextToken());        }    }    // 将中序表达式转换成右序表达式    private void toRight() {        Stacks aStack = new Stacks();        String operator;        int position = 0;        while (true) {            if (Calculate.isOperator((String) expression.get(position))) {                if (aStack.top == -1                        || ((String) expression.get(position)).equals("(")) {                    aStack.push(expression.get(position));                } else {                    if (((String) expression.get(position)).equals(")")) {                        if (!((String) aStack.top()).equals("(")) {                            operator = (String) aStack.pop();                            right.add(operator);                        }                    } else {                        if (Calculate.priority((String) expression                                .get(position)) <= Calculate                                .priority((String) aStack.top())                                && aStack.top != -1) {                            operator = (String) aStack.pop();                            if (!operator.equals("("))                                right.add(operator);                        }                        aStack.push(expression.get(position));                    }                }            } else                right.add(expression.get(position));            position++;            if (position >= expression.size())                break;        }        while (aStack.top != -1) {            operator = (String) aStack.pop();            right.add(operator);        }    }    // 对右序表达式进行求值    public void getResult(HashMap<String, Float> var) {        this.toRight();        Stack<AbstractExpresstion> stack = new Stack<AbstractExpresstion>();        AbstractExpresstion op1, op2;        String is = null;        Iterator it = right.iterator();        while (it.hasNext()) {            is = (String) it.next();            if (Calculate.isOperator(is)) {                op2 = stack.pop();                op1 = stack.pop();                stack.push(Calculate.twoResult(is, op1, op2));            } else                stack.push(new VarExpresstion(is));        }        result = stack.pop();        it = expression.iterator();        while (it.hasNext()) {            System.out.print((String) it.next());        }        System.out.println("=" + result.interpreter(var));    }    public static class Calculate {        // 判断是否为操作符号        public static boolean isOperator(String operator) {            if (operator.equals("+") || operator.equals("-")                    || operator.equals("*") || operator.equals("/")                    || operator.equals("(") || operator.equals(")"))                return true;            else                return false;        }        // 判断操作符号的优先级别        public static int priority(String operator) {            if (operator.equals("+") || operator.equals("-")                    || operator.equals("("))                return 1;            else if (operator.equals("*") || operator.equals("/"))                return 2;            else                return 0;        }        // 做2值之间的计算        public static AbstractExpresstion twoResult(String op,                AbstractExpresstion a, AbstractExpresstion b) {            try {                AbstractExpresstion result = null;                if (op.equals("+"))                    result = new AddExpresstion(a, b);                else if (op.equals("-"))                    result = new SubExpresstion(a, b);                else if (op.equals("*"))                    result = new MultiExpresstion(a, b);                else if (op.equals("/"))                    result = new DivExpresstion(a, b);                else                    ;                return result;            } catch (NumberFormatException e) {                System.out.println("input has something wrong!");                return null;            }        }    }    public class Stacks {        private LinkedList list = new LinkedList();        int top = -1;        public void push(Object value) {            top++;            list.addFirst(value);        }        public Object pop() {            Object temp = list.getFirst();            top--;            list.removeFirst();            return temp;        }        public Object top() {            return list.getFirst();        }    }}

Calculator .class

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import com.java.jikexueyuan.interpreter.cls.RPN;public class Calculator {    public Calculator() {        float[][] dataSource = new float[3][6];        System.out.println("data source:");        for (int i = 0; i < 3; i++) {            for (int j = 0; j < 6; j++) {                dataSource[i][j] = (float) (Math.random() * 100);                System.out.print(dataSource[i][j] + ",");            }            System.out.println(";");        }        try {            System.out.println("Input a expression:");            BufferedReader is = new BufferedReader(new InputStreamReader(                    System.in));            for (;;) {                String input = new String();                input = is.readLine().trim();                if (input.equals("q"))                    break;                else {                    RPN boya = new RPN(input);                    HashMap<String, Float> var;                    for (int i = 0; i < 3; i++) {                        var = new HashMap<String, Float>();                        var.put("a", dataSource[i][0]);                        var.put("b", dataSource[i][1]);                        var.put("c", dataSource[i][2]);                        var.put("d", dataSource[i][3]);                        var.put("e", dataSource[i][4]);                        var.put("f", dataSource[i][5]);                        boya.getResult(var);                    }                }                System.out                        .println("Input another expression or input 'q' to quit:");            }            is.close();        } catch (IOException e) {            System.out.println("Wrong input!!!");        }    }}

MainTest .class

public class MainTest {    public static void main(String[] args) {        new Calculator();    }}
0 0
原创粉丝点击