Java - 解释器模式

-- 解释器模式(interpreter)官方解释: 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

新手表示看不懂

~ ~ 大概就是类似<翻译机>,给定一个语言<英文>,定义一个文法<Context>,并定义<英文转中文>解释器,这个解释器会解释语言中的句子。下面有该栗子~

一、用途场景

  • 可用场景比较少,好像有被用在 SQL 解析、符号处理引擎等。

二、模式结构

官方结构图:

组成(角色) 作用
Context 存储 语法和即将被翻译的句子
AbstractExpression 提供抽象的解释方法
TerminalExpression (终止表达式) 解释器具体实现类
NonterminalExpression (非终止表达式) 持有对另一个解释器的引用

TerminalExpression(终结符表达式): 只用对句子用文法解释一次 (比如: 英文->中文)

NonterminalExpression (非终终结符表达式): 由于含有对别的解释器的引用,“非终止”顾名思义,还得进一步解释翻译(推导)。

(比如:外星文->英文->中文)

终结符: 通俗的说就是不能单独出现在推导式左边的符号,也就是说终结符不能再进行推导。

非终结符: 可理解为一个可拆分元素,可进一步推导。

编译原理 - 终结符与非终结符传送门: 

但解释器模式是23种设计模式之一,是种设计思想,我们不一定非得用在终结符和非终结符身上

三、简单易懂栗子 <英文翻译中文>

1、Context - 存储语法和即将被翻译的句子

package com.behavior.interpreter;


import java.util.HashMap;
import java.util.Map;

/**
 * @description: 文法
 * @author: ziHeng
 * @create: 2018-08-11 11:56
 **/
public class Context {

    //语法
    private Map<String,String> grammar;

    //句子
    private String sentence;


    public Context(String sentence) {
        grammar = new HashMap<>();
        this.sentence= sentence;
    }

    public void addWord(String english,String chinese){
        grammar.put(english,chinese);
    }

    public String getWord(String english,String chinese){
        return grammar.get(english);
    }

    /*
    * 以下为get/set方法
    */
    public Map<String, String> getGrammar() {
        return grammar;
    }

    public void setGrammar(Map<String, String> grammar) {
        this.grammar = grammar;
    }

    public String getSentence() {
        return sentence;
    }

    public void setSentence(String sentence) {
        this.sentence = sentence;
    }
}

2、AbstractExpression - 抽象表达式

package com.behavior.interpreter;

public interface AbstractExpression {


    String interpreterContext(Context context);


}

3、TerminalExpression - 终止符表达式 翻译器

package com.behavior.interpreter;

import java.util.Iterator;
import java.util.Map;

/**
 * @description: 终结符指示器 - 翻译器
 * @author: ziHeng
 * @create: 2018-08-11 11:53
 **/
public class TerminalExpression implements AbstractExpression{

    @Override
    public String interpreterContext(Context context) {

        //句子
        String sentence = context.getSentence();
        //语法
        Map<String, String> grammar = context.getGrammar();

        //开始翻译
        Iterator<Map.Entry<String, String>> iterator = grammar.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, String> next = iterator.next();
            //句子根据语法翻译
            sentence=sentence.replace(next.getKey(),next.getValue());
        }

        return sentence;


    }

}

调用Test:

package com.behavior.interpreter;

/**
 * @description: 解释器测试
 * @author: ziHeng
 * @create: 2018-08-11 12:15
 **/
public class InterpreterTest {

    public static void main(String[] args) {
        //将翻译的句子
        String sentence = "I like GuangZhou and banana";
        Context context = new Context(sentence);

        //文法设置
        context.addWord("banana","香蕉");
        context.addWord("interpreter","解释器");
        context.addWord("GuangZhou","广州");
        
        //定义翻译机
        AbstractExpression terminalExpression = new TerminalExpression();

        //获得翻译结果
        String result = terminalExpression.interpreterContext(context);
        System.out.println(result);
    }

}

非终结符表达式(含有其它解释器的引用)的实现也是差不多的,只是进一步引用其它解释器(翻译器)进行推导。

package com.behavior.interpreter;

/**
 * @description: 非终结符指示器
 * @author: ziHeng
 * @create: 2018-08-11 11:55
 **/
public class NonInterpreterExpression implements AbstractExpression{

    //另一个解释器
    private AbstractExpression anotherExpression;

    public NonInterpreterExpression(AbstractExpression anotherExpression) {
        this.anotherExpression = anotherExpression;
    }

    @Override
    public String interpreterContext(Context context) {
        
        return null;
    }
}

Java: 如果真要对终结符和非终结符(数学表达式)进行解析推导,现有现成的框架(Expression4J)。

数学表达式介绍传送门:https://blog.csdn.net/lovelion/article/details/7713644

猜你喜欢

转载自blog.csdn.net/weixin_39569611/article/details/81570287
今日推荐