解释器模式

39 篇文章 2 订阅
11 篇文章 0 订阅

介绍: 解释器是一种用的比较少的行为模式,其提供了一种解释语言的语法,或者表达式的方式。该模式定义了一个表达式的接口。

运用:

  • 手机号码的验证
  1. 移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188

  2. 联通:130、131、132、152、155、156、185、186

  3. 电信:133、153、180、189、(1349卫通)

正则表达式"((13[0-9])|(15[4,\D])|(18[0,5-9]))\d{8}$"

  • xml解析

重点:

  1. 必须有一个抽象接口
  2. 构建语法树

应用场景:

  1. 简单的语言需要解释执行而且可以将该语言中的语句表示一个抽象的语法树。
  2. 对于某个特定的领域出现的不断重复的问题,可以转换成一种语法规则下的语句。

优缺点:
优点:
解决----》每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来了非常多的麻烦。

缺点:

  • 解释器模式采用递归调用方法,每个非终结符表达式只关心与自己有关的表达式,每个表达式需要知道最终的结果,必须一层一层地剥茧,无论是面向过程的语言还是面向对象的语言,递归都是在必要条件下使用的,它导致调试非常复杂。想想看,如果要排查一个语法错误,我们是不是要一个一个断点的调试下去,直到最小的语法单元。
  • 解释器模式由于使用了大量的循环和递归,效率是个不容忽视的问题,特别是用于解析复杂、冗长的语法时,效率是难以忍受的。

示例代码:

Node.java

package com.test.interpretor;

/**
 * 抽象接口
 */
public interface Node {
    public int interpret();
}

ValueNode.java

package com.test.interpretor;

/**
 * 终结符
 */
public class ValueNode implements Node{
    private int value;

    public ValueNode(int value) {
        this.value = value;
    }

    @Override
    public int interpret() {
       return value;
    }
}

SymbolNode.java

package com.test.interpretor;

/**
 * 非终结符
 */
public abstract class SymbolNode implements Node{
    protected Node left;
    protected Node right;

    public SymbolNode(Node left, Node right) {
        this.left = left;
        this.right = right;
    }


}


MulNode.java

package com.test.interpretor;

/**
 * 运算乘法
 */
public class MulNode extends SymbolNode{
    public MulNode(Node left, Node right) {
        super(left, right);
    }

    @Override
    public int interpret() {
        return left.interpret() * right.interpret();
    }
}

DivNode.java

package com.test.interpretor;

/**
 * 运算除法
 */
public class DivNode extends SymbolNode{
    public DivNode(Node left, Node right) {
        super(left, right);
    }

    @Override
    public int interpret() {
        return left.interpret() / right.interpret();
    }
}

ModNode.java

package com.test.interpretor;

/**
 * 模运算
 */
public class ModNode extends SymbolNode{
    public ModNode(Node left, Node right) {
        super(left, right);
    }

    @Override
    public int interpret() {
        return left.interpret() % right.interpret();
    }
}

Caculator.java

package com.test.interpretor;

public class Caculator {
    public int build(String statement) {
        Node left = null;
        Node right = null;
        Node lastNode = null;
        String[] statements = statement.split(" ");
        for (int i = 0; i < statements.length; i++) {
            if (statements[i].equalsIgnoreCase("*")) {
                //计算乘法
                left = lastNode;
                int value = Integer.parseInt(statements[++i]);
                right = new ValueNode(value);
                // 此时新建一个非终结符
                lastNode = new MulNode(left, right);
            } else if (statements[i].equalsIgnoreCase("/")) {
                //计算除法
                left = lastNode;
                int value = Integer.parseInt(statements[++i]);
                right = new ValueNode(value);
                // 此时新建一个非终结符
                lastNode = new DivNode(left, right);
            } else if (statements[i].equalsIgnoreCase("%")) {
                //计算除法
                left = lastNode;
                int value = Integer.parseInt(statements[++i]);
                right = new ValueNode(value);
                // 此时新建一个非终结符
                lastNode = new ModNode(left, right);
            } else {
                lastNode = new ValueNode(Integer.parseInt(statements[i]));
            }
        }
        return lastNode.interpret();
    }
}

Client.java

package com.test.interpretor;

public class Client {
    public static void main(String[] args) {
        String contentString = "3 * 5 * 7 / 3 % 4";
        Caculator caculator = new Caculator();
        int result = caculator.build(contentString);
        System.out.println("result = " + result);
    }

}

运行结果:

> Task :interpretor:Client.main()
result = 3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值