Interperter 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。如正则表达式的解析。
Interperter 解释器模式,适用于当一个语言需要解释执行时,并且你可以将该语言中的句子表示为一个抽象语法树时,可使用解释器模式:
1.该文法简单。对于复杂的文法,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。
2.效率不是一个关键问题。最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下,转换器仍可用解释器模式实现,该模式仍是有用的。
Interperter 的通用结构图如下:
参与者:
AbstractExpression:声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
TerminalExpression(终结符表达式):实现与文法中的终结符相关联的解释操作。一个句子中的每个终结符需要该类的一个实例。
NonterminalExpression(非终结符表达式):对文法中的每一条规则 R::R1R2…Rn都需要一个 NonterminalExpression 类。为从 R1 到 Rn 的每个符号都维护一个 AbstractExpression 类型的实例变量。为文法中的非终结符实现解释(Interpreter)操作。解释(Interpreter)一般要递归地调用表示 R1 到 Rn 的那些对象的解释操作。
Context(上下文):包含解释器之外的一些全局信息。
Client:构建(或被给定)表示该文法定义的语言中一个特定的句子的抽象语法树。该抽象语法树由 NontermnalExpression 和 TerminalExpression 的实例装配而成。调用解释操作。
Client 构建(或被给定)一个句子,它是 NonterminalExpression 和 TerminalExpression 的实例的一个抽象语法树,然后初始化上下文并调用解释操作。每一个非终结符表达式节点定义相应子表达式的解释操作。而各终结符表达式的解释操作构成了递归的基础。每一节点的解释操作用于上下文存储和访问解释器的状态。
1: //Context.h
2: #pragma once
3:
4: class Context
5: {
6: public:
7: Context(){ }
8: ~Context(){ };
9:
10: //上下文信息
11: //...
12:
13: };
14:
1: //Interpret.h
2: #pragma once
3:
4: #include
5: #include <string>
6:
7: class AbstractExpression
8: {
9: public:
10: virtual ~AbstractExpression(){ };
11: virtual void Interpret(const Context& c){ };
12: protected:
13: AbstractExpression(){ };
14: };
15: class TerminalExpression : public AbstractExpression
16: {
17: public:
18: TerminalExpression(const std::string& statement)
19: {
20: _statement = statement;
21: }
22: ~TerminalExpression(){ }
23: void Interpret(const Context& c)
24: {
25: std::cout << _statement << " TerminalExpression." << std::endl;
26: }
27: private:
28: std::string _statement;
29: };
30: class NonterminalExpression : public AbstractExpression
31: {
32: public:
33: NonterminalExpression(AbstractExpression* expression,int times)
34: {
35: _expression = expression;
36: _times = times;
37: }
38: ~NonterminalExpression(){ }
39:
40: void Interpret(const Context& c)
41: {
42: for (int i = 0; i < _times ; i++)
43: {
44: _expression->Interpret(c);
45: }
46: }
47: private:
48: AbstractExpression* _expression;
49: int _times;
50: };
1: //test.cpp
2:
3: #include "Context.h"
4: #include "Interpreter.h"
5: #include
6:
7: int main()
8: {
9: Context* context = new Context();
10: AbstractExpression* terminal = new TerminalExpression("hello");
11: AbstractExpression* nonterminal = new NonterminalExpression(terminal, 2);
12:
13: terminal->Interpret(*context);
14: nonterminal->Interpret(*context);
15:
16: return EXIT_SUCCESS;
17: }