美文网首页
设计模式-解析器模式(二十一)

设计模式-解析器模式(二十一)

作者: 巨子联盟 | 来源:发表于2018-05-28 19:22 被阅读0次

解析器模式
给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
这种模式被用在 SQL 解析、符号处理引擎等。

Jsoup这个源码里面用到,代码简单,功能狠强大.

可利用场景比较少,JAVA 中如果碰到可以用 expression4J 代替。

  • 上类图:
解析器模式.png
  • 代码示例:
  1. 创建表达式接口
package com.byedbl.interpreter;

/**
 * The interface of our BooleanExp Interpreter
 * BooleanExp definition is:
 * BooleanExp ::= VariableExp | Constant | OrExp | AndExp
 * | NotExp | '(' BooleanExp ')'
 * AndExp ::= BooleanExp 'and' BooleanExp
 * OrExp ::= BooleanExp 'or' BooleanExp
 * NotExp ::= BooleanExp 'not' BooleanExp
 * Constant ::= 'true' | 'false'
 * VariableExp ::= 'A' | 'B' | ... | 'Z'
 */
public interface BooleanExp {
    boolean evaluate(Context c);

    BooleanExp replace(String var, BooleanExp exp);

    BooleanExp copy();
}
  1. 创建一个终结符表达式
package com.byedbl.interpreter;

/**
 * A variable expression implements BooleanExp
 * A terminal expression
 */
public class VariableExp implements BooleanExp {
    private String name;

    public VariableExp(String _name) {
        name = _name;
    }

    @Override
    public boolean evaluate(Context c) {
        return c.lookUp(name);
    }

    @Override
    public BooleanExp copy() {
        return new VariableExp(name);
    }

    @Override
    public BooleanExp replace(String var, BooleanExp exp) {
        if (var.equals(name)) {
            return exp.copy();
        } else {
            return new VariableExp(name);
        }
    }

}
  1. 创建非终结符表达式
package com.byedbl.interpreter;

/**
 * A NonterminalExpression
 */
public class AndExp implements BooleanExp {
    private BooleanExp operand1;
    private BooleanExp operand2;

    public AndExp(BooleanExp oper1, BooleanExp oper2) {
        operand1 = oper1;
        operand2 = oper2;
    }

    @Override
    public boolean evaluate(Context c) {
        return operand1.evaluate(c) &&
                operand2.evaluate(c);
    }

    @Override
    public BooleanExp copy() {
        return new AndExp(operand1.copy(), operand2.copy());
    }

    @Override
    public BooleanExp replace(String var, BooleanExp exp) {
        return new AndExp(
                operand1.replace(var, exp),
                operand2.replace(var, exp)
        );
    }
}
package com.byedbl.interpreter;

/**
 * A NonterminalExpression
 */
public class NotExp implements BooleanExp {
    private BooleanExp opernot1;

    public NotExp(BooleanExp oper1) {
        opernot1 = oper1;
    }

    @Override
    public boolean evaluate(Context c) {
        return !(opernot1.evaluate(c));
    }

    @Override
    public BooleanExp copy() {
        return new NotExp(opernot1.copy());
    }

    @Override
    public BooleanExp replace(String var, BooleanExp exp) {
        return new NotExp(opernot1.replace(var, exp));
    }
}
package com.byedbl.interpreter;

/**
 * A NonterminalExpression
 */
public class OrExp implements BooleanExp {
    private BooleanExp operor1;
    private BooleanExp operor2;

    public OrExp(BooleanExp oper1, BooleanExp oper2) {
        operor1 = oper1;
        operor2 = oper2;
    }

    @Override
    public boolean evaluate(Context c) {
        return operor1.evaluate(c) ||
                operor2.evaluate(c);
    }

    @Override
    public BooleanExp copy() {
        return new OrExp(operor1.copy(), operor2.copy());
    }

    @Override
    public BooleanExp replace(String var, BooleanExp exp) {
        return new OrExp(
                operor1.replace(var, exp),
                operor2.replace(var, exp)
        );
    }
}
  1. 环境角色
package com.byedbl.interpreter; /**
 * A Context to record variable value
 */

import java.util.Hashtable;

public class Context {
    private Hashtable<String,Boolean> context = new Hashtable<>();

    public void assign(String name, boolean val) {
        context.put(name, val);
    }

    public boolean lookUp(String name) {
        return context.get(name);
    }

    public Context() {
    }
}
  1. 客户端用法
package com.byedbl.interpreter; /**
 *
 */

public class Test  {
    public static void main(String[] args) {
        // Test :
        //         (true and x) and (y and (not x))
        Context context = new Context();
       
        VariableExp x = new VariableExp("X");
        VariableExp y = new VariableExp("Y");
        VariableExp bTure = new VariableExp("true");
        VariableExp bFalse = new VariableExp("false");

        context.assign("true", true);
        context.assign("false", false);
        context.assign("X", false);
        context.assign("Y", true);
        
        BooleanExp expression = new AndExp(
            new AndExp(bTure, x),
            new AndExp(y, new NotExp(x))
        );
        boolean result = expression.evaluate(context);
        System.out.println("The result is:" + result);
    }
}

相关文章

  • 设计模式-解析器模式(二十一)

    解析器模式给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。这种模式被用在...

  • 解析器模式 与 免费公交卡

    解析器模式,它能用在什么地方呢? 解析器模式,它是如何解析的? 解析器模式,它有哪些关键要素? 解析器模式(Int...

  • 设计模式专题-解析器设计模式

    问题顾客们在你的机器App或者网页上进行报价。最终的报价包含了2个部分,零件成本和劳动成本。我们希望能够对劳动力部...

  • 设计模式之解析器模式

    解析器模式:给拍一个语言,定义它的文法的一种表示,并定义一个解析器,这个解析器使用该表达来解析语言中的句子。 UM...

  • “领域规则”模式

    “领域规则”模式 解析器模式 模式定义 类图 要点总结

  • Boolan C++设计模式第三周心得笔记

    单件模式 享元模式 状态模式 备忘录 组合模式 迭代器 职责链 命令模式 访问器 解析器 本周作业 本次作业要求针...

  • 前端设计模式

    JS设计模式一:工厂模式jS设计模式二:单例模式JS设计模式三:模块模式JS设计模式四:代理模式JS设计模式五:职...

  • 设计模式 - 目录

    设计模式01 - 单例模式 设计模式02 - 工厂模式 设计模式03 - 建造者模式 设计模式04 - 适配器模式...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • 设计模式笔记汇总

    目录 设计原则 “依赖倒置”原则 未完待续... 设计模式 设计模式——策略模式 设计模式——装饰者模式 设计模式...

网友评论

      本文标题:设计模式-解析器模式(二十一)

      本文链接:https://www.haomeiwen.com/subject/cupgjftx.html