编译原理----词法分析设计

news2024/11/24 12:35:32

程序设计实验1 词法分析

一、实验目的:

通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

二、实验内容

编制一个单词获取程序,从文件输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、整数、小数、字符串、字符、分隔符、运算符等八大类。

三、实验要求

1、词法规则
关键字: void、var、int、float、string、begin、end 、if、then、else、while、do、call、read、write、and、or
单词类别:1 注意:关键字大小敏感(区分大小写)。

标识符: 字母或 “ $ ” 打头、由字母、数字串或“$”组成的任意长度的符号串。
单词类别:2 注意:标识符大小敏感(区分大小写)。

整数: 数字串。
单词类别:3

小数: 数字串1. 数字串2
单词类别:4 注意:数字串1不能为空,数字串2可以为空,例如:23.

字符串: 由一对“”括起来的任意长度的符号串。注意:可以多行。
单词类别:5

字符: 由一对单引号括起来的单个字母。如:‘a’、‘5’、‘+’
单词类别:6

分隔符: {、}、(、)、;、空格
单词类别:7

运算符: ==、=、<、<=、>、>=、<>、+、-、*、/
单词类别:8

注释: 支持单行注释和多行注释(注释语法同C语言)。
为了实现的编译程序实用,这里规定源程序可采用自由书写格式,即一行内可以书写多个语句,一个语句也可以占领多行书写。

2、设计要求
(1)设计一个主程序,通过人机交互的方式或命令行参数获得需要分析的源代码文件,打开待分析的源程序,通过反复调用词法分析程序逐个获得源代码中的所有单词并输出。
整个程序的总体流程见图1-1。
(2)设计一个词法分析器,其输入为要分析的源文件,每次调用顺序识别出源文件中的下一个单词。每个单词需要输出:单词本身、单词类别、单词所在的行列号。遇到错误时可显示“Error”,然后跳过错误部分继续显示。
注意:在主程序中输出单词的信息,词法分析中不能输出单词信息,只能通过返回值或全局变量返回所提取的单词信息。
(3)实验结束后提交源代码、测试数据、实验报告至:
ftp://编译原理/程序设计1
本次实验提交的截止日期:2023-04-15 晚22:00 前.
(4)实验报告内容:(具体参见“编译原理程序设计实验报告模版.docx”)
(a) 有关词法分析器设计的说明。详细说明词法分析器的实现原理,包括软件结构设计说明、功能模块说明、关键数据结构说明、关键算法实现等。
(b) 给出词法分析器源程序清单,并标记出每个模块的功能;
© 说明词法分析器中可能存在的问题;
(d) 经验总结,如果重做一遍,你会有哪些新的改进?

四、实验过程和指导

(一)准备:
1、阅读课本有关章节,明确语言的语法,写出基本保留字、标识符、常数、运算符、分隔符和程序例。
2、初步编制好程序。
3、准备好多组测试数据,包括正确的输入和错误的输入。

(二)程序要求:
程序输入/输出示例:
如源程序为C语言。输入如下一段:
void main()
{
int a,b;
a = 10;
b = a + 20;
}

要求输出如下所示,每个单词输出:单词类型、单词本身、行号、列号。
(1,void,1, 1)
(2,main, 1, 6)
(7, ( ,1,10)
(7, ),1,11)
(7, { ,2, 1)
(1, int,3, 4)
(2, a ,3, 8)
(…

(三)设计指导:
词法分析程序的主要工作为:
(1)从源程序文件中逐个读入字符。
(2)统计行数和列数用于错误单词的定位。
(3)删除空格类字符,包括回车、制表符空格。
(4)根据每个单词的首字符确定该单词的类型,按构词规则从源文件中逐个读入字符检查该字符是否该单词的允许输入。
在编写词法分析程序时,用重复调用词法分析子程序取一单词的方法得到整个源程序的单词序列。
整个程序的总体流程见图1-1。
词法分析程序的流程图见图1-2。
取字符和统计字符行列位置子程序见图1-3。
注意:图1-2、图1-3仅供参考,并不完全符合本次实验的要求,仅仅说明整个词法分析程序的总体框架。因此,实验报告中不能直接贴图1-1、图1-2、图1-3,否则实验报告以无效处理。

图
图1-1

在这里插入图片描述



源代码:
import java.util.Arrays;
import java.util.Scanner;
import java.util.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.regex.Pattern;

class Results{//保存要输出的结果
    boolean rig;//是否是错误
    int type;//记录类型
    String res;//输出内容
    int li=0,co=0;//所在行和列
}
public class Main {
    static final int N=101;//定义一个常量,当输入增多时便于后续修改
    static int a[]=new int [N];//该数组用来存放文本每行的列数(假设输入数据不超过100行)
    static boolean ok=false;//记录每行第一个单词前是否有空格,如果有为true
    static boolean mark=false;//如果判断出是注释的内容,是则为true,否则为false
    static boolean biu=false;//当存在多行注释时为true
    static int blank=0;//保存前面的空格数
    static int k=0,lines,cols;//lines用来记录是第几行,cols记录第几列,不赋初值时自动为0
    static int num=0;//记录每一行字符的个数
    static boolean words=false;//当由""引起来的字符串占多行时为true
    static String strs="";//保存多行字符串前面的内容
    static Results RE[]=new Results[N];//保存一行中遇到的字符
    static String keyWord[]={"void","var","int","float","string","begin","end","if",
            "then","else","while","do","call","read","write","and","or"};//1 关键字
    static String symbol[]={"{","}","(",")",";"," "};//7 分隔符
    static String operation[]={"==","=","<","<=",">",">=","<>","+","-","*","/"};//8 运算符
    static ArrayList<String> keyWords=null;//1 关键字
    static ArrayList<String> symbols=null;//7 分隔符
    static ArrayList<String> operations=null;//8 运算符

    //关键字,字母或$的识别   1 2
    public static void letterCheck(String str){
        cols=k+1;
        String token= String.valueOf(str.charAt(k++));
        char ch;
        for( ;k<str.length();k++){
            ch=str.charAt(k);
            if (!Character.isLetterOrDigit(ch)&&ch!='$')
                break;
            else
                token+=ch;
        }
        if(ok)
            cols+=blank;
        if (keyWords.contains(token)){
            RE[num].rig=true;RE[num].type=1;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
        else{
            RE[num].rig=true;RE[num].type=2;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
        if (k!=str.length()-1||(k==str.length()-1&&(!Character.isLetterOrDigit(str.charAt(k))&&str.charAt(k)!='$')))
            k--;
    }
    //数字的识别  3 4
    //1、识别退出:遇到空格符,遇到运算符或者界符   2、错误情况:两个及以上小数点,掺杂字母
    public static void digitCheck(String str){
        cols=k+1;
        String token= String.valueOf(str.charAt(k++));
        int flag=0;//记录小数点的个数
        boolean err=false;
        char ch;
        for( ;k<str.length();k++){
            ch=str.charAt(k);
            if(ch==' '||(!Character.isLetterOrDigit(ch)&&ch!='.')||
               symbols.contains(ch)||operations.contains(ch))//遇到空格,运算符或者标识符则退出,属于正常退出
                break;
            else if (err)
                token+=ch;
            else{
                token+=ch;
                if (ch == '.') {//这个if判断是否存在多个小数点的情况
                    if(flag>=1)//如果之前已经记录有一个小数点了,那么此时就是错误
                        err=true;
                    flag++;//只要遇到小数点就加一
                }
                else if (Character.isLetter(ch))//遇到字母时是不对的
                    err=true;
            }
        }
        if(token.charAt(token.length()-1)=='.'&&flag>=2)//如果最后的出的字符串最后一位是小数点,并且出现多个小数点则错误
            err=true;  //小数点前面不能为空,后面2可以为空
        if(err){
            RE[num].rig=false;RE[num].type=-1;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
        else{
            if(ok)
                cols+=blank;
            if(flag==0) {//flag为0时说明没有小数点,数字串和小数要分开输出
                RE[num].rig=true;RE[num].type=3;
                RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                ++num;
            }
            else{
                RE[num].rig=true;RE[num].type=4;
                RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                ++num;
            }
        }
        if(k!=str.length()-1||(k==str.length()-1&&!Character.isDigit(str.charAt(k))))
            k--;
    }
    //字符串检查   5
    public static void stringCheck(String str){
        cols=k+1;
        String token=String.valueOf(str.charAt(k++));
        char ch;
        int n=str.length();
        if(!words){//直接寻找第一次分号的位置并记录下来,如果不加这个条件可能会被识别为第2次的
            for(int i=0;i<n;++i){
                if(str.charAt(i)=='"'){
                    RE[num].li=lines;
                    RE[num].co=i+1+(ok==true?blank:0);
                    break;
                }
            }
        }
        for( ;k<n;++k){
            ch=str.charAt(k);
            token+=ch;
            if(words==true&&ch=='"'){//多行结束情况判断,遇到引号结束,就把strs的值赋给token
                strs+=token;
                token=strs;//最后保存到RE中的是token,所以将strs的值赋给token
                words=false;//这里一定要置为false,否则后面对1,2的判断都不会出现
                break;
            }
            if(ch=='"')//单独一行就直接break就行了
                break;
        }
        if(token.charAt(token.length()-1)!='"') {//最后一个字符不是双引号说明是多行字符串,标记为true,直接返回继续判断
            words=true;
            strs+=token;
            return;
        }
        else{
            RE[num].type=5;
            RE[num].res=token;
            ++num;
        }
    }
    //单引号引起来字符的识别   6
    public static void charCheck(String str){
        cols=k+1;
        String token=String.valueOf(str.charAt(k++));
        char ch;
        int n=str.length();
        for( ;k<n;++k){
            ch=str.charAt(k);
            token+=ch;
            if(ch=='\'')//单个打印号要用转义字符表示
                break;
        }
        if(token.charAt(token.length()-1)!='\'') {//最后一个字符不是单引号
            RE[num].rig=false;RE[num].type=-1;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
        else {//没有就可以输出是第几个类型的词,本身,行号和列号
            if(ok)
                cols+=blank;
            RE[num].rig=true;RE[num].type=6;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
    }
    //分隔符,运算符的识别   7 8
    public static void symbolCheck(String str){
        cols=k+1;
        String token= String.valueOf(str.charAt(k++));
        char ch;
        if (symbols.contains(token)){//如果该符号包含在分隔符中,因为分隔符中都是单个符号,所以直接输出token
            if(ok)
                cols+=blank;
            RE[num].rig=true;RE[num].type=7;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
            k--;
        }
        else {
            if (operations.contains(token)){
                if (k<str.length()){
                    ch=str.charAt(k);

                    if(str.charAt(k)=='/'&&str.charAt(k-1)=='/'){//只要遇到单行注释,直接return就行,不用做标记
                        mark=true;
                        return;
                    }
                    if(str.charAt(k-1)=='/'&&str.charAt(k)=='*'){//当存在多行注释时,使biu为true
                        biu=true;
                        //return; 当在一行中找到/*符号时,可能这一行也会有*/符号,所以这个需要判断,不能直接返回
                    }
                    if(biu){//判断是不是会在当前这行注释结束
                        for(int i=k;i<str.length();++i){
                            if(str.charAt(i)=='*'&&str.charAt(i+1)=='/'){
                                biu=false;
                                k=i+1;//从多行注释结束的下一个字符开始分析
                                return;
                            }
                        }
                        return;//如果没在同一行结束,直接返回判断下一行就好了
                    }
                    if (operations.contains(token+ch)){//如果包含,说明该运算符由2个字符组成
                        token+=ch;
                        if(ok)
                            cols+=blank;
                        RE[num].rig=true;RE[num].type=8;
                        RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                        ++num;
                    }
                    else {//此情况说明只是单个字符的运算符
                        k--;
                        if(ok)
                            cols+=blank;
                        if(mark==false&&biu==false){
                            RE[num].rig=true;RE[num].type=8;
                            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                            ++num;
                        }
                    }
                }
            }
            else {//错误
                k--;
                if(ok)
                    cols+=blank;
                RE[num].rig=false;RE[num].type=-1;
                RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                ++num;
            }
        }
    }

    public static void init(){//初始化把数组转换为ArrayList,容易查找
        keyWords=new ArrayList<>();
        operations=new ArrayList<>();
        symbols=new ArrayList<>();
        Collections.addAll(keyWords,keyWord);
        Collections.addAll(symbols,symbol);
        Collections.addAll(operations,operation);
    }
    public static void analyze(String str){
        k=0;
        char ch;
        str=str.trim();//去掉每一行前后的空格
        int n=str.length();
        if(biu){//判断是不是会在下一行注释结束
            for(int i=0;i<n-1;++i){
                if(str.charAt(i)=='*'&&str.charAt(i+1)=='/'){
                    biu=false;
                    k=i+2;//从多行注释结束的下一个字符开始分析
                    break;
                }
            }
        }
        if(biu)
            return;//如果当前没有多行注释结束标志,说明这一行还是注释,直接跳过
        for ( ;k<str.length();k++){
            ch=str.charAt(k);
            if (Character.isDigit(ch))
                digitCheck(str);//3 4
            else if((words==false)&&(Character.isLetter(ch)||ch=='$'))//多行字符串时不能被1,2判断
                letterCheck(str);//1 2
            else if (words==true||ch=='"')//多行字符串的情况或者双引号开头都要归为第5类判断
                stringCheck(str);//5
            else if(ch=='\'')
                charCheck(str);//6
            else if (ch==' ')
                continue;
            else {
                symbolCheck(str);//7 8
                if(mark||biu)
                    return;
            }

        }
    }

    public static void main(String[] args) {
        init();
        File file=new File("D:\\Java_code\\Beijing\\src\\score3.txt");
        try(Scanner in=new Scanner(file)) {
            while (in.hasNextLine()){
                String str=in.nextLine();//每次读取一行
                cols=0;//每一次换行的列数 都要从头计数
                ok=false;
                mark=false;//每一行新判断的时候都应该把注释记录清空
                //biu=false;  多行注释的消除只能通过再一次遇到*/才行,不是每次循环设为false
                //只要出现2个斜杠它后面就得是注释,不管后面还有啥,2个斜杠是肯定把后面的东西都注释掉了
                if(!words){//当有多行字符串时,要保存之前的行和列,所以就不对其清零了。并且数组也不从0开始保存
                    num=0;//表示一行中分析到词的个数
                    for(int i=0;i<N;++i){
                        RE[i]=new Results();//必须要先对每一个对象先实例化之后再对其赋值,否则会报空指针的错误
                        RE[i].rig=true;RE[i].type=0;
                        RE[i].res="";RE[i].li=0;RE[i].co=0;
                    }
                }
                int len=str.length();
                a[++lines]=len;//用数组存放每一行有多少列
                if(str.trim().length()!=a[lines]) {//如果前面有空格,就先把相差的空格数记上
                    blank=(a[lines] - str.trim().length());
                    ok=true;//只有开头有空格时ok才为true,在句子中时或者句子前没空格时ok为false
                }
                analyze(str);
                for(int i=0;i<num;++i){//在主函数中输出信息
                    if(RE[i].rig)
                        System.out.println("("+RE[i].type+","+RE[i].res+","+RE[i].li+","+RE[i].co+")");
                    else
                        System.out.println(RE[i].li+"line"+": "+RE[i].res+" Error");
                }
            }
        }
        catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}


在这里插入图片描述
图1-1 总体架构设计


在这里插入图片描述
图1-2 词法分析程序


在这里插入图片描述

图1-3 取字符和统计字符行列位置



时间:2023年5月12日17:12:42

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/518775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

门店销售干货 | 4种不同类型的顾客VS销售技巧,直接套用!

“我就路过随便看看” “我在别人家看到的更便宜” “我自己看&#xff0c;你不要跟着我” “我下次再买” …… 在日常的门店经营过程中&#xff0c;你是否经常遇到不同类型的顾客&#xff0c;用各种不同的话拒绝你&#xff0c;最后成交的寥寥无几。 面对不同这样不同类型…

java异常总结

java异常总结 什么是异常&#xff1f; 在Java中&#xff0c;将程序执行过程中发生的不正常行为称为异常。 常见异常举例 1.算数异常ArithmeticException public class Test{public static void main(String[] args) {System.out.println(10/0);} }报错 ArithmeticExcept…

webhub123整理 中文语音识别数据集​

我们收集和整理了常用的中文语音识别数据集&#xff0c;合计超过12000小时的数据集。已经按照不同来源整理收录到 webhub123整理 中文语音识别数据集​https://www.webhub123.com/#/home/detail?projectHashid64335220&ownerUserid22053727 整理后的效果如下 ​ 每个卡片…

mysql Lock wait timeout exceeded; try restarting transaction

文章目录 一、mysql死锁及超时的原因二、mysql死锁排查思路1、show full processlist 查询当前数据库全部线程2、information_schema 一、mysql死锁及超时的原因 当在业务逻辑中看到这个错误&#xff0c;或者mysql中使用update语句更新数据报错&#xff1a; Lock wait timeout…

数影周报:丰田215万名日本客户信息被无意泄露,菜鸟将于明年初在港IPO

本周看点&#xff1a;丰田215万名日本客户信息被无意泄露&#xff1b;美光宣布吴明霞出任美光中国区总经理&#xff1b;谷歌将向Gmail用户提供暗网数据泄露报告&#xff1b;淘宝天猫集团架构调整完成&#xff1b;菜鸟计划于2024年初在香港IPO...... 数据安全那些事 丰田215万名…

体验了基于ChatGPT的谷歌翻译插件后,我把其他翻译插件移除了

最近&#xff0c;一个基于 ChatGPT 的谷歌浏览器翻译插件挺火的&#xff0c;我体验了下&#xff0c;总结下来就一个字“666”。 github 上已经有 14.9k 的 star 了 传送门&#xff1a;GitHub - yetone/openai-translator: 基于 ChatGPT API 的划词翻译浏览器插件和跨平台桌面端…

AI学术界无人后继?高校毕业生纷纷进厂,全是香饽饽

来源 | 新智元 微信号&#xff1a;AI-era 【导读】近日&#xff0c;有外媒对一批美国名校的大学生和教授进行了采访。结果显示&#xff0c;高校毕业生入职科技公司已成主流。 AI火&#xff0c;搞AI的人就火。 这不&#xff0c;据Insider最近的一次采访报道&#xff0c;科技类…

Vue3-黑马(五)

目录&#xff1a; &#xff08;1&#xff09;vue3-基础-axios-拦截器 &#xff08;2&#xff09;vue3-基础-条件与列表 &#xff08;3&#xff09;vue3- 基础-监听器 &#xff08;1&#xff09;vue3-基础-axios-拦截器 我们自己创建axios对象有一个好处&#xff0c;就是可以…

[译] Flutter 3.10 的新功能

[译] Flutter 3.10 的新功能 原文 https://medium.com/flutter/whats-new-in-flutter-3-10-b21db2c38c73 无缝的Web和移动端集成&#xff0c;Impeller稳定版的突破性图形性能&#xff0c;以及更多 欢迎使用Flutter 3.10&#xff01;我们非常期待展示我们令人惊叹的Flutter社区所…

java可视化开发工具好用不好用?

java可视化开发工具到底好用不好用&#xff1f;这是不少粉丝朋友经常询问到的一个问题。在数字化发展趋势越发明显的当下&#xff0c;java可视化开发工具可以帮助各中大型企业实现转型升级&#xff0c;它的灵活、简洁、易操作、可视化等功能优势&#xff0c;让很多客户朋友欣慰…

OLYMP‘ARTS 2023奥艺大会中国推介会在北京盛大举行

北京时间2023年5月11日16时&#xff0c;以“艺术连接世界”为主题的OLYMPARTS 2023 国际奥艺大会中国推介会在北京盛大举行。此次活动由国际奥艺委员会&#xff08;WOAC&#xff09;指导支持&#xff0c;共邀请了国外驻华机构、文旅部、央国企、国内外协会机构、知名艺术家代表…

【项目源码】智慧班牌源码 家校互联小程序源码 智慧校园云平台

智慧校园平台源码 智慧班牌源码 人脸识别技术 电子班牌源码 家校互联小程序源码 源码开发环境&#xff1a;Javaspringbootvueelement-uimysql 智慧校园系统定位于中小学教育学校&#xff0c;侧重实际应用&#xff0c;讲究实际&#xff0c;突出加强校园安全监管&#xff0c;德…

【数值模型系列】CMAQ全局属性修改

一、问题产生 在做一个月的浓度预测时&#xff0c;由于GFS只能预报16天左右&#xff0c;因此需要使用CFS气象数据来驱动WRF模型&#xff0c;但CFS在WRF4.x版本有问题&#xff0c;因此重新装了WRF3.9.1版本的WRF。 而我这里的CMAQ ICON会去取前一天的CCTM CONC制作新的ICON文件…

ImageBind 横跨六种数据模式,用向量统一 AI 语言

出品人&#xff1a;Towhee 技术团队 作者&#xff1a;顾梦佳 人工智能&#xff08;AI&#xff09;最近毋庸置疑又迎来了一个高速发展的浪潮。 目前&#xff0c;人工智能的应用已经渗透到各个领域&#xff0c;包括自然语言处理、计算机视觉、语音识别、机器人技术等&#xff0c;…

如何自己搭建Scrapy爬虫框架

前言 当你学了一段时间爬虫后&#xff0c;就会知道各种功能太多而且麻烦。还不如自己整理个框架方便的多。因此&#xff0c;从开始写爬虫程序开始&#xff0c;就会慢慢的接触到一些有关爬虫的框架、效率提升而且扩展也很方便。接下来我将会以Scrapy爬虫框架将我的学习过程记录下…

查找符合条件,且不重复的数据 +++ EXCEL的数组公式(未完成)

查找符合条件&#xff0c;且不重复的数据 1 目标问题 查找第1列&#xff0c;月份为5月&#xff0c;并且第2列不重复的数据个数有2个条件 有的版本有唯一计数&#xff0c;有的没有 2 比较简单的方法 2.1 加辅助列&#xff0c;简单公式&#xff0c;其实逻辑是更清晰的 这里主要…

【数据结构】和栈一样简单的结构——队列

【数据结构】和栈一样简单的结构——队列 一、前言1、什么是队列&#xff1f;2、使用什么结构实现&#xff1f; 二、目标三、实现1、初始化工作2、入队2.1、图解思路2.2、代码实现 3、出队3.1、图解思路3.2、代码实现 4、打印队列(用于测试)5、返回队头元素6、返回队尾元素7、返…

Android工程师复盘小米、滴滴的面试全过程,网易offer已收入囊中

背景 时间过的真快&#xff0c;16年毕业到现在也有好几年了&#xff0c;最近面试试着投了几十家Android framework工程师的岗位&#xff0c;也面试了好几家&#xff0c;其中包括滴滴出行、小米、合众新能源、网易、最终收到了网易和滴滴offer&#xff0c;小米二面挂掉&#xf…

四、Eureka注册中心集群配置

目录 需要两个eureka server项目&#xff0c;之前已经有一个springcloud-eureka 1、在springcloud项目下新建一个聚合项目springcloud-eureka2 2、修改springcloud-eureka2的pom文件&#xff0c;引入eureka-server依赖 3、增加springcloud-eureka2的启动类&#xff0c;开启…

五、基于服务发现获取并访问远程接口

目录 1、在springcloud-order项目中新建controller供外部远程访问 2、在springcloud-member项目中新建controller去访问远程接口 3、运行springcloud-eureka、springcloud-member、springcloud-order项目的启动类 4、访问member服务的接口&#xff0c;通过member服务调用or…