每日博客
解释器模式(选作)
本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:
1、理解解释器模式的动机,掌握该模式的结构;
2、能够利用解释器模式解决实际问题。
[实验任务一]:解释器模式
某机器人控制程序包含一些简单的英文指令,其文法规则如下:
expression ::= direction action distance | composite
composite ::= expression and expression
direction ::= ‘up’ | ‘down’ | ‘left’ | ‘right’
action ::= ‘move’ | ‘run’
distance ::= an integer //一个整数值
如输入:up move 5,则输出“向上移动5个单位”;输入:down run 10 and left move 20,则输出“向下移动10个单位再向左移动20个单位”。
C++
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <typeinfo>
using namespace std;
template<typename CharT, template<typename S, typename Q = std::allocator<S> > class Container>
void Split(Container<std::basic_string<CharT> >& v, const std::basic_string<CharT>& s, const std::basic_string<CharT>& c);
template<template<typename S, typename Q = std::allocator<S> > class Container>
void Split(Container<std::basic_string<char> >& v, const std::basic_string<char>& s, const std::basic_string<char>& c)
{
if (0 == c.length())
return;
std::basic_string<char>::size_type pos1 = 0;
std::basic_string<char>::size_type pos2 = 0;
pos1 = 0;
pos2 = s.find(c);
while (std::basic_string<char>::npos != pos2)
{
v.push_back(s.substr(pos1, pos2 - pos1));
pos1 = pos2 + c.size();
pos2 = s.find(c, pos1);
}
if (pos1 != s.length())
{
v.push_back(s.substr(pos1));
}
}
class AbstractExpression
{
public:
virtual string interpret() = 0;
virtual ~AbstractExpression(){}
};
class AndExpression : public AbstractExpression
{
private:
AbstractExpression* left ;
AbstractExpression* right;
public:
AndExpression(AbstractExpression* left,
AbstractExpression* right)
{
this->left = left;
this->right = right;
}
string interpret()
{
return left->interpret() + "再" + right->interpret();
}
AbstractExpression* getLeft()
{
return left;
}
AbstractExpression* getRight()
{
return right;
}
};
class SentenceExpression : public AbstractExpression
{
private:
AbstractExpression* direction;
AbstractExpression* action;
AbstractExpression* distance;
public:
SentenceExpression(AbstractExpression* direction,
AbstractExpression* action,
AbstractExpression* distance)
{
this->direction = direction;
this->action = action;
this->distance = distance;
}
string interpret()
{
return direction->interpret() + action->interpret() + distance->interpret();
}
AbstractExpression* getDirection()
{
return direction;
}
AbstractExpression* getAction()
{
return action;
}
AbstractExpression* getDistance()
{
return distance;
}
};
class DirectionExpression : public AbstractExpression
{
private:
string direction;
public:
DirectionExpression(string direction)
{
this->direction = direction;
}
string interpret()
{
if(direction =="up")
{
return "向上";
}
else if(direction == "down")
{
return "向下";
}
else if(direction == "left")
{
return "向左";
}
else if(direction == "right")
{
return "向右";
}
else
{
return "无效指令";
}
}
};
class ActionExpression : public AbstractExpression
{
private:
string action;
public:
ActionExpression(string action)
{
this->action = action;
}
string interpret()
{
if(action == "move")
{
return "移动";
}
else if(action == "run")
{
return "快速移动";
}
else
{
return "无效指令";
}
}
};
class DistanceExpression : public AbstractExpression
{
private:
string distance;
public:
DistanceExpression(string distance)
{
this->distance = distance;
}
string interpret()
{
return distance;
}
};
class InstructionHandler
{
private:
AbstractExpression* mExp;
void delTree(AbstractExpression* exp)
{
bool bLeaf = typeid(*exp) ==typeid(DirectionExpression) ||
typeid(*exp) ==typeid(ActionExpression) ||
typeid(*exp) ==typeid(DistanceExpression);
AndExpression* andExp = dynamic_cast<AndExpression*>(exp);
SentenceExpression* sentenceExp = dynamic_cast<SentenceExpression*>(exp);
if(bLeaf)
{
delete exp;
}
else if (andExp != NULL)
{
AbstractExpression* left = andExp->getLeft();
AbstractExpression* right = andExp->getRight();
delTree(left);
delTree(right);
delete andExp;
}
else if(sentenceExp != NULL)
{
AbstractExpression* dir = sentenceExp->getDirection();
AbstractExpression* act = sentenceExp->getAction();
AbstractExpression* dis = sentenceExp->getDistance();
delTree(dir);
delTree(act);
delTree(dis);
delete sentenceExp;
}
else
{
}
}
public:
InstructionHandler():mExp(NULL){}
void handle(string instruction){
AbstractExpression* left = NULL;
AbstractExpression* right = NULL;
AbstractExpression* direction = NULL;
AbstractExpression* action = NULL;
AbstractExpression* distance = NULL;
if (mExp!=NULL)
{
delTree(mExp);
mExp = NULL;
}
stack<AbstractExpression*> stkExp;
vector<string> words;
Split(words, instruction, " ");
for(unsigned int i=0; i<words.size(); i++){
string dir("");
string act("");
string dis("");
if(words[i] =="and"){
left = stkExp.top();
stkExp.pop();
dir = words[++i];
direction = new DirectionExpression(dir);
act = words[++i];
action = new ActionExpression(act);
dis = words[++i];
distance = new DistanceExpression(dis);
right = new SentenceExpression(direction, action, distance);
stkExp.push(new AndExpression(left, right));
}
else{
dir = words[i];
direction = new DirectionExpression(dir);
act = words[++i];
action = new ActionExpression(act);
dis = words[++i];
distance = new DistanceExpression(dis);
stkExp.push(new SentenceExpression(direction, action, distance));
}
}
if(!stkExp.empty()){
mExp = stkExp.top();
stkExp.pop();
}
else
mExp = NULL;
}
string output(){
return mExp==NULL ? "": mExp->interpret();
}
};
int main()
{
string instruction = "up move 5 and down run 10 and left move 5";
InstructionHandler handler;
handler.handle(instruction);
cout <<"输入指令: " <<instruction <<endl;
cout <<"移动结果:" << handler.output() << endl;
instruction = "right run 20 and down move 10 and left run 40 and up run 10";
handler.handle(instruction);
cout <<"输入指令: " <<instruction <<endl;
cout <<"移动结果:" << handler.output() << endl;
return 0;
}