博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Interpreter - 解释器模式
阅读量:5237 次
发布时间:2019-06-14

本文共 3120 字,大约阅读时间需要 10 分钟。

定义
给定一个语言, 定于它的文法,并定义一个解释器,这个解释器使用改表示来解释语言中的句子。
类型
行为型模式
案例
像很熟知的正則表達式就是描写叙述字符串模式的一种标准语言,它为每个模式都构造了一个特定的算法。
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!

转载于:https://www.cnblogs.com/mengfanrong/p/4329814.html

你可能感兴趣的文章
《C++反汇编与逆向分析技术揭秘》之十——构造函数
查看>>
2018年学习的一门语言
查看>>
lightoj 1057 - Collecting Gold(状压dp)
查看>>
1401机器翻译(Noip2010提高组第1题)
查看>>
矢量图
查看>>
CSS--文本属性
查看>>
【二次元的CSS】—— 用 DIV + CSS3 画咸蛋超人(详解步骤)
查看>>
关于restful开发的疑惑
查看>>
笔记:html常见的兼容问题
查看>>
如何获取HTML中Select选中项的值
查看>>
什么是Reactor模式,或者叫反应器模式
查看>>
高效程序员的工作场所和装备
查看>>
【GO基础】main redeclared in this block问题的排查与解决
查看>>
给按钮添加 toSearch_Button.setOnClickListener(this);出错 解决办法
查看>>
python之线程、进程入门
查看>>
English trip M1 - PC7 Can I Borrow Your Ping-Pong? Teacher:Patrick
查看>>
Windbg+Procdump解决w3wp.exe CPU过百问题
查看>>
ef codefirst VS里修改数据表结构后更新到数据库
查看>>
async await 和 task的区别和理解(可能有错)
查看>>
使用自定义比较操作符排序,查找
查看>>