Java設計模式15:解釋器模式(Interpreter)

解釋器模式

意圖

給定一個語言,定義他的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子

動機

目前計算機編程語言有好幾百種,但有時候我們還是希望能用一些簡單的語言來實現一些特定的操作,我們只要向計算機輸入一個句子或文件,它就能夠按照預先定義的文法規則來對句子或文件進行解釋,從而實現相應的功能。例如當輸入字符串表達式爲“1 + 2 + 3 ”時,將輸出計算結果爲6

適用性

1、可以將一個需要解釋執行的語言中的句子表示爲一個抽象語法樹

2、一些重複出現的問題可以用一種簡單的語言來進行表達。

3、一個語言的文法較爲簡單。

4、執行效率不是關鍵問題。

結構

這裏寫圖片描述

AbstractExpression

聲明一個抽象的解釋操作,這個接口爲抽象語法樹中所有節點共享

TerminalExpression

實現與文法中的終結符相關聯的解釋操作

一個橘子中的每個終結符需要該類的一個實例

NonterminalExpression

對文法中每一條規則都需要一個這樣的類

Context

包含解釋器之外的一些全局信息

實現

實現一個輸入類似“4*8/9%2”類似的表達式,輸出對應的結果

package interpreter;

/**
 * @Author fitz.bai
 * @Date 2018/9/4 18:45
 * 抽象表達式
 */
public interface Node {
    int interpret();
}

package interpreter;

/**
 * @Author fitz.bai
 * @Date 2018/9/4 18:48
 * 非終結表達式
 */
public class ValueNode implements Node {
    private int value;

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

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

package interpreter;

/**
 * @Author fitz.bai
 * @Date 2018/9/4 18:49
 * 終結表達式抽象類,由於該終結表達式需要解釋多個運算符號,同時用來構建抽象語法樹
 */
public abstract class SymbolNode implements Node {
    protected Node left;
    protected Node right;

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

}
package interpreter;


/**
 * @Author fitz.bai
 * @Date 2018/9/4 18:51
 */
public class MulNode extends SymbolNode {
    public MulNode(Node left, Node right) {
        super(left, right);
    }

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


/**
 * @Author fitz.bai
 * @Date 2018/9/4 18:51
 */
public class ModNode extends SymbolNode {
    public ModNode(Node left, Node right) {
        super(left, right);
    }

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


/**
 * @Author fitz.bai
 * @Date 2018/9/4 18:51
 */
public class DivNode extends SymbolNode {
    public DivNode(Node left, Node right) {
        super(left, right);
    }

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

import java.util.Stack;

/**
 * @Author fitz.bai
 * @Date 2018/9/4 18:52
 */
public class Calculator {
    private String statement;
    private Node node;

    public void build(String statement) {
        Node left, right;
        Stack stack = new Stack();

        String[] statementArr = statement.split(" ");

        for (int i = 0; i < statementArr.length; i++) {
            if (statementArr[i].equalsIgnoreCase("*")) {
                left = (Node) stack.pop();
                int val = Integer.parseInt(statementArr[++i]);
                right = new ValueNode(val);
                stack.push(new MulNode(left, right));
            } else if (statementArr[i].equalsIgnoreCase("/")) {
                left = (Node) stack.pop();
                int val = Integer.parseInt(statementArr[++i]);
                right = new ValueNode(val);
                stack.push(new DivNode(left, right));
            } else if (statementArr[i].equalsIgnoreCase("%")) {
                left = (Node) stack.pop();
                int val = Integer.parseInt(statementArr[++i]);
                right = new ValueNode(val);
                stack.push(new ModNode(left, right));
            } else {
                stack.push(new ValueNode(Integer.parseInt(statementArr[i])));
            }
        }
        this.node = (Node) stack.pop();
    }

    public int compute() {
        return node.interpret();
    }
}
package interpreter;

/**
 * @Author fitz.bai
 * @Date 2018/9/4 18:45
 */
public class Client {
    public static void main(String[] args) {
        String statement = "3 * 5 / 2 % 2";
        Calculator calculator = new Calculator();
        calculator.build(statement);
        int result = calculator.compute();
        System.out.println(result);
    }
}

####優點

1、 擴展性比較好,靈活

2、 增加新的解釋表達式方便。

3、 易於實現文法

缺點

​1、 執行效率比較低,可利用場景比較少。

2、 對於複雜的文法比較難維護。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章