图片引用于百度
简介:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子
优点:扩展性、灵活性比较好,易于实现简单文法
缺点:可利用场景的比较少,对于复杂的文法比较难维护并且会引起类膨胀
例子背景:解释一段汇编加减乘除代码
解释器模式代码:
- 上下文类:
#pragma once
#include <string>
#include <iostream>
#include <list>
#include <map>
using namespace std;
using StringList = list<string>;
class Context
{
private:
StringList m_lstStatements;
public:
Context(const string& str) : m_lstStatements(split(str))
{
}
~Context() {}
public:
string NextStatement()
{
auto str = m_lstStatements.front();
m_lstStatements.pop_front();
return str;
}
bool HasNext()
{
return !m_lstStatements.empty();
}
private:
StringList split(const string& txt)
{
char* str = const_cast<char*>(txt.c_str());
string tmp;
StringList tmpLst;
while (*str != '\0')
{
if( *str != '\n')
{
tmp.push_back(*str);
}
else
{
tmpLst.push_back(tmp);
tmp.clear();
}
str++;
}
tmpLst.push_back(tmp);
return tmpLst;
}
};
- 抽象解释器类:
#pragma once
#include "Context.h"
class AbstractExpression
{
public:
AbstractExpression() = default;
virtual ~AbstractExpression() = default;
public:
virtual void interpret(Context* text) = 0;
virtual int execute() = 0;
};
- 具体解释器类:
#pragma once
#include "AbstractExpression.h"
class MovExpression : public AbstractExpression
{
private:
int m_num = 0;
public:
MovExpression(const int& num) : m_num(num) {}
public:
virtual void interpret(Context* text)
{
(text);
}
virtual int execute()
{
return m_num;
}
};
class AddExpression : public AbstractExpression
{
private:
AbstractExpression* m_mov = nullptr;
int m_num = 0;
public:
AddExpression(AbstractExpression* mov, const int& num) : m_mov(mov), m_num(num) {}
~AddExpression()
{
delete m_mov;
}
public:
virtual void interpret(Context* text)
{
(text);
}
virtual int execute()
{
return m_mov->execute() + m_num;
}
};
class SubExpression : public AbstractExpression
{
private:
AbstractExpression* m_mov = nullptr;
int m_num = 0;
public:
SubExpression(AbstractExpression* mov, const int& num) : m_mov(mov), m_num(num) {}
~SubExpression()
{
delete m_mov;
}
public:
virtual void interpret(Context* text)
{
(text);
}
virtual int execute()
{
return m_mov->execute() - m_num;
}
};
class MulExpression : public AbstractExpression
{
private:
AbstractExpression* m_mov = nullptr;
int m_num = 0;
public:
MulExpression(AbstractExpression* mov, const int& num) : m_mov(mov), m_num(num) {}
~MulExpression()
{
delete m_mov;
}
public:
virtual void interpret(Context* text)
{
(text);
}
virtual int execute()
{
return m_mov->execute() * m_num;
}
};
class IdivExpression : public AbstractExpression
{
private:
AbstractExpression* m_mov = nullptr;
int m_num = 0;
public:
IdivExpression(AbstractExpression* mov, const int& num) : m_mov(mov), m_num(num) {}
~IdivExpression()
{
delete m_mov;
}
public:
virtual void interpret(Context* text)
{
(text);
}
virtual int execute()
{
return m_mov->execute() / m_num;
}
};
class ExplainStatement : public AbstractExpression
{
private:
map<string, AbstractExpression*> m_lstExpression;
AbstractExpression* m_execute = nullptr;
bool m_isError = false;
public:
ExplainStatement() {}
~ExplainStatement()
{
delete m_execute;
}
private:
bool isNumber(const string& str)
{
return (str.at(0) >= 0x30 && str.at(0) < 0x40);
}
void judgeCommand(const string& statement)
{
int replace = static_cast<int>(statement.find(" "));
auto command = statement.substr(0, replace);
int replace1 = static_cast<int>(statement.find(",", replace));
string theRegister = statement.substr(replace+1, replace1-replace-1);
string numStr = statement.substr(replace1+2, statement.size()-replace1-2);
bool isNum = isNumber(numStr);
int num = atoi(numStr.c_str());
if (command == "mov")
{
m_lstExpression.insert(make_pair(theRegister, new MovExpression(num)));
}
else
{
AbstractExpression* nextCommand = m_lstExpression[theRegister];
if (!nextCommand) throw "寄存器:" + theRegister + "不存在!";
if (!isNum)
{
auto numExp = m_lstExpression[numStr];
if (!numExp) throw "寄存器:" + numStr + "不存在!";
else num = numExp->execute();
}
if (command == "add")
{
m_execute = new AddExpression(nextCommand, num);
}
else if (command == "sub")
{
m_execute = new SubExpression(nextCommand, num);
}
else if (command == "mul")
{
m_execute = new MulExpression(nextCommand, num);
}
else if (command == "idiv")
{
m_execute = new IdivExpression(nextCommand, num);
}
m_lstExpression[theRegister] = m_execute;
}
}
public:
virtual void interpret(Context* text)
{
while (text->HasNext())
{
try
{
judgeCommand(text->NextStatement());
}
catch (string& str)
{
cout << str << endl;
m_isError = true;
break;
}
}
}
virtual int execute()
{
return (m_isError ? 0 : m_execute->execute());
}
};
- 引用:
#include "Expressions.h"
int main()
{
string text("mov eax, 12\nmov ebx, 15\nadd eax, 20\nsub eax, ebx\nmul eax, ebx\nidiv eax, 5");
//string text("mov eax, 0\nadd eax, ebx\nadd eax, 12\nsub eax, 10");
Context* context = new Context(text);
ExplainStatement* es = new ExplainStatement;
es->interpret(context);
cout << "result:" << es->execute() << endl;
getchar();
return 0;
}
总结:
解释器模式(Interpreter):可以用于解释一些自定义的数据结构,常用于编译器、规则引擎、正则表达式等,这个设计模式的本质就是解释、解析
作者:丶梦爱
博客:https://blog.csdn.net/u014732297(转载请说明出处)