实验3 词法分析(二)

devtools/2025/2/8 10:01:31/

实验3 词法分析(二)

[实验目的]:
1 . 熟悉给定的词法分析程序;
2 . 改进词法分析程序。
[实验内容]:
1.尝试多方面改进TEST语言的文法,参考教材附录B词法分析程序TESTscan.c,在此词法分析程序的基础上改进程序,并编程运行。(第3章习题6给出了需要改进的程序功能要求)
2.输入一段TEST源程序并以文件形式保存,运行改进后的TEST词法程序,查看词法分析输出文件,检查是否与改进要求一致。
[实验要求]:
每位同学撰写一份试验报告,并提交电子版的源程序和实验报告。
实验报告的要求:
1.写出改进的文法;
2.写出改进部分的程序。(可在原程序上将改进部分标红色字体)
3.心得体会的总结

1.写出改进的文法:
标识符:允许的标识符现在必须以字母或下划线开头,后面可以跟字母、数字或下划线。这修正了标识符的定义,使其符合编程语言中常见的约定。
数字: 增加了对十六进制(以0x开头)和二进制(以0b开头)的支持,使得数字表示的范围更广。
字符串: 字符串现在用双引号(")包围,可以包含普通字符和转义字符,增强了语言的表达能力。
注释: 增加了多行注释和单行注释的功能,提升了程序的可读性。

2.写出改进部分的程序。(可在原程序上将改进部分标红色字体)

#include <stdio.h>
#include <ctype.h>
#include <string.h>
// 下面定义保留,为简化程序,使用字符指针数组保存所有保留字。
// 如果想增加保留字,可继续添加,并修改保留字数目
#define keywordSum 9
char *keyword[keywordSum] = {"do", "if", "else", "for", "while", "do", "int", "read", "write"};
// 下面定义纯单分界符,如需要可添加
// 添加了!的处理
char singleword[50] = "+-*(){};,:!";
// 下面定义双分界符的首字符
// 添加了&&和||的处理
char doubleword[10] = "><=!&|";
extern char Scanin[300], Scanout[300]; // 用于接收输入输出文件名,在TEST_main.c中定义
extern FILE *fin, *fout; // 用于指向输入输出文件的指针,在TEST_main.c中定义
int TESTscan() { // 词法分析函数char ch, token[40]; // ch为每次读入的字符,token用于保存识别出的单词int es = 0, j, n; // es错误代码,0表示没有错误。j,n为临时变量,控制组合单词时的下标等printf("请输入源程序文件名(包括路径):");scanf("%s", Scanin);printf("请输入词法分析输出文件名(包括路径):");scanf("%s", Scanout);if ((fin = fopen(Scanin, "r")) == NULL) { // 判断输入文件名是否正确printf("\n打开词法分析输入文件出错!\n");return (1); // 输入文件出错返回错误代码1}if ((fout = fopen(Scanout, "w")) == NULL) { // 判断输出文件名是否正确printf("\n创建词法分析输出文件出错!\n");return (2); // 输出文件出错返回错误代码2}ch = getc(fin);while (ch != EOF) {while (ch == ' ' || ch == '\n' || ch == '\t')ch = getc(fin);if (ch == EOF)break;if (isalpha(ch)) { // 如果是字母,则进行标识符处理token[0] = ch;j = 1;ch = getc(fin);while (isalnum(ch)) { // 如果是字母数字则组合标识符;如果不是则标识符组合结束token[j++] = ch; // 组合的标识符保存在token中ch = getc(fin); // 读下一个字符}token[j] = '\0'; // 标识符组合结束// 查保留字n = 0;while ((n < keywordSum) && strcmp(token, keyword[n]))n++;if (n >= keywordSum) // 不是保留字,输出标识符fprintf(fout, "%s\t%s\n", "ID", token); // 输出标识符符号else  // 是保留字,输出保留字fprintf(fout, "%s\t%s\n", token, token); // 输出保留字符号} else if (isdigit(ch)) { // 数字处理token[0] = ch;j = 1;ch = getc(fin); // 读下一个字符while (isdigit(ch)) { // 如果是数字则组合整数;如果不是则整数组合结束token[j++] = ch; // 组合整数保存在token中ch = getc(fin); // 读下一个字符}token[j] = '\0';  // 整数组合结束fprintf(fout, "%s\t%s\n", "NUM", token); // 输出整数符号} else if (strchr(singleword, ch) > 0) { // 单分符处理token[0] = ch;token[1] = '\0';ch = getc(fin);// 读下一个符号以便识别下一个单词fprintf(fout, "%s\t%s\n", token, token); // 输出单分界符符号} else if (strchr(doubleword, ch) > 0) { // 双分界符处理token[0] = ch;ch = getc(fin); // 读下一个字符判断是否为双分界符if (ch == '=') { // 如果是=,组合双分界符token[1] = ch;token[2] = '\0'; // 组合双分界符结束ch = getc(fin); // 读下一个符号以便识别下一个单词} else if (ch == '&') {// 新加双分界符 &token[1] = ch;token[2] = '\0';ch = getc(fin);} else if (ch == '|') {// 新加双分界符 |token[1] = ch;token[2] = '\0';ch = getc(fin);} else // 不是=则为单分界符token[1] = '\0';fprintf(fout, "%s\t%s\n", token, token); // 输出单或双分界符符号} else if (ch == '/') { // 注释处理ch = getc(fin); // 读下一个字符if (ch == '*') { // 如果是*,则开始处理注释char ch1;ch1 = getc(fin); // 读下一个字符do {ch = ch1;ch1 = getc(fin);} // 删除注释while ((ch != '*' || ch1 != '/') && ch1 != EOF); // 直到遇到注释结束符*/或文件尾ch = getc(fin); // 读下一个符号以便识别下一个单词} else { // 不是*则处理单分界符/token[0] = '/';token[1] = '\0';fprintf(fout, "%s\t%s\n", token, token); // 输出单分界符/}} else { // 错误处理token[0] = ch;token[1] = '\0';ch = getc(fin); // 读下一个符号以便识别下一个单词es = 3;  // 设置错误代码fprintf(fout, "%s\t%s\n", "ERROR", token); // 输出错误符号}}fclose(fin); // 关闭输入输出文件fclose(fout);return (es); // 返回主程序
}
#include <stdio.h>
#include "TESTscan.h"
extern int TESTscan();char Scanin[300], Scanout[300];FILE *fin, *fout;int main() {int es = 0;es = TESTscan();if (es > 0) {printf("词法分析有误,编译停止\n");} else {printf("词法分析成功\n");}
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
3.心得体会的总结
加深了对词法分析原理的理解,还提高了编程实践和调试能力,更加熟悉和掌握了编译器设计的基本流程和技术。


http://www.ppmy.cn/devtools/157071.html

相关文章

《Node.js Express 框架》

《Node.js Express 框架》 引言 Node.js 是一种基于 Chrome V8 引擎的 JavaScript 运行环境,它允许开发者使用 JavaScript 来编写服务器端代码。Express 是一个简洁、灵活的 Node.js Web 应用框架,它为 Web 和移动应用程序提供了一系列强大的功能。本文将详细介绍 Node.js …

Mac: docker安装以后报错Command not found: docker

文章目录 前言解决办法&#xff08;新的&#xff09;解决步骤&#xff08;原来的&#xff09;不推荐总结 前言 ​本操作参考 http://blog.csdn.net/enhenglhm/article/details/137955756 原作者&#xff0c;更详细请&#xff0c;查看详细内容请关注原作者。 一般&#xff0c;…

python编程-类结构,lambda语法,原始字符串

一个类的基本结构包括以下部分&#xff1a; 类名&#xff1a;用来描述具有相同属性和方法的对象的集合。 属性&#xff1a;类变量或实例变量&#xff0c;用于处理类及其实例对象的相关数据。 方法&#xff1a;在类中定义的函数&#xff0c;用于执行特定操作。 构造器&#xff…

TCN时间卷积神经网络多变量多步光伏功率预测(Matlab)

代码下载&#xff1a;TCN时间卷积神经网络多变量多步光伏功率预测&#xff08;Matlab&#xff09; TCN时间卷积神经网络多变量多步光伏功率预测 一、引言 1.1、研究背景和意义 随着全球能源危机的加剧和环保意识的提升&#xff0c;可再生能源&#xff0c;尤其是太阳能&…

ubuntu20.04+RTX4060Ti大模型环境安装

装显卡驱动 这里是重点&#xff0c;因为我是跑深度学习的&#xff0c;要用CUDA&#xff0c;所以必须得装官方的驱动&#xff0c;Ubuntu的附件驱动可能不太行. 进入官网https://www.nvidia.cn/geforce/drivers/&#xff0c;选择类型&#xff0c;最新版本下载。 挨个运行&#…

云上考场微信小程序的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

2025Java面试题超详细整理《微服务篇》

什么是微服务架构&#xff1f; 微服务框架是将某个应用程序开发划分为许多独立小型服务&#xff0c;实现敏捷开发和部署&#xff0c;这些服务一般围绕业务规则进行构建&#xff0c;可以用不同的语言开发&#xff0c;使用不同的数据存储&#xff0c;最终使得每个服务运行在自己…

k8s,1.修改容器内主机名和/etc/hosts 文件,2.root特权容器,3.pod安全策略(基于名称空间

1.修改容器内主机名和/etc/hosts 文件,让持久生效,通过修改资源清单方式---kind: PodapiVersion: v1metadata:name: rootspec:hostname: myhost # 修改主机名hostAliases: # 修改 /etc/hosts- ip: 192.168.88.240 # IP 地址hostnames: # 名…