编译原理——扫描器设计与实现

改进了一下,加入了能够输出错误提示(注意:我们是用char接收的,但是遇到中文的时候因为码值的原因,一个中文字占三个char所以按照我们判断流程会输出三个错误提示,你们要是见意的话可以自行修改)

非常详细(包括跳过注释部分),不多说直接上代码(结合代码讲解)

#include<bits/stdc++.h>using namespace std;#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof(arr[0]))//关键词集合
string KEY_WORD[] = {"int","char","string","bool","float","double","true","false","return","if","else","while","for","default","do","public","static","switch","case","private","protected"};
//界符集合,我将'/'也加到界符表中用于判断是否是注释
char BOUND_CHAR[] = {',', ';', '(', ')', '{', '}', '[', ']', '\'', '\"', '/'};
int pos = 0;//当前读到的数的下标
short in_annotation = 0;//当前是否在注释的范围,1表示在并且是"//"这种类型,2表示在并且是"/**/"这种注释类型,默认不在(因为两种注释的退出条件不同)// 关键字,标识符,运算符,界符和常量
enum WordTypeKind{KEYWORD, IDENTIFIER, CONSTANT, OPERATOR, DELIMITER, ANNOTATION, ERROR, STOP
};//定义词
struct WORD {WordTypeKind wordType;string value;
};//读取文件中的内容
string openFile(string fileName) {ifstream readFile(fileName);//文件是否打开if(!readFile.is_open()) {cerr << "无法打开文件!" << '\n';return "";}string content, temp;while(getline(readFile, temp)) {// cout << content << endl;content += temp;content += '\n';}//关闭资源readFile.close();return content;
}//将字符串写入文件
bool writeFile(string fileName, string content) {ofstream writeFile(fileName);if(!writeFile.is_open()) {cerr << "无法打开文件!" << '\n';return false;}writeFile << content << endl;writeFile.close();return true;
}//判断一个单词是不是关键字,是返回true
bool isKeyWord(string word) {for(int i = 0; i < ARRAY_LENGTH(KEY_WORD); i++) {if(word == KEY_WORD[i]) return true;}return false;
}//分词器,将字符串分成最小单位(关键字,标识符,运算符,界符和常量),关键字我们可以自己根据使用的高级语句自定义
WORD getNextWord(string str) {string tempStr = "";//暂存这个单词WORD newWord;//返回的词newWord.wordType = STOP;//方便后续退出循环while (pos < str.length() && std::isspace(str[pos])) {if(in_annotation == 1 && str[pos] == '\n') in_annotation = 0;//退出注释状态++pos; // 跳过空白字符}if (pos >= str.length()) {return newWord; // 结束}if(pos < str.length()) {//不越界char c = str[pos++];tempStr += c;//标识符的命名规范:只能以字母或'_'开头if(isalpha(c) || c == '_') {//这个词是关键词或标识符// isalnum(str[pos])这个函数用来检查传递给它的字符是否是字母(isalpha)或者是数字(isdigit)while(pos < str.length() && (isalnum(str[pos]) || str[pos] == '_')) {tempStr += str[pos++];}//判断这个单词是标识符or关键字if(isKeyWord(tempStr)) {//是关键字newWord.wordType = KEYWORD;} else {//标识符newWord.wordType = IDENTIFIER;}} else if(isdigit(c)) {//数字开头只可能是常数,我们把所有数字读完while(pos < str.length() && isdigit(str[pos])) {tempStr += str[pos++];}newWord.wordType = CONSTANT;} else if(c >= 0 && c <= 127) {//只可能是运算符或界符for(int i = 0; i < ARRAY_LENGTH(BOUND_CHAR); i++) {//是不是界符if(c == BOUND_CHAR[i]) {//遇到'/'判断是不是注释和注释类型if(c == '/' && pos < str.length() && str[pos] == '/') {//是'//'类型in_annotation = 1; newWord.wordType = ANNOTATION;tempStr += str[pos++];newWord.value = tempStr;return newWord;} else if(c == '/' && pos < str.length() && str[pos] == '*') {//是'/**/'类型in_annotation = 2;newWord.wordType = ANNOTATION;tempStr += str[pos++];newWord.value = tempStr;return newWord;}newWord.wordType = DELIMITER;break;}}//是运算符,注意双目运算符(三目运算符我们就不考虑了)if(pos < str.length()) {//注意不要越界newWord.wordType = OPERATOR;char nextChar = str[pos];//特判一下'*/'的情况,因为这是第二种注释的退出标识if(c == '*' && nextChar == '/') {//退出注释状态,下面也不用看了in_annotation = 0;tempStr += nextChar;newWord.wordType = ANNOTATION;pos++;newWord.value = tempStr;return newWord;}//考虑一下所有的双目运算符if((c == '+' || c == '-' || c == '*' || c == '/' || c == '!' || c == '^' || c == '%' || c == '=' || c == '<' || c == '>') && nextChar == '=') {tempStr += nextChar;//更新一下nextCharpos++;}if(c == '+' && nextChar == '+') {tempStr += nextChar;//更新一下nextCharpos++;}if(c == '-' && nextChar == '-') {tempStr += nextChar;//更新一下nextCharpos++;}if(c == '&' && nextChar == '&') {tempStr += nextChar;//更新一下nextCharpos++;}if(c == '|' && nextChar == '|') {tempStr += nextChar;//更新一下nextCharpos++;}if(c == '<' && nextChar == '<') {tempStr += nextChar;//更新一下nextCharpos++;}if(c == '>' && nextChar == '>') {tempStr += nextChar;//更新一下nextCharpos++;}}} else {newWord.wordType = ERROR;}newWord.value = tempStr;}return newWord;
}//换行符占一个长度!!!int main() {//先读取txt文件string fileName = "E:\\program\\bianyiyuanli\\1.txt";string str = openFile(fileName);WORD word;while((word = getNextWord(str)).wordType != STOP) {if(word.wordType == ERROR && in_annotation == 0) cout << "出现ERROR!!!" << '\n';else if(word.wordType != ANNOTATION && in_annotation == 0) {//我们只有在词语不是注释类型和不在注释状态才输出它std::cout << "[" << word.wordType << ",   " << word.value << "]" << std::endl;}}return 1;
}

txt文件内容:

/*我好帅*/
int main() {
//你好
    int x = 10;
    好
    return x;

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JMeter】使用BeanShell写入内容到文件

一、前言 在我们日常工作中&#xff0c;可能会遇到需要将请求返回的数据写入到文件中。在我们使用JMeter进行性能测试时&#xff0c;就经常能够遇到这种情况。要想达到这种目的&#xff0c;我们一般采取BeanShell后置处理器来将内容写入到文件。 二、提取 在目前大多数的性能…

Java多线程编程实战:生产者与消费者问题的同步、互斥案例分析

前言 生产者和消费者模式是一个十分经典的多线程协作模式&#xff0c;该模式又称为等待唤醒机制。本质上就是打破多线程的随机性&#xff0c;使得线程轮流执行。 问题分析 生产者和消费者问题&#xff1a; 生产者生产数据&#xff0c;消费者消费数据&#xff0c;需要借助第三…

The First项目报告:Puffer Finance如何破解LST/LRT赛道中心化难题?

10月09日The First上线了一种基于以太坊的协议&#xff0c;引入了重新质押的概念的生态协议EigenLayer。10月15日&#xff0c;一款搭建在 Eigenlayer 上原生流动性再质押平台 Puffer Finance 宣布其原生代币 PUFFER 将于 2024 年 10 月 15 日 07时&#xff08;UTC8&#xff09;…

Java基于微信小程序的健身小助手打卡预约教学系统(源码+lw+部署文档+讲解等)

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

android11 usb摄像头添加多分辨率支持

部分借鉴于&#xff1a;https://blog.csdn.net/weixin_45639314/article/details/142210634 目录 一、需求介绍 二、UVC介绍 三、解析 四、补丁修改 1、预览的限制主要存在于hal层和framework层 2、添加所需要的分辨率&#xff1a; 3、hal层修改 4、frameworks 5、备…

多场景多任务建模(三): M2M(Multi-Scenario Multi-Task Meta Learning)

多场景建模: STAR(Star Topology Adaptive Recommender) 多场景建模&#xff08;二&#xff09;: SAR-Net&#xff08;Scenario-Aware Ranking Network&#xff09; 前面两篇文章&#xff0c;讲述了关于多场景的建模方案&#xff0c;其中可以看到很多关于多任务学习的影子&…

CSS网页布局(重塑网页布局)

一、实现两列布局 许多网站有一些特点&#xff0c;如页面顶部放置一个大的导航或广告条&#xff0c;右侧是链接或图片&#xff0c;左侧放置主要内容&#xff0c;页面底部放置版权信息等 一般情况&#xff0c;此类网页布局的两列都有固定的宽度&#xff0c;而且从内容上很容易区…

Cherno游戏引擎笔记(73~90)

------- scene viewport ---------- 》》》》做了两件事&#xff1a;设置视口和设置相机比例 》》》》为什么要设置 m_ViewportSize 为 glm::vec2 而不是 ImVec2 ? 因为后面需要进行 ! 运算&#xff0c;而 ImVec2 没有这个运算符的定义&#xff0c;只有 glm::vec2 有这个运算…

linux 下 verilog 简明开发环境附简单实例

author: hjjdebug date: 2024年 10月 12日 星期六 10:34:13 CST descripton: linux 下 verilog 简明开发环境附简单实例 甲: 安装软件 1. sudo apt install iverilog 该包verilog 源代码的编译器iverilog&#xff0c;其输出是可执行的仿真文件格式vvp格式 它可以检查源代码中…

高效办公必备:2024四款免费PDF转换器推荐!

PDF文件的管理和转换离不开一些PDF转换器的使用。今天就给大家盘点几个好用免费的PDF转换器&#xff0c;帮助大家轻松应对各种文档转换任务 福昕PDF转换大师&#xff08;365客户端&#xff09; 直达链接&#xff1a;www.pdf365.cn/pdf2word/ 操作教程&#xff1a;立即获取 …

Windows系统总是占用内存过高的解决方法

文章目录 1. Antimalware Service Executable占用CPU过多1.1 问题1.2 解决方法&#xff1a;关闭实时保护&#xff0c;并且添加排除项 2. wsappx占用CPU过多2.1 问题2.2 解决方法&#xff1a;关闭应用更新等选项 3. 内存一直高于50%3.1 解决方法1&#xff1a;关机&#xff0c;重…

关于新国标强制电动车应内置北斗定位模块的规定有哪些?附北斗定位芯片对比参数

关于新国标要求电动自行车内置的北斗定位功能&#xff0c;需要符合以下几点&#xff1a; 支持UART或SPI接口至少支持接收处理北斗B1C和B2a信号具备定位信息的采集、存储和发送功能&#xff08;其中定位信息包括&#xff1a;经度、纬度、速度、定位时间&#xff09;具备采集、存…

C++之多继承

普通的继承中,子类的虚表是从父类拷贝过来的,子类新增加的特有的虚函数&#xff0c;会添加在这个虚表里。参考文章&#xff1a;CSDN 多继承 问&#xff1a;如果A1、A2中有相同的虚函数&#xff0c;覆盖谁的&#xff1f; 答案&#xff1a;覆盖A1的 多继承还存在一种特殊情况——…

Docker SDK for Python 交互

目录 1. 创建 Docker 客户端 2. 列出所有容器 3. 容器内执行命令 4. 启动和停止容器 5. 创建和运行新容器 6. 获取容器日志 7. 删除容器 8. 处理镜像 使用 Docker SDK for Python 进行交互非常方便&#xff0c;可以执行各种操作&#xff0c;如管理容器、镜像、网络等。…

动态规划-简单多状态dp问题——714.买卖股票的最佳时机含手续费

1.题目解析 题目来源&#xff1a;714.买卖股票的最佳时机含手续费——力扣 测试用例 2.算法原理 1.状态表示 本题有两种状态&#xff0c;一种是卖出状态一种是买入状态 我们创建两个dp表来分别存储这两种状态&#xff0c;f[]表示买入&#xff0c;g[]表示卖出 f[i]表示第i个位…

一个Idea:爆改 T480

爆改 T480 准备大改 T480&#xff0c;家里有一台闲置很久的 T480&#xff0c;不舍得扔&#xff0c;打算升级一下。看了几位up主的视频后&#xff0c;决定动手改造。 计划如下 网卡&#xff1a;加装4G网卡硬盘&#xff1a;更换为 1T 的 NVMe 2280 固态硬盘内存&#xff1a;升…

WordPress添加meta标签做seo优化

一、使用function.php文件添加钩子函数添加 方法1、使用is_page()判断不同页面的page_id进行辨别添加不同页面keyword和description &#xff08;1&#xff09;通过页面前台源码查看对应页面的id &#xff08;2&#xff09;或者通过wordpress后台&#xff0c;点击页面列表&…

基于BeautyEye开发Java程序用户界面

文章目录 I idea引入jar包添加本地jar包maven方式引入本地包方式1:将第三方JAR包安装到本地仓库maven方式引入本地包方式2:引用本地路径将本地jar包打进war包Maven内置变量说明II BeautyEye Swing外观实现方案案例III 知识扩展Swing常用的顶级容器BeautyEye SwingI idea引入j…

南京邮电大学电工电子A实验十二(集成触发器及其应用和计数与分频电路)

文章目录 一、实验报告预览二、Word版本报告下载 一、实验报告预览 二、Word版本报告下载 点我

6本“灌水神刊”SCI,沾边可录,可选非OA,1个月Accept!

01 录用快刊 1、Drones • 影响因子&#xff1a;4.4 • 期刊分区&#xff1a;JCR1区&#xff0c;中科院2区 • 检索数据库&#xff1a;SCI • 征稿领域&#xff1a;该杂志主要关注无人机的设计和应用&#xff0c;包括无人机&#xff08;UAV&#xff09;、无人机系统&#x…