实验17:解释器模式(选作)
本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:
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个单位”。
实验要求:
1. 提交类图;
2. 提交源代码;
JAVA
import java.util.Stack;
public abstract class AbstractNode {
public abstract
String interpret();
}
public class ActionNode extends AbstractNode{
private String
action;
public
ActionNode(String action) {
this.action =
action;
}
//动作(移动方式)表达式的解释操作
public String
interpret() {
if
(action.equalsIgnoreCase("move")) {
return
"移动";
}
else if
(action.equalsIgnoreCase("run")) {
return
"快速移动";
}
else {
return
"无效指令";
}
}
}
public class AndNode extends AbstractNode{
private
AbstractNode left; //And的左表达式
private
AbstractNode right; //And的右表达式
public
AndNode(AbstractNode left, AbstractNode right) {
this.left =
left;
this.right =
right;
}
//And表达式解释操作
public String
interpret() {
return
left.interpret() + "再" + right.interpret();
}
}
public class DirectionNode extends AbstractNode{
private String
direction;
public
DirectionNode(String direction) {
this.direction = direction;
}
//方向表达式的解释操作
public String
interpret() {
if (direction.equalsIgnoreCase("up"))
{
return
"向上";
}
else if
(direction.equalsIgnoreCase("down")) {
return
"向下";
}
else if
(direction.equalsIgnoreCase("left")) {
return
"向左";
}
else if
(direction.equalsIgnoreCase("right")) {
return
"向右";
}
else {
return
"无效指令";
}
}
}
public class DistanceNode extends AbstractNode{
private String
distance;
public
DistanceNode(String distance) {
this.distance = distance;
}
//距离表达式的解释操作
public String
interpret() {
return
this.distance;
}
}
public class InstructionHandler {
private String
instruction;
private
AbstractNode node;
public void
handle(String instruction) {
AbstractNode left = null, right = null;
AbstractNode direction = null, action = null, distance = null;
Stack
stack = new Stack(); //声明一个栈对象用于存储抽象语法树
String[]
words = instruction.split(" "); //以空格分隔指令字符串
for (int
i = 0; i < words.length; i++) {
if
(words[i].equalsIgnoreCase("and")) {
left = (AbstractNode)stack.pop(); //弹出栈顶表达式作为左表达式
String word1= words[++i];
direction = new DirectionNode(word1);
String word2 = words[++i];
action = new ActionNode(word2);
String word3 = words[++i];
distance = new DistanceNode(word3);
right = new SentenceNode(direction,action,distance); //右表达式
stack.push(new AndNode(left,right)); //将新表达式压入栈中
}
//如果是从头开始进行解释,则将前三个单词组成一个简单句子SentenceNode并将该句子压入栈中
else
{
String word1 = words[i];
direction = new DirectionNode(word1);
String word2 = words[++i];
action = new ActionNode(word2);
String word3 = words[++i];
distance = new DistanceNode(word3);
left = new SentenceNode(direction,action,distance);
stack.push(left); //将新表达式压入栈中
}
}
this.node
= (AbstractNode)stack.pop(); //将全部表达式从栈中弹出
}
public String
output() {
String
result = node.interpret(); //解释表达式
return
result;
}
}
public class SentenceNode extends AbstractNode{
private
AbstractNode direction;
private
AbstractNode action;
private
AbstractNode distance;
public
SentenceNode(AbstractNode direction,AbstractNode action,AbstractNode distance)
{
this.direction = direction;
this.action =
action;
this.distance
= distance;
}
//简单句子的解释操作
public String
interpret() {
return
direction.interpret() + action.interpret() + distance.interpret();
}
}
public class Client {
public static
void main(String[] args) {
// TODO
Auto-generated method stub
String
instruction1 = "up move 5 and down run 10 and left move 5";
String
instruction2="down run 10 and left move 20";
InstructionHandler handler = new InstructionHandler();
handler.handle(instruction1);
String
outString;
outString =
handler.output();
System.out.println(outString);
handler.handle(instruction2);
outString =
handler.output();
System.out.println(outString);
}
}
C++
#include<iostream>
#include<stack>
#include <sstream>
#include<string>
using namespace std;
class AbstractNode {
public:
virtual string
interpret()=0;
};
class ActionNode:public AbstractNode{
private:
string action;
public:
ActionNode(string
action) {
this->action = action;
}
string
interpret() {
if
(action=="move") {
return "移动";
}
else if
(action=="run") {
return
"快速移动";
}
else {
return
"无效指令";
}
}
};
class AndNode:public AbstractNode{
private:
AbstractNode
*left; //And的左表达式
AbstractNode *right;
//And的右表达式
public:
AndNode(AbstractNode *left, AbstractNode *right) {
this->left
= left;
this->right = right;
}
//And表达式解释操作
string
interpret() {
return
left->interpret() + "再" + right->interpret();
}
};
class DirectionNode :public AbstractNode{
private:
string direction;
public:
DirectionNode(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 DistanceNode:public AbstractNode{
private:
string distance;
public:
DistanceNode(string distance) {
this->distance = distance;
}
//距离表达式的解释操作
string
interpret() {
return
this->distance;
}
};
class SentenceNode:public AbstractNode{
private:
AbstractNode
*direction;
AbstractNode
*action;
AbstractNode
*distance;
public:
SentenceNode(AbstractNode *direction,AbstractNode *action,AbstractNode
*distance) {
this->direction
= direction;
this->action = action;
this->distance
= distance;
}
//简单句子的解释操作
string
interpret() {
return
direction->interpret() + action->interpret() + distance->interpret();
}
};
class InstructionHandler {
private:
string
instruction;
AbstractNode
*node;
public:
void
handle(string instruction) {
AbstractNode
*left = NULL, *right = NULL;
AbstractNode
*direction = NULL, *action = NULL, *distance = NULL;
stack<AbstractNode*> stack; //声明一个栈对象用于存储抽象语法树
istringstream
str1(instruction);
istringstream
str2(instruction);
string out;
int j=0,k=0;
int n;
//以空格分隔指令字符串
while (str1
>> out) {
j++;
}
n=j;
string
words[n];
string out2;
while (str2
>> out2) {
words[k]=out2;
k++;
}
for (int i =
0; i <n; i++) {
//本实例采用栈的方式来处理指令,如果遇到“and”,则将其后的三个单词作为三个终结符表达式连成一个简单句子SentenceNode作为“and”的右表达式,而将从栈顶弹出的表达式作为“and”的左表达式,最后将新的“and”表达式压入栈中。
if
(words[i]=="and") {
left
= stack.top(); //弹出栈顶表达式作为左表达式
stack.pop();
string word1= words[++i];
direction = new DirectionNode(word1);
string word2 = words[++i];
action = new ActionNode(word2);
string word3 = words[++i];
distance = new DistanceNode(word3);
right
= new SentenceNode(direction,action,distance); //右表达式
stack.push(new AndNode(left,right)); //将新表达式压入栈中
}
//如果是从头开始进行解释,则将前三个单词组成一个简单句子SentenceNode并将该句子压入栈中
else {
string word1 = words[i];
direction = new DirectionNode(word1);
string word2 = words[++i];
action = new ActionNode(word2);
string word3 = words[++i];
distance = new DistanceNode(word3);
left
= new SentenceNode(direction,action,distance);
stack.push(left); //将新表达式压入栈中
}
}
this->node
= stack.top(); //将全部表达式从栈中弹出
stack.pop();
}
string output() {
string result
= node->interpret(); //解释表达式
return
result;
}
};
int main(){
string
instruction1 = "up move 5 and down run 10 and left move 5";
string
instruction2="down run 10 and left move 20";
InstructionHandler *handler = new InstructionHandler();
handler->handle(instruction1);
string outString;
outString =
handler->output();
cout<<outString<<endl;
handler->handle(instruction2);
outString =
handler->output();
cout<<outString<<endl;
}
3. 注意编程规范。