Java设计模式之解析器模式

来源:互联网 发布:2017淘宝购物节 编辑:程序博客网 时间:2024/05/21 07:33

一、定义:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。这种官话理解起来有点蛋疼。举个例子说明上述含义。“给定一个语言,定义它的文法的一种表示”,就是定义一个语言的规则,比如定义一个以阿拉伯数字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
原创粉丝点击