设计模式——解释器模式
来源:互联网 发布:淘宝店铺图标设计 编辑:程序博客网 时间: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
- 设计模式——解释器模式
- 设计模式——解释器模式
- 设计模式—— 解释器模式
- 设计模式——解释器模式
- C#设计模式—解释器模式
- 设计模式学习—解释器模式
- Java设计模式—解释器模式&迭代器模式简介
- 设计模式——解释器设计模式
- 设计模式——解释器
- 设计模式学习—Interpreter(解释器)
- 每日设计模式——解释器模式
- C#设计模式之16——解释器模式
- 设计模式学习笔记——解释器模式
- java设计模式——解释器模式
- 设计模式(22)——解释器模式
- 设计模式——解释器模式(二)
- 设计模式学习笔记——解释器模式
- PHP设计模式——解释器模式
- python openstack API 系列(Nova)
- MYSQL服务器my.cnf配置文档中文详解
- 【LeetCode006算法/编程练习C++】ZigZag Conversion //折形string重新排序
- iOS中几种数据持久化方案
- Linux网络编程之广播
- 设计模式——解释器模式
- 基于注解的Spring AOP的配置和使用
- BFS(广搜) 翻币问题
- Matlab与线性代数--矩阵的奇异值和奇异值分解
- Tiling ,Tri Tiling(递推)
- angularjs中回车键触发某一事件
- Linux 进程间通信 基础
- 动态添加Fragment
- Eclipse的Debug介绍与技巧