实验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. 提交源代码;
3. 注意编程规范。
1、类图
源代码
package org.example;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Command {
String direction;
String action;
int distance;
public Command(String direction, String action, int distance) {
this.direction = direction;
this.action = action;
this.distance = distance;
}
@Override
public String toString() {
return "向" + direction + " " + action + " " + distance + "个单位";
}
}
package org.example;
import java.util.ArrayList;
import java.util.List;
class Parser {
private String input;
private int index = 0;
public Parser(String input) {
this.input = input.trim(); // 去除输入字符串的首尾空格
}
// 解析主入口
public List<Command> parse() {
List<Command> commands = new ArrayList<>();
while (index < input.length()) {
Command command = parseExpression();
commands.add(command);
skipWhitespace();
// 如果下一个部分是 'and',则继续解析复合指令
if (index < input.length() && input.startsWith("and", index)) {
index += 3; // 跳过 "and"
// 跳过可能的空格
skipWhitespace();
}
}
return commands;
}
// 解析一个表达式(可能是简单指令或复合指令)
private Command parseExpression() {
if (input.startsWith("up", index) || input.startsWith("down", index) || input.startsWith("left", index) || input.startsWith("right", index)) {
return parseSimpleExpression();
} else {
throw new IllegalArgumentException("Invalid expression at index " + index + " in input: '" + input.substring(index) + "'");
}
}
// 解析简单指令(方向 + 动作 + 距离)
private Command parseSimpleExpression() {
String direction = parseDirection();
String action = parseAction();
int distance = parseDistance();
return new Command(direction, action, distance);
}
// 解析方向(up, down, left, right)
private String parseDirection() {
if (input.startsWith("up", index)) {
index += 2;
return "上";
} else if (input.startsWith("down", index)) {
index += 4;
return "下";
} else if (input.startsWith("left", index)) {
index += 4;
return "左";
} else if (input.startsWith("right", index)) {
index += 5;
return "右";
} else {
throw new IllegalArgumentException("Invalid direction at index " + index);
}
}
// 解析动作(move, run)
private String parseAction() {
skipWhitespace(); // 跳过空格
// 跳过可能的空格
while (index < input.length() && input.charAt(index) == ' ') {
index++;
}
if (input.startsWith("move", index)) {
index += 4;
return "移动";
} else if (input.startsWith("run", index)) {
index += 3;
return "奔跑";
} else {
throw new IllegalArgumentException("Invalid action at index " + index);
}
}
// 解析距离(整数)
private int parseDistance() {
skipWhitespace(); // 跳过空格
while (index < input.length() && input.charAt(index) == ' ') { // 跳过空格
index++;
}
int start = index;
while (index < input.length() && Character.isDigit(input.charAt(index))) {
index++;
}
if (start == index) {
throw new IllegalArgumentException("Invalid distance at index " + start);
}
return Integer.parseInt(input.substring(start, index));
}
// 跳过空格
private void skipWhitespace() {
while (index < input.length() && input.charAt(index) == ' ') {
index++;
}
}
}
package org.example;
import java.util.List;
import java.util.Scanner;
public class RobotControl {
public static void main(String[] args) {
// 创建 Scanner 用于读取用户输入
Scanner scanner = new Scanner(System.in);
// 循环接受用户输入
while (true) {
System.out.print("请输入指令 (或输入 'exit' 退出): ");
String input = scanner.nextLine().trim();
// 如果输入 'exit' 则退出程序
if (input.equalsIgnoreCase("exit")) {
System.out.println("程序结束!");
break;
}
// 创建 Parser 对象并解析指令
Parser parser = new Parser(input);
List<Command> commands = parser.parse();
// 输出解析结果
for (int i = 0; i < commands.size(); i++) {
// 如果是最后一个命令,不加 "再"
if (i == commands.size() - 1) {
System.out.println(commands.get(i));
} else {
System.out.print(commands.get(i) + "再");
}
}
}
scanner.close(); // 关闭扫描器
}
}
3、运行截图