首先介紹一下解釋器模式適合解決哪類問題。
其實,解釋器模式需要解決的問題是,如果一種特定類型的問題發生的頻率足夠高,那麼可能就值得將該問題的各個實例表述爲一個簡單語言的句子。這樣就可以構建一個解釋器,該解釋器通過解釋這些句子來解決該問題。
就應用的例子來說,例如正則表達式就是它的一種具體應用,解釋器可以爲正則表示定義一個文法,如何表示一個特定的正則表達式,以及如何解釋這個正則表達式。
下面給出解釋器模式的定義。
解釋器模式 (interpreter),給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
解釋器模式的類結構圖如下。
圖中的結構也比較好理解,解釋器方法抽象出一個統一的接口(AbstractExpression),於需要解釋的內容(Context)做了解耦,調用時爲具體的解釋器方法傳入內容(Context)從而實現相應的解釋功能。
那麼解釋器模式有什麼好處呢?
其實用瞭解釋器模式,就意味着可以很容易地改變和擴展文法,因爲該模式使用類來表示文法規則,你可以使用繼承來改變或擴展該文法。也比較容易實現文法,因爲定義抽象語法樹中各個節點的類的實現大體類似,這些類都易於直接編寫。
那麼除了之前提到的正則表達式這種應用之外,其實用處還是很廣的,當然了主要還是對文本的解釋。
除了好處,其實解釋器模式還是有不足的,解釋器模式爲文法中的每一條規則至少定義了一個類,因此包含許多規則的文法可能難以管理和維護。建議當文法非常複雜時,使用其他的技術如語法分析程序或編譯器生成器來處理。
說了不少,下面用代碼簡單展示一下解釋器模式的具體實現。
==============================================
-
Context類接口
1
2
3
4
5
6
|
#import
<Foundation/Foundation.h> @interface
Context : NSObject @property
NSString
*Input; @property
NSString
*Output; @end |
-
Context類實現
1
2
3
4
5
|
#import
"Context.h" @implementation
Context @synthesize
Input,Output; @end |
-
AbstractExpression類接口
1
2
3
4
5
6
|
#import
<Foundation/Foundation.h> @class
Context; @interface
AbstractExpression: NSObject -( void )Interpret:(Context*)context; @end |
-
AbstractExpression類實現
1
2
3
4
5
6
7
|
#import
"AbstractExpression.h" @implementation
AbstractExpression -( void )Interpret:(Context
*)context{ return ; } @end |
-
TerminalExpression類接口
1
2
3
4
|
#import
"AbstractExpression.h" @interface
TerminalExpression :AbstractExpression @end |
-
TerminalExpression類實現
1
2
3
4
5
6
7
|
#import
"TerminalExpression.h" @implementation
TerminalExpression -( void )Interpret:(Context
*)context{ NSLog (@ "終端解釋器" ); } @end |
-
NonterminalExpression類接口
1
2
3
4
|
#import
"AbstractExpression.h" @interface
NonterminalExpression:AbstractExpression @end |
-
NonterminalExpression類實現
1
2
3
4
5
6
7
|
#import
"NonterminalExpression.h" @implementation
NonterminalExpression -( void )Interpret:(Context
*)context{ NSLog (@ "非終端解釋器" ); } @end |
-
Main方法調用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#import
<Foundation/Foundation.h> #import
"Context.h" #import
"TerminalExpression.h" #import
"NonterminalExpression.h" int
main ( int
argc, const
char
* argv[]) { @autoreleasepool { Context
*context = [[Contextalloc]init]; NSMutableArray *list
= [[ NSMutableArrayalloc ]init]; [list
addObject:[[TerminalExpressionalloc]init]]; [list
addObject:[[NonterminalExpressionalloc]init]]; [list
addObject:[[TerminalExpressionalloc]init]]; [list
addObject:[[TerminalExpressionalloc]init]]; for
(AbstractExpression *exp in list) { [exp
Interpret:context]; } } return
0; } |