每日博客

解释器模式(选作)

本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:

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;
}

posted @ 2021-10-31 19:16  谦寻  阅读(23)  评论(0编辑  收藏  举报