首页 > 代码库 > Interpreter - 解释器模式

Interpreter - 解释器模式

定义
给定一个语言, 定于它的文法,并定义一个解释器,这个解释器使用改表示来解释语言中的句子。

类型
行为型模式

案例
像非常熟知的正则表达式就是描述字符串模式的一种标准语言,它为每一个模式都构造了一个特定的算法。


AbstractExpression - 一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
TerminalExpression - 终结符表达式,实现与文法中的终结符相关联的解释操作。
NonterminalExpression - 非终结符表达式,对文法中每一条规则R1R2...Rn都需要一个NonterminalExpressoin。
Context - 上下文,包含解释器之外的一些全局信息。

比如现在有一些表达式:
  1. PRINT MyLanguage: NEXTLINE 
  2. LOOP
  3. PRINT Hello SPACE
  4. PRINT world! NEXTLINE 
  5. BREAK 
  6. END
要解释这些语句,我们先用Context把他们分成一个一个的单词,然后通过IteratorExpression遍历这个Context得到每一个字符,然后调用具体的解释器进行解释,比如LoopExpression, CommandExpression,其中IteratorExpression和LoopExpression是非终结符表达式,CommandExpression四终结符表达式:


Context类进行输入字符串的分解,并能获取单一表达式:
  1. class Context {
  2. public:
  3. Context(const string str)
  4. {
  5. m_size = splitStr(str, m_strs);
  6. }
  7. string current()
  8. {
  9. return m_strs[m_size];
  10. }
  11. string next()
  12. {
  13. return m_strs[++m_size];
  14. }
  15. private:
  16. vector<string> m_strs;
  17. int m_size;
  18. }
AbstractExpression定义了一个统一的接口:
  1. class AbstractExpression {
  2. public:
  3. virtual void interpret(Context* context) = 0;
  4. virtual void execute() = 0;
  5. }
在IteratorExpression中进行Context中字符串的遍历,并分配合适的解释器:
  1. class IteratorExpression : public AbstractExpression {
  2. public:
  3. virtual void interpret(Context* context);
  4. virtual void execute();
  5. private:
  6. vector<AbstractExpression*> m_exps;
  7. }
  8. void IteratorExpression::interpret(Context* context)
  9. {
  10. while(context->current() != "END")
  11. {
  12. if(context->current() == "LOOP")
  13. {
  14. LoopExpression* loopExp = new LoopExpression(context);
  15. m_exp.insert(loopExp);
  16. }
  17. else
  18. {
  19. CommandExpresion* cmdExp = new CommandExpression(context);
  20. m_exps.insert(cmdExp);
  21. }
  22. }
  23. }
  24. void IteratorExpresion::execute()
  25. {
  26. for(int i = 0; i < m_str.size(); ++i)
  27. m_exps[i]->execute();
  28. }
在LoopExpression中处理LOOP和BREAK之间的内容,并分配合适的解释器:
  1. class LoopExpression : public AbstractExpresion
  2. {
  3. public:
  4. virtual void interpret(Context* context);
  5. virtual void execute();
  6. private:
  7. vector<AbstractExpression*> m_exps;
  8. int m_count;
  9. }
  10. void LoopExpression::interpret(Context* context)
  11. {
  12. while(context->current() != "BREAK")
  13. {
  14. if(context->current() == "LOOP")
  15. {
  16. m_count = context->next().toInt();
  17. }
  18. else
  19. {
  20. CommandExpresion* cmdExp = new CommandExpression(context);
  21. m_exps.insert(cmdExp);
  22. }
  23. }
  24. }
  25. void LoopExpression::execute()
  26. {
  27. for(int i = 0; i < m_count; ++i)
  28. for(int j = 0; j < m_exps.size(); ++j)
  29. m_exps[j]->execute();
  30. }
在CommandExpression中决定具体解释操作:
  1. class CommandExpression : public AbstractExpression
  2. {
  3. public:
  4. virtual void interpret(Context* context);
  5. virtual void execute();
  6. private:
  7. string m_name;
  8. string m_text;
  9. }
  10. void CommandExpression::interpret(Context* context)
  11. {
  12. m_name = context->current();
  13. if(context->current() == "PRINT")
  14. {
  15. m_text = context->next();
  16. }
  17. context->next();
  18. }
  19. void CommandExpression::execute()
  20. {
  21. if(m_name == "PRINT")
  22. cout << m_text;
  23. else if(m_name == "NEXTLINE")
  24. cout << endl;
  25. else if(m_name == "SPACE")
  26. cout << " ";
  27. }
有了以上对类的定义,就可以输出我们想要的结果了
  1. string str = "PRINT MyLanguage: NEXTLINE LOOP 2 PRINT Hello SPACE PRINT world! NEXTLINE BREAK END";
  2. Context* context = new Context(str);
  3. IteratorExpression* iterExp = new IteratorExpression();
  4. iterExp->interpret(context);
  5. iterExp->execute();
结果:
  1. MyLauguage:
  2. Hello world!
  3. Hello world!