南京邮电大学编译原理实验一(词法分析器的构造)

news2024/10/6 18:32:07

文章目录

  • 一、 实验目的和要求
  • 二、实验环境(实验设备)
  • 三、实验原理及内容
    • (一)设计概要
      • 1、C++语言子集
      • 2、单词及编码
      • 3、状态转换图
    • (二)实现分析
    • (三)结果分析
  • 四、实验小结(包括问题和解决方法、心得体会、意见与建议等)
    • (一)实验中遇到的主要问题及解决方法
    • (二)实验心得
    • (三)意见与建议(没有可省略)

一、 实验目的和要求

设计、编制、调试一个词法分析程序,对单词进行识别和编码,加深对词法分析原理的理解。

二、实验环境(实验设备)

硬件:微型计算机
软件:Windows 操作系统、Visual Studio 2019

三、实验原理及内容

(一)设计概要

1、C++语言子集

(1) 关键字:
void、int、main、return、if、else
(2) 运算符和界限符:
+、-、*、/、%、=
;、(、)、[、]、{、}
(3) 整型常数(INT)和标识符(ID)通过正规文法定义
:= |
:= letter||(||)

2、单词及编码

基本符号类型类型说明
void1关键字
int1关键字
main1关键字
return1关键字
if1关键字
else1关键字
;2界限符
(2界限符
)2界限符
[2界限符
]2界限符
{2界限符
}2界限符
+3运算符
-3运算符
*3运算符
/3运算符
%3运算符
=3运算符
标识符4标识符
整常数5常量

3、状态转换图

在这里插入图片描述

(二)实现分析

1、代码
#include <iostream>
#include<fstream>
#define KEYWORD         1
#define DELIMITER       2
#define OPERATOR        3
#define IDENTIFIER      4
#define CONSTINTEGRAL   5
#define ELSE            0

// 关键词列表,界限符列表、运算符列表
std::string keyWord[] = { "void", "int", "char", "main", "return", "if", "else"};
std::string delimiter[] = { "(", ")", "[", "]", "{", "}", ";", "," };
std::string operator0[] = { "+", "-", "*", "/", "%", "=" };


// 检测 char 中字符是否为字母
bool Letter(char c) 
{
    if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') 
    {
        return true;
    }
    return false;
}

// 检测单词是否为关键字
bool KeyWord(std::string str)
{
    for (std::string p : keyWord)
    {
        if (p == str)
            return true;
    }
    return false;
}

// 判断单词是否是界限符
bool Delimiter(std::string str)
{
    for (std::string p : delimiter)
    {
        if (p == str)
            return true;
    }
    return false;
}

// 判断单词是否是运算符
bool Operator(std::string str)
{
    for (std::string p : operator0)
    {
        if (p == str)
            return true;
    }
    return false;
}

// 判断字符是否为数字
bool Digit(char c)
{
    if (c >= '0' && c <= '9')
    {
        return true;
    }
    return false;
}


// 由 token 查保留字表,若 token 中字符串为保留字符则返回其类别编码,否则返回值为0
int Reserve(std::string str)
{
    int type = ELSE;

    if (KeyWord(str))
        type = KEYWORD;

    else if (Delimiter(str))
        type = DELIMITER;

    else if (Operator(str))
        type = OPERATOR;

    else if (Digit(str[0])) 
        type = CONSTINTEGRAL;

    // 标识符
    else if (str[0] == '_' || Letter(str[0]))
    {
        type = IDENTIFIER;
        {
            for (int i = 1; i < str.length(); i++)
            {
                // 若不符合标识符规则,则type=0
                if (!(str[i] == '_' || Letter(str[i]) || Digit(str[i])))
                {
                    type = ELSE;
                    break;
                }
            }
        }
    }
    else
        type = ELSE;

    return type;
}

// 读取源代码文本文件
std::string ReadFile(std::string url)
{
    std::string token = "";
    char ch;
    std::ifstream infile;
    infile.open(url, std::ios::in);

    if (!infile.is_open())
    {
        std::cout << "文件无法打开!";
        return "";
    }

    infile >> ch;
    while (!infile.eof())
    {
        token = token + ch;
        infile >> ch;
    }


    infile.close();
    return token;
}


int main()
{
    // 读取源代码文本文件,将空格和回车删除
    std::string token = ReadFile("code.txt");

    // 打印处理后的源代码
    std::cout << "token = " << token << std::endl;

    // str 存入一个单词
    std::string str = "";
    int i = 0;

    // 依次遍历源代码中的每一个字符
    while(i < token.length())
    {
        str = "";
        // 数字开头
        if (Digit(token[i]))
        {                   
            while (Digit(token[i]))
                str = str + token[i++];
            // 打印分类结果
            std::cout << "(" << Reserve(str) << ", " << "\"" << str << "\"" << ")" << std::endl;
        }
        // 下划线或者字母开头的单词,即标识符或者关键字
        else if (token[i] == '_' || Letter(token[i]))
        {                     
            while (token[i] == '_' || Letter(token[i]) || Digit(token[i]))
            {
                str = str + token[i++];
                // 如果是关键字,立即结束
                if (Reserve(str) == KEYWORD)
                    break;
            }
            std::cout << "(" << Reserve(str) << ", " << "\"" << str << "\"" << ")" << std::endl;
        }
        // 运算符
        else {
            str = str + token[i++];
            std::cout << "(" << Reserve(str) << ", " << "\"" << str << "\"" << ")" << std::endl;
        }
    }
}

1、时间复杂度分析
时间复杂度为O(n)

(三)结果分析

1、 实验使用的源代码文本文件内容如下
在这里插入图片描述

2、实验结果
在这里插入图片描述

3、结果分析
各种单词均识别分类正确,实验正确
实 验 报 告

四、实验小结(包括问题和解决方法、心得体会、意见与建议等)

(一)实验中遇到的主要问题及解决方法

1、 在编译时,只有第一个标识符识别正确,从第二个标识符开始被识别成非法单词,后来经过调试,发现是在循环过程中,应该首先假设下划线或者字母开头的任意单词是标识符,然后再判断单词中是否出现其他非法字符
2、 在读取源代码文本文件时,无法读取到最后一个字符,后来通过调试,发现读取每个字符时,不能使用string类型变量保存读取到的字符,改用char类型变量读取后,能够正常读取文件内所有的字符。

(二)实验心得

1、熟悉了词法分析的过程
2、加深了对编译器分析源代码词法的理解

(三)意见与建议(没有可省略)

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

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

相关文章

文本纠错--N-gram--Macbert模型的调用以及对返回结果的处理

文本根据词典进行纠错 输入一段可能带有错误信息的文字&#xff0c; 通过词典来检测其中可能错误的词。 例如&#xff1a;有句子如下&#xff1a;中央人民政府驻澳门特别行政区联络办公室1日在机关大楼设灵堂    有词典如下&#xff1a;中国人民&#xff0c;中央人民&#x…

红帽曹衡康:开源是企业数字化转型的机遇

在数据成为企业核心资产的今天&#xff0c;为了更好地降本增效&#xff0c;实现业务创新和增长&#xff0c;越来越多的企业都开启了数字化转型之路。然而对于绝大多数企业来说&#xff0c;这条转型之路都并非一帆风顺。事实上&#xff0c;数字化转型在为企业开启更多机遇的同时…

爆火Chatgpt注册 chatgpt使用 完全指南

1 chatgpt 简介 ChatGPT是一种语言模型&#xff0c;它被训练来对对话进行建模。它能够通过学习和理解人类语言来进行对话&#xff0c;并能够生成适当的响应。ChatGPT使用了一种叫做Transformer的神经网络架构&#xff0c;这是一种用于处理序列数据的模型&#xff0c;能够在输入…

Java System类

JavaSystem类\huge{Java \space System类}Java System类 System类概述 简而言之&#xff1a;SystemSystemSystem类就是一个工具类&#xff0c;直接调用对应的方法来使用即可&#xff0c;不需要也不能被实例化。 常用方法 ①. exit() 退出Java虚拟机 //执行这个exit(0)代码之…

[附源码]计算机毕业设计的花店售卖系统的设计与实现Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

GPU——占用情况和进程情况的参数解读表

GPU——占用情况和进程情况的参数解读表一、GPU占用情况二、GPU的进程情况参考资料一、GPU占用情况 名称功能说明Fan风扇转速在0 (%) 到100 (%) 之间变动Temp摄氏温度CPerf性能状态从P0到P12&#xff0c;P0表示最大性能&#xff0c;P12表示状态最小性能Persistence-M持续模式的…

微服务框架 SpringCloud微服务架构 微服务保护 31 限流规则 31.2 流控模式【关联】

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务保护 文章目录微服务框架微服务保护31 限流规则31.2 流控模式【关联】31.2.1 流控模式31.2.2 流控模式 - 关联31.2.3 小结31 限流规则…

OpenCV入门(C++/Python)- 使用OpenCV色彩空间(七)

在本教程中&#xff0c;了解计算机视觉中使用的流行色彩空间&#xff0c;并将其用于基于颜色的分割。 使用OpenCV色彩空间不同的颜色空间RGB颜色空间LAB颜色空间YCrCB 颜色空间HSV颜色空间如何使用这些颜色空间进行分割简单方法文章内容如下&#xff1a;首先&#xff0c;我们将…

Linux线程的创建

用户态创建线程&#xff1a; 线程不是一个完全由内核实现的机制&#xff0c;它是由内核态和用户态合作完成的。pthread_create不是一个系统调用&#xff0c;是Glibc库的一个函数。 在nptl/pthread_creat.c里面找到了这个函数&#xff1a; int __pthread_create_2_1 (pthread…

直播预告 | SOFAChannel#31《RPC 框架设计的考和量》

SOFARPC 是蚂蚁集团开源的一款基于 Java 实现的 RPC 服务框架&#xff0c;为应用之间提供远程服务调用能力&#xff0c;具有高可伸缩性&#xff0c;高容错性&#xff0c;目前蚂蚁集团所有的业务的相互间的 RPC 调用都是采用 SOFARPC。SOFARPC 为用户提供了负载均衡&#xff0c;…

web课程设计网页制作、基于HTML+CSS大学校园班级网页设计

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

代码随想录刷题Day60 | 84. 柱状图中最大的矩形

代码随想录刷题Day60 | 84. 柱状图中最大的矩形 84. 柱状图中最大的矩形 题目&#xff1a; 定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: …

C++调用OpenCV实现图像阈值处理

1 前言 在计算机视觉技术中&#xff0c;阈值处理是一种非常重要的操作&#xff0c;它是很多高级算法的底层处理逻辑之一。比如在使用OpenCV检测图形时&#xff0c;通常要先对灰度图像进行阈值&#xff08;二值化&#xff09;处理&#xff0c;这样就得到了图像的大致轮廓&#…

English Learning - L1 站在高处建立灵魂 2022.12.5

English Learning - L1 站在高处建立灵魂 2022.12.51.1 到底什么是语法1.2 为什么要学习语法口语分广义和狭义讲母语的人为啥不学语法&#xff1f;作为一名二语习得者口语中可不可以没有有语法&#xff1f;1.3 英语&#xff08;听说读写&#xff09;的核心金字塔理论关于词汇量…

免费内网穿透工具测评对比,谁更好用 2

文章目录1. 前言2. 对比内容2.1 http协议功能及操作对比2.1.1 网云穿的http设置2.1.2 Cpolar的http设置2.2 使用感受对比3. 结语1. 前言 上篇文章&#xff0c;笔者对比了网云穿和Cpolar的直观内容&#xff0c;包括网站界面、客户端界面和内网穿透设置界面。总的来说&#xff0…

保姆级教程:手把手教你使用深度学习处理文本

大家好&#xff0c;今天给大家分享使用深度学习处理文本&#xff0c;更多技术干货&#xff0c;后面会陆续分享出来&#xff0c;感兴趣可以持续关注。 文章目录NLP技术历程准备数据标准化词元化Tokenization&#xff08;文本拆分&#xff09;技术提升建立索引表使用TextVectoriz…

开源开放 | 开源知识图谱抽取工具DeepKE发布更新

知识图谱是一种用图模型来描述知识和建模世界万物之间关联关系的大规模语义网络&#xff0c;是大数据时代知识表示的重要方式之一。近年来&#xff0c;知识图谱在辅助语义搜索、支持智能问答、增强推荐计算、提升语言语义理解和大数据分析能力等越来越多的技术领域得到重视&…

极客时间课程笔记:业务安全

业务安全 业务安全体系&#xff1a;对比基础安全&#xff0c;业务安全有哪些不同&#xff1f;业务安全和基础安全在本质上就有很大的不同&#xff1a;在基础安全中&#xff0c;黑客将技术作为核心竞争力&#xff1b;在业务安全中&#xff0c;黑产将资源作为核心竞争力。谁能够…

ADI Blackfin DSP处理器-BF533的开发详解23:SDRAM内存的设计和自检(含源代码)

硬件准备** ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 功能介绍 ADSP-EDU-BF53x 板卡上采用的 SDRAM 型号为 MT48LC16M16A2,容量为 32Mbyte&#xff0c;采用 16Bit 模式连接ADSP-BF53x。通过配置 EB…

【STM32】详解嵌入式中FLASH闪存的特性和代码示例

一、存储器 我们正常编译生成的二进制文件&#xff0c;需要下载烧录到单片机里面去&#xff0c;这个文件保存在单片机的ROM(read only memory)中&#xff0c;所有可以完成这种特性的存储介质都可以称为ROM。 分类 ROM一般分为四大类 ①PROM&#xff1a;可编程只读存储器&#…