設(shè)計(jì)模式-解析器模式(二十一)

解析器模式
給定一個(gè)語(yǔ)言,定義它的文法表示,并定義一個(gè)解釋器,這個(gè)解釋器使用該標(biāo)識(shí)來(lái)解釋語(yǔ)言中的句子。
這種模式被用在 SQL 解析、符號(hào)處理引擎等。

Jsoup這個(gè)源碼里面用到,代碼簡(jiǎn)單,功能狠強(qiáng)大.

可利用場(chǎng)景比較少,JAVA 中如果碰到可以用 expression4J 代替。

  • 上類(lèi)圖:
解析器模式.png
  • 代碼示例:
  1. 創(chuàng)建表達(dá)式接口
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. 創(chuàng)建一個(gè)終結(jié)符表達(dá)式
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. 創(chuàng)建非終結(jié)符表達(dá)式
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. 環(huán)境角色
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);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 場(chǎng)景問(wèn)題# 1.1 讀取配置文件## 考慮這樣一個(gè)實(shí)際的應(yīng)用,維護(hù)系統(tǒng)自定義的配置文件。 幾乎每個(gè)實(shí)際的應(yīng)用系...
    七寸知架構(gòu)閱讀 3,259評(píng)論 2 56
  • 【學(xué)習(xí)難度:★★★★★,使用頻率:★☆☆☆☆】直接出處:解釋器模式梳理和學(xué)習(xí):https://github.com...
    BruceOuyang閱讀 724評(píng)論 0 2
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,562評(píng)論 19 139
  • 1. 介紹 瀏覽器可能是最廣泛使用的軟件。本書(shū)將介紹瀏覽器的工作原理。我們將看到,當(dāng)你在地址欄中輸入google....
    康斌閱讀 2,162評(píng)論 7 18
  • “最美不過(guò)是童心”,——發(fā)出如此感慨,源于我所作的一節(jié)課。 接到學(xué)校任務(wù),要作一節(jié)群文閱讀課,閱讀教材已上完的我為...
    青風(fēng)竹韻閱讀 814評(píng)論 6 6

友情鏈接更多精彩內(nèi)容