博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解释器模式
阅读量:4181 次
发布时间:2019-05-26

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

解释器模式(Interpreter Pattern):给定一种语言(规定格式和语法的代码),定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

类图及角色

在这里插入图片描述

抽象表达角色(Abstract Expression):声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
终结符表达式角色(Terminal Expression):实现与文法中的终结符相关联的解释操作。一个句子中的每个终结符需要该类的一个实例。
非终结表达式角色(Non terminal Expression):对文法中的每一条规则R::=R1R2…Rn都需要一个Nonterminal Expression类型的实例变量,为文法中的非终结符实现解释(Interpret)操作。解释一般要递归地调用表示R1到Rn的那些对象的解释操作。
上下文角色(context):包含解释器之外的一些全局信息。
客户端角色(client):构建表示该文法定义的语言中一个特定的句子的抽象语法树。该抽象语法树由终结符表达式和非终结符表达式的实例装配而成,调用解释操作。

解释器模式的优缺点

优点

  1. 易于改变和扩展文法(原因1:使用类来表示文法规则2:可用继承来改变或扩展)。
  2. 增加新的解释表达式使得实现新的“计算”变得容易。

缺点

4. 每一条文法定义一个类,复杂的文法难以维护(多如乱麻的类难以交织)
当文法非常复杂时,应该用其他技术如语法分析程序或编译器生成器更为合适。
5. 效率低。最高效率的解释器不是通过直接解释分析语法树来实现的,而是将他们转化为另一种形式。(如正则表达式被转换为状态机)

解释器的适用情况
  1. 文法相对简单,使用率高。
  2. 不追求效率,或者效率不是一个关键问题。
//上下文环境角色public class Context {
private HashMap
valueMap = new HashMap<>(); public void add(Variable x, int y) {
Integer yi = new Integer(y); valueMap.put(x, yi); } public int LookUpValue(Variable x) {
int i = ((Integer)valueMap.get(x)).intValue(); System.out.println(i); return i; }}//抽象表达式角色public abstract class Expression {
public abstract int interpret(Context context);}//终结符表达式角色(变量)public class Variable extends Expression{
@Override public int interpret(Context context) {
return context.LookUpValue(this); }}//终结符表达式角色(常量)public class Constant extends Expression{
private int i; public Constant(int i) {
this.i = i; } @Override public int interpret(Context context) {
return i; }}//非终结符表达式(加)public class Add extends Expression {
private Expression left, right; public Add(Expression left, Expression right) {
this.left = left; this.right = right; } @Override public int interpret(Context context) {
return left.interpret(context) + right.interpret(context); }}//非终结符表达式(减)public class Subtract extends Expression {
private Expression left, right; public Subtract(Expression left, Expression right) {
this.left = left; this.right = right; } @Override public int interpret(Context context) {
return left.interpret(context) - right.interpret(context); }}//非终结符表达式(乘法)public class Multiply extends Expression{
private Expression left, right; public Multiply(Expression left, Expression right) {
this.left = left; this.right = right; } @Override public int interpret(Context context) {
return left.interpret(context) * right.interpret(context); }}//非终结符表达式(除法)public class Division extends Expression{
private Expression left, right; public Division(Expression left, Expression right) {
this.left = left; this.right = right; } @Override public int interpret(Context context) {
try {
return left.interpret(context) / right.interpret(context); } catch(ArithmeticException e) {
System.out.println("除数为0"); } return 0; }}//客户端public class Test {
private static Expression ex; private static Context context; public static void main(String[] args) {
context = new Context(); //设置变量常量 Variable a = new Variable(); Variable b = new Variable(); Constant c = new Constant(2); //为变量赋值 context.add(a, 5); context.add(b, 8); //运算,自己构造句子结构((a*b)/((a-b)+c)) ex = new Division(new Multiply(a, b), new Add(new Subtract(a, b), c)); System.out.println(ex.interpret(context)); }}

上一篇:

下一篇:

转载地址:http://fmrai.baihongyu.com/

你可能感兴趣的文章
Ubuntu Navicat for MySQL安装以及破解方案
查看>>
java多线程中的join方法详解
查看>>
在C++中如何实现模板函数的外部调用
查看>>
HTML5学习之——HTML 5 应用程序缓存
查看>>
HTML5学习之——HTML 5 服务器发送事件
查看>>
SVG学习之——HTML 页面中的 SVG
查看>>
SVG 滤镜学习之——SVG 滤镜
查看>>
mysql中用命令行复制表结构的方法
查看>>
hbase shell出现ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException
查看>>
让代码变得更优雅-Lombok
查看>>
解决Rhythmbox乱码
查看>>
豆瓣爱问共享资料插件发布啦
查看>>
kermit的安装和配置
查看>>
vim 配置
查看>>
openocd zylin
查看>>
linux中cat命令使用详解
查看>>
java中的异常机制
查看>>
商务智能-基本方法-数据钻取
查看>>
C++程序员技术需求规划(发展方向)
查看>>
JNI
查看>>