diff --git a/README.md b/README.md index 233e91bbb78741e7f0db37629e280db35e24e271..70b05fcf5aeada9cb3c66ff26b8c98cf9a720d6f 100644 --- a/README.md +++ b/README.md @@ -344,6 +344,74 @@ * 系统需要在不同的时间指定请求、将请求排队和执行请求。 * 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。 +# 解释器模式 +## 定义 +解释器模式使用频率不算高,通常用来描述如何构建一个简单“语言”的语法解释器。它只在一些非常特定的领域被用到,比如编译器、规则引擎、正则表达式、SQL 解析等。不过,了解它的实现原理同样很重要,能帮助你思考如何通过更简洁的规则来表示复杂的逻辑。 + +**解释器模式(Interpreter pattern)的原始定义是:用于定义语言的语法规则表示,并提供解释器来处理句子中的语法。** + +我们通过一个例子给大家解释一下解释器模式 + +- 假设我们设计一个软件用来进行加减计算。我们第一想法就是使用工具类,提供对应的加法和减法的工具方法。 + +```java +//用于两个整数相加的方法 +public static int add(int a , int b){ + return a + b; +} + +//用于三个整数相加的方法 +public static int add(int a , int b,int c){ + return a + b + c; +} + +public static int add(Integer ... arr){ + int sum = 0; + for(Integer num : arr){ + sum += num; + } + return sum; +} + ++ - +``` + +上面的形式比较单一、有限,如果形式变化非常多,这就不符合要求,因为加法和减法运算,两个运算符与数值可以有无限种组合方式。比如: 5-3+2-1, 10-5+20.... + +**文法规则和抽象语法树** + +解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子. + +在上面提到的加法/减法解释器中,每一个输入表达式(比如:2+3+4-5) 都包含了3个语言单位,可以使用下面的文法规则定义: + +文法是用于描述语言的语法结构的形式规则。 + +``` +expression ::= value | plus | minus +plus ::= expression ‘+’ expression +minus ::= expression ‘-’ expression +value ::= integer +``` + +> 注意: 这里的符号“::=”表示“定义为”的意思,竖线 | 表示或,左右的其中一个,引号内为字符本身,引号外为语法。 + +上面规则描述为 : + +表达式可以是一个值,也可以是plus或者minus运算,而plus和minus又是由表达式结合运算符构成,值的类型为整型数。 + +**抽象语法树:** + +在解释器模式中还可以通过一种称为抽象语法树的图形方式来直观的表示语言的构成,每一棵抽象语法树对应一个语言实例,例如加法/减法表达式语言中的语句 " 1+ 2 + 3 - 4 + 1" 可以通过下面的抽象语法树表示 + +## 原理图 +![img.png](img/img_interprter_pattern_priciple01.png) +解释器模式包含以下主要角色。 + +* 抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。 +* 终结符表达式(Terminal Expression)角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。上例中的value 是终结符表达式. +* 非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。上例中的 plus , minus 都是非终结符表达式 +* 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。 +* 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。 1. 使用 Readme.md 来支持不同的语言, Readme\_en.md: 支持英文, Readme\_zh.md: 支持中文 diff --git a/img/img_interprter_pattern_priciple01.png b/img/img_interprter_pattern_priciple01.png new file mode 100644 index 0000000000000000000000000000000000000000..0f17ecd35f4a889fe3d4b61d3a15672c2ec46944 Binary files /dev/null and b/img/img_interprter_pattern_priciple01.png differ diff --git a/img/img_interprter_pattern_principle.png b/img/img_interprter_pattern_principle.png new file mode 100644 index 0000000000000000000000000000000000000000..5ed5a4de8a56c82291ea159ad993af50bf29fd0c Binary files /dev/null and b/img/img_interprter_pattern_principle.png differ