基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
设计模式是什么鬼(解释器)
设计模式是什么鬼(解释器)
阅读
1
2019-01-07
“
Java
知音”,选择“置顶公众号”
技术文章第一时间送达!
//本文作者:凸凹里歐
//本文收录菜单栏:《设计模式是什么鬼》专栏中
解释,一定是针对某种语言的拆解、释意,并按照文法翻译、转换成另一种表达形式以达到目标能够理解的目的。比如我们都知道
Java
编程语言是人类可以理解的语言,程序写好后要先进行编译生成字节码(
class
文件),然后对此文件解释成机器码,最终机器才可以理解并执行,这就是解释器存在的意义。
就拿我们人类的自然语言来举例,比如我们要进行英文翻译工作,首先要对一句话(表达式)进行拆解,而拆开后的单词就成了不可再分的终极表达式,例如说对英语句子“
I
love
you
”(非终极表达式)进行拆解,按空格分割为单词“
I
”、“
love
”、“
you
”(终极表达式),然后翻译每个单词再合并成“我爱你”,貌似很简单的样子。再看句子“
I
love
that
you
love
”,翻译成“我爱你那个你爱”。
这简直太荒谬了,这句明明是“我爱你所爱”的意思,貌似这里的拆解方式是有讲究的。“
that
you
love
”在这里应该是作为从句出现,所以它应该属于一个特殊的“非终极表达式”,有自己独特的翻译方式,而不是简单的单词拼接了。我们意识到语言的翻译绝非易事,但至少我们通过思考搞明白了终极与非终极表达式的区别、表达式的多态性、以及表达式的自包含关系结构。
化繁为简,为了保持例子的简约实用风格,我们决定自己发明一种语言,什么语言呢?对于骨灰级网游玩家来说打怪升级是最漫长的过程,既浪费时间又伤害身体,该怎么解决这个问题呢?有网瘾,电电就好。
开个玩笑,所以呢我们研发了一款挂机程序并起名”耗子精“,它可以直接发送指令给鼠标驱动来实现点击、移动操作,从此解放我们的双手让游戏人物自动打怪升级。既然不操作鼠标,那就需要一段脚本告诉“耗子精”怎样去操作鼠标指针,于是我们发明了一种脚本语言“精神食粮”,像是下面这样:
1BEGIN
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E8
%
84
%
9A
%
E6
%
9C
%
AC
%
E5
%
BC
%
80
%
E5
%
A7
%
8B
%
0A2MOVE
%
20500
,
600
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
E7
%
A7
%
BB
%
E5
%
8A
%
A8
%
E5
%
88
%
B0
%
E5
%
9D
%
90
%
E6
%
A0
%
87
(
500
,%
20600
)%
0A3
%
20
%
20
%
20
%
20BEGIN
%
20LOOP
%
205
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
BC
%
80
%
E5
%
A7
%
8B
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF5
%
E6
%
AC
%
A1
%
0A4
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20LEFT
_
CLICK
;%
20
%
20
//%
20
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E4
%
BD
%
93
%
E5
%
86
%
85
%
E5
%
8D
%
95
%
E5
%
87
%
BB
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A5
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20DELAY
%
201
;%
20
%
20
%
20
%
20
%
20
//%
20
%
E6
%
AF
%
8F
%
E6
%
AC
%
A1
%
E5
%
BB
%
B6
%
E6
%
97
%
B61
%
E7
%
A7
%
92
%
0A6
%
20
%
20
%
20
%
20END
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E4
%
BD
%
93
%
E7
%
BB
%
93
%
E6
%
9D
%
9F
%
0A7RIGHT
_
DOWN
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E5
%
8F
%
B3
%
E9
%
94
%
AE
%
0A8DELAY
%
207200
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
BB
%
B6
%
E6
%
97
%
B62
%
E5
%
B0
%
8F
%
E6
%
97
%
B6
%
0A9END
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E8
%
84
%
9A
%
E6
%
9C
%
AC
%
E7
%
BB
%
93
%
E6
%
9D
%
9F
%
0A
看注释很容易就能理解这是要干什么了,玩家先让鼠标挪动到地图的某个点上,然后不停地点击了
n
次(比如此处简化为
5
次)过后人物便到达了刷怪地点了(计算好延时时间),最后按下右键触发技能并一直不松开,直到挂机
2
小时后结束,这样便实现了自动打怪升级。
我们现在来对这个语言的表达式进行拆解、抽象、建模,可以看到除了循环(非终极表达式)以外其他的都是单个命令不可以拆了,也就是我们之前讲过的终极表达式,按照这个脚本我们先看一张结构图。
可以看到从始发节点“指令序列表达式”(根)开始被拆解成三个分支,第一步和第三步都是执行鼠标动作的终极表达式了(叶),而第二步的“循环”则属于非终极表达式(枝),它的循环体内可以包含多步指令,所以它包括一个子指令集(枝),然后继续往下延续出“左键单击表达式”(枝)和“系统延时表达式”(叶),最后“单击”其实就是“按下”与“松开”的组合了。有没有这个语义树结构好像似曾相识?没错,这就是之前讲过的“组合模式”,我们正是利用了“组合模式”(强调结构型)的结构模型构建了这个语义树(
Syntax
Tree
),来完成我们的翻译工作(这里强调行为型)。
开始写代码,这么多表达式到底应该从哪里开始定义呢?不管三七二十一它们统统都是表达式,先写个表达式总抽象。
1public
%
20interface
%
20Expression
%
20
%
7B
%
20
//%
20
%
E8
%
A1
%
A8
%
E8
%
BE
%
BE
%
E5
%
BC
%
8F
%
E6
%
8E
%
A5
%
E5
%
8F
%
A3
%
0A2
%
20
%
20
%
20
%
20public
%
20void
%
20interpret
();%
20
//%
20
%
E8
%
A7
%
A3
%
E9
%
87
%
8A
%
E6
%
96
%
B9
%
E6
%
B3
%
95
%
0A3
%
7D
%
0A
可以看到这个接口定义了表达式的通用解释方法标准,一切表达式都得符合这个规则。接下来我们先从最基本的原子操作(终极表达式)开始定义实现类,它们应该依次是移动鼠标、左(右)键按下(松开)、系统延时表达式等,雷同的我们不做赘述,读者可以自己实现。
%
201public
%
20class
%
20Move
%
20implements
%
20Expression
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20
//%
20
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
E4
%
BD
%
8D
%
E7
%
BD
%
AE
%
E5
%
9D
%
90
%
E6
%
A0
%
87
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20int
%
20x
,%
20y
;%
0A
%
204
%
0A
%
205
%
20
%
20
%
20
%
20public
%
20Move
(
int
%
20x
,%
20int
%
20y
)%
20
%
7B
%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
x
%
20
=%
20x
;%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
y
%
20
=%
20y
;%
0A
%
208
%
20
%
20
%
20
%
20
%
7D
%
0A
%
209
%
0A10
%
20
%
20
%
20
%
20public
%
20void
%
20interpret
()%
20
%
7B
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E7
%
A7
%
BB
%
E5
%
8A
%
A8
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E3
%
80
%
90
%
22
%
20
%
20x
%
20
%
20
%
22
,%
22
%
20
%
20y
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A12
%
20
%
20
%
20
%
20
%
7D
%
0A13
%
0A14
%
7D
1public
%
20class
%
20LeftDown
%
20implements
%
20Expression
%
20
%
7B
%
0A2
%
0A3
%
20
%
20
%
20
%
20public
%
20void
%
20interpret
()%
20
%
7B
%
0A4
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
22
);%
0A5
%
20
%
20
%
20
%
20
%
7D
%
0A6
%
0A7
%
7D
1public
%
20class
%
20LeftUp
%
20implements
%
20Expression
%
20
%
7B
%
0A2
%
0A3
%
20
%
20
%
20
%
20public
%
20void
%
20interpret
()%
20
%
7B
%
0A4
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E6
%
9D
%
BE
%
E5
%
BC
%
80
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
22
);%
0A5
%
20
%
20
%
20
%
20
%
7D
%
0A6
%
0A7
%
7D
%
201public
%
20class
%
20Delay
%
20implements
%
20Expression
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20int
%
20seconds
;//%
20
%
E5
%
BB
%
B6
%
E6
%
97
%
B6
%
E7
%
A7
%
92
%
E6
%
95
%
B0
%
0A
%
204
%
0A
%
205
%
20
%
20
%
20
%
20public
%
20Delay
(
int
%
20seconds
)%
20
%
7B
%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
seconds
%
20
=%
20seconds
;%
0A
%
207
%
20
%
20
%
20
%
20
%
7D
%
0A
%
208
%
0A
%
209
%
20
%
20
%
20
%
20public
%
20int
%
20getSeconds
()%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20seconds
;%
0A11
%
20
%
20
%
20
%
20
%
7D
%
0A12
%
0A13
%
20
%
20
%
20
%
20public
%
20void
%
20interpret
()%
20
%
7B
%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E7
%
B3
%
BB
%
E7
%
BB
%
9F
%
E5
%
BB
%
B6
%
E8
%
BF
%
9F
%
EF
%
BC
%
9A
%
22
%
20
%
20seconds
%
20
%
20
%
22
%
E7
%
A7
%
92
%
E9
%
92
%
9F
%
22
);%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20try
%
20
%
7B
%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Thread
.
sleep
(
seconds
%
20
*%
201000
);%
0A17
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
20catch
%
20
(
InterruptedException
%
20e
)%
20
%
7B
%
0A18
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20e
.
printStackTrace
();%
0A19
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A20
%
20
%
20
%
20
%
20
%
7D
%
0A21
%
0A22
%
7D
%
0A
很简单,它们都实现了
interpret
方法,并进行了相关操作的模拟。照猫画虎,下来实现非终极表达式:左(右)键单击表达式、循环表达式、以及指令集序列表达式等。
%
201public
%
20class
%
20LeftClick
%
20implements
%
20Expression
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20Expression
%
20leftDown
;%
0A
%
204
%
20
%
20
%
20
%
20private
%
20Expression
%
20leftUp
;%
0A
%
205
%
0A
%
206
%
20
%
20
%
20
%
20public
%
20LeftClick
()%
20
%
7B
%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
leftDown
%
20
=%
20new
%
20LeftDown
();%
0A
%
208
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
leftUp
%
20
=%
20new
%
20LeftUp
();%
0A
%
209
%
20
%
20
%
20
%
20
%
7D
%
0A10
%
0A11
%
20
%
20
%
20
%
20public
%
20void
%
20interpret
()%
20
%
7B
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
E5
%
8D
%
95
%
E5
%
87
%
BB
=%
E5
%
85
%
88
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E5
%
86
%
8D
%
E6
%
9D
%
BE
%
E5
%
BC
%
80
%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20leftDown
.
interpret
();%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20leftUp
.
interpret
();%
0A15
%
20
%
20
%
20
%
20
%
7D
%
0A16
%
0A17
%
7D
%
0A
这里有点意思了,单击表达式被我们继续拆分成“按下”及“松开”两个原子操作,由于点击是个固定的死操作,并不需要提供给客户端任何灵活性把它们传入进来,所以我们在构造时(第
7
行)主动实例化了它们。接下来是循环表达式,我们需要知道循环次数,以及循环体内要执行的表达式。
%
201public
%
20class
%
20Repetition
%
20implements
%
20Expression
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20int
%
20loopCount
;//%
20
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E6
%
AC
%
A1
%
E6
%
95
%
B0
%
0A
%
204
%
20
%
20
%
20
%
20private
%
20Expression
%
20expression
;//%
20
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E4
%
BD
%
93
%
E8
%
A1
%
A8
%
E8
%
BE
%
BE
%
E5
%
BC
%
8F
%
0A
%
205
%
0A
%
206
%
20
%
20
%
20
%
20public
%
20Repetition
(
Expression
%
20expression
,%
20int
%
20loopCount
)%
20
%
7B
%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
expression
%
20
=%
20expression
;%
0A
%
208
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
loopCount
%
20
=%
20loopCount
;%
0A
%
209
%
20
%
20
%
20
%
20
%
7D
%
0A10
%
0A11
%
20
%
20
%
20
%
20public
%
20void
%
20interpret
()%
20
%
7B
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20while
%
20
(
loopCount
%
20
&
gt
;%
200
)%
20
%
7B
%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20expression
.
interpret
();%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20loopCount
--;%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A16
%
20
%
20
%
20
%
20
%
7D
%
0A17
%
0A18
%
7D
%
0A
清晰明了,循环表达式被初始化后用这些参数进行循环、并调用循环体表达式的解释方法,继续向下传递,至于这个表达式里具体还有什么子表达式我们根本不关心,这里主要负责循环调用,仅此而已。最后就是指令集序列表达式的实现了。
%
201public
%
20class
%
20Sequence
%
20implements
%
20Expression
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20
//%
20
%
E6
%
8C
%
87
%
E4
%
BB
%
A4
%
E9
%
9B
%
86
%
E5
%
BA
%
8F
%
E5
%
88
%
97
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20List
&
lt
;
Expression
&
gt
;%
20expressions
;%
0A
%
204
%
0A
%
205
%
20
%
20
%
20
%
20public
%
20Sequence
(
List
&
lt
;
Expression
&
gt
;%
20expressions
)%
20
%
7B
%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
expressions
%
20
=%
20expressions
;%
0A
%
207
%
20
%
20
%
20
%
20
%
7D
%
0A
%
208
%
0A
%
209
%
20
%
20
%
20
%
20public
%
20void
%
20interpret
()%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E6
%
8C
%
A8
%
E4
%
B8
%
AA
%
E8
%
A7
%
A3
%
E6
%
9E
%
90
%
E6
%
AF
%
8F
%
E6
%
9D
%
A1
%
E6
%
8C
%
87
%
E4
%
BB
%
A4
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20expressions
.
forEach
(
exp
%
20
-&
gt
;%
20exp
.
interpret
());%
0A12
%
20
%
20
%
20
%
20
%
7D
%
0A13
%
0A14
%
7D
%
0A
我们要运行的脚本一定是有先后顺序的,所以这个指令集表达式里包含一个
List
&
lt
;
Expression
&
gt
;,在构造时(第
5
行)由客户端传入,并于第
11
行挨个顺序调用解释方法。貌似脚本用到的表达式已经定义完毕,客户端开始调用。
%
201public
%
20class
%
20Client
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20public
%
20static
%
20void
%
20main
(
String
%
5B
%
5D
%
20args
)%
20
%
7B
%
0A
%
203
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/*%
0A
%
204
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20BEGIN
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E8
%
84
%
9A
%
E6
%
9C
%
AC
%
E5
%
BC
%
80
%
E5
%
A7
%
8B
%
0A
%
205
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20MOVE
%
20500
,
600
;%
20
%
20
%
20
%
20
%
20
//%
20
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
E7
%
A7
%
BB
%
E5
%
8A
%
A8
%
E5
%
88
%
B0
%
E5
%
9D
%
90
%
E6
%
A0
%
87
(
500
,%
20600
)%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20
%
20BEGIN
%
20LOOP
%
205
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
BC
%
80
%
E5
%
A7
%
8B
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF5
%
E6
%
AC
%
A1
%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20
%
20
%
20
%
20
%
20
%
20LEFT
_
CLICK
;%
20
%
20
//%
20
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E4
%
BD
%
93
%
E5
%
86
%
85
%
E5
%
8D
%
95
%
E5
%
87
%
BB
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A
%
208
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20
%
20
%
20
%
20
%
20
%
20DELAY
%
201
;%
20
%
20
%
20
%
20
%
20
//%
20
%
E6
%
AF
%
8F
%
E6
%
AC
%
A1
%
E5
%
BB
%
B6
%
E6
%
97
%
B61
%
E7
%
A7
%
92
%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20
%
20END
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E4
%
BD
%
93
%
E7
%
BB
%
93
%
E6
%
9D
%
9F
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20RIGHT
_
DOWN
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E5
%
8F
%
B3
%
E9
%
94
%
AE
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20DELAY
%
207200
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
BB
%
B6
%
E6
%
97
%
B62
%
E5
%
B0
%
8F
%
E6
%
97
%
B6
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*%
20END
;%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E8
%
84
%
9A
%
E6
%
9C
%
AC
%
E7
%
BB
%
93
%
E6
%
9D
%
9F
%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*/%
0A14
%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E6
%
9E
%
84
%
E9
%
80
%
A0
%
E6
%
8C
%
87
%
E4
%
BB
%
A4
%
E9
%
9B
%
86
%
E8
%
AF
%
AD
%
E4
%
B9
%
89
%
E6
%
A0
%
91
%
EF
%
BC
%
8C
%
E5
%
AE
%
9E
%
E9
%
99
%
85
%
E6
%
83
%
85
%
E5
%
86
%
B5
%
E4
%
BC
%
9A
%
E4
%
BA
%
A4
%
E7
%
BB
%
99
%
E8
%
AF
%
AD
%
E6
%
B3
%
95
%
E8
%
A7
%
A3
%
E6
%
9E
%
90
%
E5
%
99
%
A8
%
EF
%
BC
%
88Evaluator
%
20or
%
20Parser
%
EF
%
BC
%
89
%
E3
%
80
%
82
%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Expression
%
20sequence
%
20
=%
20new
%
20Sequence
(
Arrays
.
asList
(%
0A17
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20new
%
20Move
(
500
,%
20600
),%
20
%
0A18
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20new
%
20Repetition
(%
0A19
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20new
%
20Sequence
(%
0A20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Arrays
.
asList
(
new
%
20LeftClick
(),%
20
%
0A21
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20new
%
20Delay
(
1
))%
0A22
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
),%
0A23
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
205
%
0A24
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
),%
20
%
0A25
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20new
%
20RightDown
(),%
0A26
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20new
%
20Delay
(
7200
)%
0A27
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
));%
0A28
%
0A29
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20sequence
.
interpret
();%
0A30
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/*%
E6
%
89
%
93
%
E5
%
8D
%
B0
%
E8
%
BE
%
93
%
E5
%
87
%
BA
%
0A31
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
A7
%
BB
%
E5
%
8A
%
A8
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E3
%
80
%
90500
,
600
%
E3
%
80
%
91
%
0A32
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A33
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
9D
%
BE
%
E5
%
BC
%
80
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A34
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
B3
%
BB
%
E7
%
BB
%
9F
%
E5
%
BB
%
B6
%
E8
%
BF
%
9F
%
EF
%
BC
%
9A1
%
E7
%
A7
%
92
%
E9
%
92
%
9F
%
0A35
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A36
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
9D
%
BE
%
E5
%
BC
%
80
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A37
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
B3
%
BB
%
E7
%
BB
%
9F
%
E5
%
BB
%
B6
%
E8
%
BF
%
9F
%
EF
%
BC
%
9A1
%
E7
%
A7
%
92
%
E9
%
92
%
9F
%
0A38
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A39
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
9D
%
BE
%
E5
%
BC
%
80
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A40
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
B3
%
BB
%
E7
%
BB
%
9F
%
E5
%
BB
%
B6
%
E8
%
BF
%
9F
%
EF
%
BC
%
9A1
%
E7
%
A7
%
92
%
E9
%
92
%
9F
%
0A41
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A42
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
9D
%
BE
%
E5
%
BC
%
80
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A43
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
B3
%
BB
%
E7
%
BB
%
9F
%
E5
%
BB
%
B6
%
E8
%
BF
%
9F
%
EF
%
BC
%
9A1
%
E7
%
A7
%
92
%
E9
%
92
%
9F
%
0A44
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A45
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
9D
%
BE
%
E5
%
BC
%
80
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
B7
%
A6
%
E9
%
94
%
AE
%
0A46
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
B3
%
BB
%
E7
%
BB
%
9F
%
E5
%
BB
%
B6
%
E8
%
BF
%
9F
%
EF
%
BC
%
9A1
%
E7
%
A7
%
92
%
E9
%
92
%
9F
%
0A47
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
8C
%
89
%
E4
%
B8
%
8B
%
E9
%
BC
%
A0
%
E6
%
A0
%
87
%
EF
%
BC
%
9A
%
E5
%
8F
%
B3
%
E9
%
94
%
AE
%
0A48
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
B3
%
BB
%
E7
%
BB
%
9F
%
E5
%
BB
%
B6
%
E8
%
BF
%
9F
%
EF
%
BC
%
9A7200
%
E7
%
A7
%
92
%
E9
%
92
%
9F
%
0A49
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*/%
0A50
%
20
%
20
%
20
%
20
%
7D
%
0A51
%
7D
%
0A
注意看第
16
行,仔细参照注释中的脚本并实例化我们的语义树结构,最后只需调用根节点的
interpret
()方法即可完成整个解释工作。其实对于这个脚本转语义树的工作我们完全可以自己实现一个
Evaluator
来分析这段脚本并生成语义树(类似于编译的过程),由于这并不属于解释器模式的范畴,所以我们就不混淆进来了,这里我们留给读者朋友自己实现。
终于,“耗子精”有了脚本识别的能力,并顺利对接鼠标驱动,帮我们自动完成升级,玩家再也不用没日没夜地做那些无聊至极的重复动作了,并且后期如果需要更多的功能还可以对表达式继续进行扩展(比如对键盘指令的解释),我们只需优雅地植入语义树即可,就这么简单。正是因为我们对语言的语法解析、表达式抽象化,关系结构化,使得让翻译工作变得即插即用,解释器模式不但提高了代码的易读性、易用性、可维护性,更重要的是对未来语言变化的可扩展性。
语言是可以拆解的,句子是可以包括从句(子句)或单词的,单词是具有终极原子性的,它们统统重复出现。
干货!必须好看☟
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
面试官:说说为什么HTTPS是安全的
下一篇:
什么鬼?(终章)
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目