博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
行为类模式(三):解释器(Interpreter)
阅读量:5249 次
发布时间:2019-06-14

本文共 5034 字,大约阅读时间需要 16 分钟。

定义

给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

UML

优点

  1. 将每一个语法规则表示成一个类,方便事先语言。
  2. 因为语法由许多类表示,所以你可以轻易地改变或扩展此语言
  3. 通过在类结构中加入新的方法,可以在解释的同时增加新的行为,例如打印格式的梅花或者进行复制的程序验证。

缺点

  1. 解释器模式会引起类膨胀,每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来了非常多的麻烦。
  2. 解释器模式采用递归调用方法,每个非终结符表达式只关心与自己有关的表达式,每个表达式需要知道最终的结果,必须一层一层地剥茧,无论是面向过程的语言还是面向对象的语言,递归都是在必要条件下使用的,它导致调试非常复杂。想想看,如果要排查一个语法错误,我们是不是要一个一个断点的调试下去,直到最小的语法单元。
  3. 效率问题,解释器模式由于使用了大量的循环和递归,效率是个不容忽视的问题,特别是用于解析复杂、冗长的语法时,效率是难以忍受的。

应用场景

  1. 重复发生的问题可以使用解释器模式。
  2. 一个简单语法需要解释的场景。
  3. 可以处理脚本语言和编程语言,比如正则表达式。

示例

使用解释器模式完成一个两则运算器,要求输入表达式和每个符号的值得到表达式的最终结果。

Java

1 import java.io.BufferedReader;  2 import java.io.IOException;  3 import java.io.InputStreamReader;  4 import java.util.HashMap;  5 import java.util.Stack;  6   7 public class Main  8 {  9     public static void main(String[] args) throws IOException 10     { 11         String expStr = getExpStr(); 12         //赋值 13         HashMap
var = getValue(expStr); 14 Calculator cal = new Calculator(expStr); 15 System.out.println("运算结果为:" + expStr + "=" + cal.run(var)); 16 } 17 18 /** 19 * 获得表达式 20 */ 21 public static String getExpStr() throws IOException 22 { 23 System.out.print("请输入表达式:"); 24 return (new BufferedReader(new InputStreamReader(System.in))).readLine(); 25 } 26 27 /** 28 * 获得值映射 29 */ 30 public static HashMap
getValue(String exprStr) throws IOException 31 { 32 HashMap
map = new HashMap<>(); 33 //解析有几个参数要传递 34 for (char ch : exprStr.toCharArray()) 35 { 36 if (ch != '+' && ch != '-') 37 { 38 //解决重复参数的问题 39 if (!map.containsKey(String.valueOf(ch))) 40 { 41 System.out.print("请输入" + ch + "的值:"); 42 String in = (new BufferedReader(new InputStreamReader(System.in))).readLine(); 43 map.put(String.valueOf(ch), Integer.valueOf(in)); 44 } 45 } 46 } 47 return map; 48 } 49 50 /** 51 * 表达式基类 52 */ 53 public static abstract class Expression 54 { 55 /** 56 * 解析公式和数值 57 * @param var key值是是公式中的参数,value值是具体的数字 58 * @return 结果 59 */ 60 public abstract int interpreter(HashMap
var); 61 } 62 63 /** 64 * 取值表达式 65 */ 66 public static class VarExpression extends Expression 67 { 68 private String key; 69 70 public VarExpression(String _key) 71 { 72 key = _key; 73 } 74 75 @Override 76 public int interpreter(HashMap
var) 77 { 78 return var.get(key); 79 } 80 } 81 82 /** 83 * 运算表达式,仅关心左右两个值 84 */ 85 public static abstract class SymbolExpression extends Expression 86 { 87 protected Expression left; 88 protected Expression right; 89 90 public SymbolExpression(Expression _left, Expression _right) 91 { 92 this.left = _left; 93 this.right = _right; 94 } 95 } 96 97 /** 98 * 加法表达式处理 99 */100 public static class AddExpression extends SymbolExpression101 {102 public AddExpression(Expression _left, Expression _right)103 {104 super(_left, _right);105 }106 107 public int interpreter(HashMap
var)108 {109 return super.left.interpreter(var) + super.right.interpreter(var);110 }111 }112 113 /**114 * 减法表达式处理115 */116 public static class SubExpression extends SymbolExpression117 {118 public SubExpression(Expression _left, Expression _right)119 {120 super(_left, _right);121 }122 123 public int interpreter(HashMap
var)124 {125 return super.left.interpreter(var) - super.right.interpreter(var);126 }127 }128 129 /**130 * 运算类131 */132 public static class Calculator133 {134 //定义的表达式135 private Expression expression;136 137 //构造函数传参,并解析138 public Calculator(String expStr)139 {140 //定义一个堆栈,安排运算的先后顺序141 Stack
stack = new Stack
();142 //表达式拆分为字符数组143 char[] charArray = expStr.toCharArray();144 //运算145 Expression left = null;146 Expression right = null;147 for (int i = 0; i < charArray.length; i++)148 {149 switch (charArray[i])150 {151 case '+': //加法152 //加法结果放到堆栈中153 left = stack.pop();154 right = new VarExpression(String.valueOf(charArray[++i]));155 stack.push(new AddExpression(left, right));156 break;157 case '-': //减法158 left = stack.pop();159 right = new VarExpression(String.valueOf(charArray[++i]));160 stack.push(new SubExpression(left, right));161 break;162 default: //公式中的变量163 stack.push(new VarExpression(String.valueOf(charArray[i])));164 }165 }166 //把运算结果抛出来167 this.expression = stack.pop();168 }169 170 //开始运算171 public int run(HashMap
var)172 {173 return this.expression.interpreter(var);174 }175 }176 }
View Code

 

转载于:https://www.cnblogs.com/hammerc/p/4743800.html

你可能感兴趣的文章
android 签名
查看>>
vue项目中使用百度统计
查看>>
android:scaleType属性
查看>>
SuperEPC
查看>>
mysql-5.7 innodb 的并行任务调度详解
查看>>
shell脚本
查看>>
Upload Image to .NET Core 2.1 API
查看>>
Js时间处理
查看>>
Java项目xml相关配置
查看>>
三维变换概述
查看>>
第三次作业
查看>>
vue route 跳转
查看>>
【雷电】源代码分析(二)-- 进入游戏攻击
查看>>
Entityframework:“System.Data.Entity.Internal.AppConfig”的类型初始值设定项引发异常。...
查看>>
Linux中防火墙centos
查看>>
mysql新建用户,用户授权,删除用户,修改密码
查看>>
FancyCoverFlow
查看>>
JS博客
查看>>
如何设置映射网络驱动器的具体步骤和方法
查看>>
ASP.NET WebApi 基于OAuth2.0实现Token签名认证
查看>>