Java设计模式之解析器模式

一、定义:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。这种官话理解起来有点蛋疼。举个例子说明上述含义。“给定一个语言,定义它的文法的一种表示”,就是定义一个语言的规则,比如定义一个以阿拉伯数字0开头和以0结束的规则;“并定义一个解释器,这个解释器使用该表示来解释语言中的句子”:定义一个解析器,解析传过来的参数,若符合以阿拉伯数字0开头和以0结束这这种规则,返回true,否则返回false。
二、角色
1.AbstractExpression(抽象表达式) 声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。

2.TerminalExpression(终结符表达式) 实现与文法中的终结符相关联的解释操作。 一个句子中的每个终结符需要该类的一个实例。

3.NonterminalExpression(非终结符表达式) 为文法中的非终结符实现解释(Interpret)操作。
4.Context(上下文) 包含解释器之外的一些全局信息。

5.Client(客户) 构建(或被给定)表示该文法定义的语言中一个特定的句子的抽象语法树。 该抽象语法树由NonterminalExpression和TerminalExpression的实例装配而成。 调j用解释操作。
三、解析字符串,实现乘除运算的demo(本demo无需保存解析器以外的全局信息,所以没有定义Context类)。此处,定义的文法便是符号“*”代表乘,“/”代表除,其余代表数字。当然,也可自行扩展,添加减等文法规则。
1.AbstractExpression(抽象表达式) ,申明了一个interpret()的解析操作,不管终结符表达式还是非终结符表达式都要继承抽象表达式。

package com.exaple.interpret;
/**
 * 抽象表达式
 * @author zeng
 *
 */
public interface Expression {
    public int interpret();

}

2.TerminalExpression(终结符表达式),也就是不能再继续推导的表达式,比如传入一个数字,就解析成一个数字。

package com.exaple.interpret;
/**
 * 终结符表达式
 * @author zeng
 *
 */
public class TerminalExpression implements Expression {
    private int value;


    public TerminalExpression(int value) {
        super();
        this.value = value;
    }


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



}

3.NonterminalExpression(非终结符表达式) ,非终结符可以推导出其他表达式,比如S = S1 + S2,那么S就可以推导出S1 + S2,在本demo中,至少包含两个终结符,也可以包含一个终结符和一个非终结符。

package com.exaple.interpret;
/**
 * 非终结表达式
 * @author zeng
 *
 */
public abstract class NonterminalExpression implements Expression {
    protected Expression left;
    protected Expression right;

    public NonterminalExpression(Expression left, Expression right) {
        super();
        this.left = left;
        this.right = right;
    }


}

package com.exaple.interpret;
/**
 * 除法表达式
 * @author zeng
 *
 */
public class DivExpression extends NonterminalExpression{

    public DivExpression(Expression left, Expression right) {
        super(left, right);

    }

    @Override
    public int interpret() {
        int val = right.interpret();
        if (val == 0) {
            System.out.println("零不能做分母");
            return -1;

        }else {
            return left.interpret() / right.interpret();
        }

    }

}

package com.exaple.interpret;
/**
 * 乘法表达式
 * @author zeng
 *
 */
public class MulExpression extends NonterminalExpression{

    public MulExpression(Expression left, Expression right) {
        super(left, right);

    }

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

}


4.Client(客户):装配终结符表达式和非终结符表达式实例。 调j用解释操作。

package com.exaple.interpret;
/**
 * 计算器(客户)
 * @author zeng
 *
 */
public class Caculator {
    public int caculate(String statement){
        Expression left = null;
        Expression right = null;
        Expression lastExpression = null;
        String[] statements = statement.split(" ");

        for (int i = 0; i < statements.length; i++) {
            if (statements[i].equals("*")) {
                left = lastExpression;
                int val = Integer.parseInt(statements[++i]);
                //statements[++i]表示一个数字,实例化一个终结符表达式
                right = new TerminalExpression(val);
                lastExpression = new MulExpression(left, right);


            }else if (statements[i].equals("/")) {
                left = lastExpression;
                int val = Integer.parseInt(statements[++i]);
                //statements[++i]表示一个数字,实例化一个终结符表达式
                right = new TerminalExpression(val);
                lastExpression = new DivExpression(left, right);

            }else {
                lastExpression = new TerminalExpression(Integer.parseInt(statements[i]));

            }
        }


        return lastExpression.interpret();
    }

}

测试

package com.exaple.interpret;
/**
 * 客户
 * @author zeng
 *
 */
public class Test {

    public static void main(String[] args) {
       String content = "6 * 4 * 8 / 6";
       Caculator caculator = new Caculator();
       int result = caculator.caculate(content);
       System.out.println("计算结果: " + result);

    }

}

打印结果:

计算结果: 32
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值