今天覆習設計模式看到解釋器模式。想到之前我碰到過的一個問題。
問題:前後端多條件的解析。
例:某字符串token開始於“a” 且包含“b” 或長度等於10
之前是通過三方的組件解決的。如果要自己實現一個可擴展、易交互的方案。之前沒想到什麼好辦法。
其實可以用解釋器模式封裝兩層來解決。
但我的解釋器示例以另一個更簡單的例子做一個舉例。上面的僅是一個思考。
問題:波蘭表示法。運算符末尾添加操作數的方式
例:1 2 + 代表1+2的運算。 3 4 + 5 - 6 + 代表3+4-5+6的運算
解釋器一般有幾部分組成。
1、Context(環境):封裝解釋器的全局信息,所有具體的解釋器都需訪問Context.
2、AbstractExpression(抽象表達式):一個抽象類或接口。聲明執行的解釋方法,由所有具體的解釋器實現。
3、TerminalExpression(終結符表達式)。一種解釋器類,實現與語法終結符相關的操作。終結符表達式必須被實現或示例化,因爲它表示表達式的結尾
4、NonTerminalExpression(非終結符表達式):實現語法的不同規則或符號的類。每一個語法都應該創建一個類。
實現代碼示例:
1、表達式接口:
/**
* 表達式接口
*/
public interface Expression {
public float interpret();
}
2、終結符表達式。(在本例中爲數值)
/**
* 數值表達式
*/
public class NumberExpression implements Expression{
private float number;
public NumberExpression(float number){
this.number = number;
}
@Override
public float interpret() {
return number;
}
}
3、非終結符表達式。本例中以加法、減法兩個規則爲例
/**
* 操作符解釋器:加法
*/
public class PlusExpression implements Expression{
Expression left;
Expression right;
public PlusExpression(Expression left, Expression right){
this.left = left;
this.right = right;
}
@Override
public float interpret() {
return this.left.interpret() + this.right.interpret();
}
}
/**
* 操作符解釋器:減法
*/
public class MinusExpression implements Expression{
Expression left;
Expression right;
public MinusExpression(Expression left, Expression right){
this.left = left;
this.right = right;
}
@Override
public float interpret() {
return this.left.interpret() - this.right.interpret();
}
}
4、寫一段代碼通過建立好的類來實現語法樹。
/**
* 通過解釋器類實現語法樹
*/
public class Evaluator {
public float evaluator(String expression){
Stack<Expression> stack = new Stack<>();
float result = 0;
for (String token : expression.split(" ")){
if(isOperator(token)){
Expression exp = null;
if(token.equals("+")){
exp = stack.push(new PlusExpression(stack.pop(), stack.pop()));
}else if(token.equals("-")){
exp = stack.push(new MinusExpression(stack.pop(),stack.pop()));
}
if(exp != null){
result = exp.interpret();
stack.push(new NumberExpression(result));
}
}
if(isNumber(token)){
stack.push(new NumberExpression(Float.parseFloat(token)));
}
}
return result;
}
private boolean isOperator(String token){
if(token.equals("+") || token.equals("-"))
return true;
return false;
}
private boolean isNumber(String token){
try {
float v = Float.parseFloat(token);
return true;
}catch (Exception e){
return false;
}
}
public static void main(String[] args) {
Evaluator evaluator = new Evaluator();
System.out.println(evaluator.evaluator("2 3 +"));
System.out.println(evaluator.evaluator("2 3 + 5 - 6 +"));
}
}
一個簡單的解釋器模式代碼完成了。