-- 解释器模式(interpreter)官方解释: 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
新手表示看不懂
~ ~ 大概就是类似<翻译机>,给定一个语言<英文>,定义一个文法<Context>,并定义<英文转中文>解释器,这个解释器会解释语言中的句子。下面有该栗子~
一、用途场景
- 可用场景比较少,好像有被用在 SQL 解析、符号处理引擎等。
二、模式结构
官方结构图:
组成(角色) | 作用 |
---|---|
Context | 存储 语法和即将被翻译的句子 |
AbstractExpression | 提供抽象的解释方法 |
TerminalExpression (终止表达式) | 解释器具体实现类 |
NonterminalExpression (非终止表达式) | 持有对另一个解释器的引用 |
TerminalExpression(终结符表达式): 只用对句子用文法解释一次 (比如: 英文->中文)
NonterminalExpression (非终终结符表达式): 由于含有对别的解释器的引用,“非终止”顾名思义,还得进一步解释翻译(推导)。
(比如:外星文->英文->中文)
终结符: 通俗的说就是不能单独出现在推导式左边的符号,也就是说终结符不能再进行推导。
非终结符: 可理解为一个可拆分元素,可进一步推导。
编译原理 - 终结符与非终结符传送门:
- https://blog.csdn.net/leohels/article/details/7534685
- https://blog.csdn.net/chenxu6/article/details/46490689
但解释器模式是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