首页 > 其他分享 >实验17:解释器模式

实验17:解释器模式

时间:2024-11-13 09:10:34浏览次数:1  
标签:index 解释器 return String 17 startsWith 实验 action input

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

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、运行截图

 

 

 

 

标签:index,解释器,return,String,17,startsWith,实验,action,input
From: https://www.cnblogs.com/yuanxinglan/p/18543061

相关文章

  • 11.17
    [实验任务一]:双向适配器实现一个双向适配器,使得猫可以学狗叫,狗可以学猫抓老鼠。实验要求:画出对应的类图;提交源代码;packageadapter;//Cat接口interfaceCat{voidcry();voidcatchMouse();}//Dog接口interfaceDog{voidwang();voida......
  • 上机实验:数据准备与模型评估
    1、实验目的熟悉Python的基本操作,掌握对数据集的读写实现、对模型性能的评估实现的能力;加深对训练集、测试集、N折交叉验证、模型评估标准的理解。2、实验内容(1)利用pandas库从本地读取iris数据集;(2)从scikit-learn库中直接加载iris数据集;(3)实现五折交叉验证进行模型......
  • 环境变量提权实验
    环境变量提权PATH是Linux和Unix操作系统中的环境变量,它指定所有存储可执行程序的bin和sbin目录。当用户在终端中执行任何命令时,它会通过PATH变量来响应用户执行的命令,并向shell发送请求以搜索可执行文件。超级用户通常还具有/sbin和/usr/sbin目录,以便系统管理命令的执行。环......
  • Solution - Codeforces 1217E Sum Queries?
    对于这个“好的”的判定条件看起来有点奇怪,不妨结合上题目要求的“最小\(sum\)”一起考虑。因为要最小化\(s_p\),所以一个比较直观的想法是先从选的数个数入手。考虑到如果选的只有\(1\)个数\(a_i\),那么\(sum=a_i\),一定是好的,排除。如果选的是\(2\)个数\(a_i,a_j\),......
  • 题解:「2017 山东一轮集训 Day7」逆序对
    LibreOJ6077前置知识:生成函数、组合数先考虑平方怎么做。\(f_{i,j}\)表示处理了前\(i\)个值,逆序对有\(j\)个。显然可以转移到\(f_{i+1,j},f_{i+1,j+1},f_{i+1,j+2},...,f_{i+1,j+i}\)。然后发现这个东西是个很简单的递推,而且长得很生成函数,于是可以很自然的写成\[1\t......
  • 洛谷 P1772 [ZJOI2006] 物流运输 做题记录
    很神经的一道题。令\(val_{i,j}\)表示从第\(i\)天到第\(j\)天每天都走一条道路,单次的最小花费。可以枚举\(\{i,j\}\)然后把在这个区间里的所有点设置成不可达,每一个\(\{i,j\}\)都可以用floyd算,时间复杂度\(O(n^2m^3)\)。令\(f_i\)表示第\(i\)天的最小花费,那么......
  • 2024.11.12 1703版
    起于《海奥华预言》的思考◆地球管理结构和参考持续更新中...... 英文地址:https://github.com/zhuyongzhe/Earth/tags中文地址:https://www.cnblogs.com/zhuyongzhe85作者:朱永哲 ---------------------------------------------------------------------------------......
  • 11.11 ~ 11.17
    11.11早晨去级部转了一圈然后没看见人就直接回来了PEP说没事?不懂,有老师叫我再说(上午模拟赛。好像是直接搬了场梦熊S组上来,有少部分人看过题......
  • 17.ORM的迁移命令
    1.settings配置文件链接数据库 2.generate_schemas设置为True表示项目启动会自动将models中的表迁移到数据库Ⅰ 3.generate_schemas设置为True表示项目启动会自动将models中的表迁移到数据库Ⅱ 4.generate_schemas设置为True表示项目启动会自动将models中的表迁移到数据......
  • springboot高校心理测评系统-计算机毕业设计源码25173
    目 录第1章 引 言1.1 选题背景1.2 研究现状1.3 论文结构安排第2章 系统的需求分析2.1 系统可行性分析2.1.1 技术方面可行性分析2.1.2 经济方面可行性分析2.1.3 法律方面可行性分析2.1.4 操作方面可行性分析2.2 系统功能需求分析2.......