编译原理实验课

本人没咋学编译原理,能力有限,写的不好轻点喷,大佬路过的话,那你就路过就好

东大编译原理实验课原题,22年

1. 基本题:简单的扫描器设计

【问题描述】

熟悉并实现一个简单的扫描器,设计扫描器的自动机;设计翻译、生成Token的算法;编写代码并上机调试运行通过。

要求扫描器可识别的单词包括:关键字、界符、标识符和常整形数。

其中关键字表、界符表、标识符表、常整数表如下:(表中没有的关键字、界符等可以接着编号继续扩展)
在这里插入图片描述
【输入形式】源程序文件

【输出形式】

相应单词的Token序列;

标识符表,常数表。

【样例输入】

x10=x+y1*120+10;

【样例输出】

注意每行输出最后没有多余空格,最后一行输出后不换行。

Token :(I 1)(P 11)(I 2)(P 8)(I 3)(P 9)(C 1)(P 8)(C 2)(P 13)
I :x10 x y1
C :120 10

大体思路

我这里用了unordered_map来对应存<string,int> ,但是unordered_map他存进去后的顺序是胡乱的,不利于输出,我就直接存到vector里输出了,建议可以用pair<string,int> 方便点。
然后就是把想到的一些关键字,界符什么的初始化一下。
文件输入输出就上网一查,很多用法都有,我这里用了一种比较方便的。

从文本里一行一行的读入数据,存到一个string变量里,然后就对这个string从头到尾跑一遍,分三种情况,第一种是界符,如果当前字符是界符,那就再看看下一个字母是不是+,=这样的能够满足==,++,–这样的符号。第二种情况就是第一个字母为数字,这种呢就要么是标识符,要么就是整数了,分情况讨论就行。第三种就是第一个字母是字母,那这种就是要么关键字,要么标识符了
过验收的代码(文件输入输出)
里边的小注释是我用来debug的,一些没用到的变量是给第二题的,第二题题目看着怪怪的,不想写了,也懒得改了

#include<iostream>
#include<unordered_map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<fstream>
using namespace std;
unordered_map<string,int> keyK;//这个无序是胡乱排序,也不按照自己输入的顺序,后来知道了懒得改了,直接套个vector输出吧
unordered_map<string,int> keyP;
unordered_map<string,int> keyI;
unordered_map<string,int> keyC1;
unordered_map<string,int> keyC2;
unordered_map<string,int> keyCT;
unordered_map<string,int> keyST;
vector<string> I;
vector<string> C1;
vector<string> C2;
vector<string> CT;
vector<string> ST;
int idxI=1,idxC1=1,idxC2=1,idxCT=1,idxST=1;
int kind(char ch)
{if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return 1;if (ch>='0'&&ch<='9') return 2;if (ch=='-'||ch=='/'||ch=='('||ch==')'||ch=='='||ch=='<'||ch=='>'||ch=='+'||ch=='*'||ch==','||ch==';'||ch=='{'||ch=='}'||ch=='"') return 3;return 0;
}
void init()
{keyK["int"]=1,keyK["void"]=2,keyK["break"]=3,keyK["float"]=4,keyK["while"]=5;keyK["do"]=6,keyK["struct"]=7,keyK["const"]=8,keyK["case"]=9,keyK["for"]=10;keyK["return"]=11,keyK["if"]=12,keyK["default"]=13,keyK["else"]=14;keyK["long"]=15,keyK["short"]=16,keyK["double"]=17,keyK["char"]=18;keyK["unsigned"]=19,keyK["signed"]=20,keyK["union"]=21,keyK["goto"]=22;keyK["switch"]=23,keyK["continue"]=24,keyK["typedef"]=25,keyK["cout"]=26;keyK["cin"]=27,keyK["main"]=28,keyK["printf"]=29,keyK["scanf"]=30;keyP["-"]=1,keyP["/"]=2,keyP["("]=3,keyP[")"]=4,keyP["=="]=5,keyP["<="]=6;keyP["<"]=7,keyP["+"]=8,keyP["*"]=9,keyP[">"]=10,keyP["="]=11,keyP[","]=12;keyP[";"]=13,keyP["++"]=14,keyP["{"]=15,keyP["}"]=16,keyP["["]=17,keyP["]"]=18;}
int main()
{init();//for (auto i:keyK) cout<<i.first<<" "<<i.second<<"\n";//for (auto i:keyP) cout<<i.first<<" "<<i.second<<"\n";ifstream infile;infile.open("data2.txt",ios::in);if (!infile.is_open()){printf("Not found file!\n");return 0;}cout<<"Token :";string input;while(getline(infile,input)){for (int i=0;i<(int)input.size();i++){string tmp;//cout<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";if (kind(input[i])==3) {//cout<<"i=P"<<i<<" ";string tt;if (input[i+1]=='='||input[i+1]=='+') {tt+=input[i];tt+=input[i+1];cout<<"(P "<<keyP[tt]<<")";i++;}else {tt+=input[i];cout<<"(P "<<keyP[tt]<<")";}}else if (kind(input[i])==2) {//cout<<"i=C"<<i<<" ";bool flag=false;while (kind(input[i])!=3) {if (kind(input[i])==1) flag=true;tmp+=input[i];i++;}i--;if (keyI.find(tmp)!=keyI.end()) {cout<<"(I "<<keyI[tmp]<<")";}else if (keyC1.find(tmp)!=keyC1.end()) {cout<<"(C1 "<<keyC1[tmp]<<")";}else {if (flag) {keyI[tmp]=idxI;I.push_back(tmp);cout<<"(I "<<idxI<<")";idxI++;}else {keyC1[tmp]=idxC1;C1.push_back(tmp);cout<<"(C1 "<<idxC1<<")";idxC1++;}}}else if (kind(input[i])==1) {//cout<<"i=K"<<i<<" ";bool Find=false;while (kind(input[i])!=3) {tmp+=input[i];if (keyK.find(tmp)!=keyK.end()) {Find=true;cout<<"(K "<<keyK[tmp]<<")";break;}i++;}if (Find) continue;i--;if (keyK.find(tmp)!=keyK.end()) {cout<<"(K "<<keyK[tmp]<<")";}else if (keyI.find(tmp)!=keyI.end()) {cout<<"(I "<<keyI[tmp]<<")";}else {keyI[tmp]=idxI;I.push_back(tmp);cout<<"(I "<<idxI<<")";idxI++;}}//cout<<"2 "<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";}}cout<<"\nI :";bool flag=false;for (auto i:I) {if (!flag) flag=true;else cout<<" ";cout<<i;}cout<<"\n";cout<<"C1 :";flag=false;for (auto i:C1) {if (!flag) flag=true;else cout<<" ";cout<<i;}return 0;
}

都能过测试点的代码,虽然说我感觉输出有点奇怪,但能满分就行,懒得管了

#include<iostream>
#include<unordered_map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<fstream>
using namespace std;
unordered_map<string,int> keyK;//这个无序是胡乱排序,也不按照自己输入的顺序,后来知道了懒得改了,直接套个vector输出吧
unordered_map<string,int> keyP;
unordered_map<string,int> keyI;
unordered_map<string,int> keyC;
vector<string> I;
vector<string> C;
int idxI=1,idxC=1;
int kind(char ch)
{if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return 1;if (ch>='0'&&ch<='9') return 2;if (ch=='-'||ch=='/'||ch=='('||ch==')'||ch=='='||ch=='<'||ch=='>'||ch=='+'||ch=='*'||ch==','||ch==';'||ch=='{'||ch=='}'||ch=='"') return 3;return 0;
}
void init()
{keyK["int"]=1,keyK["void"]=2,keyK["break"]=3,keyK["float"]=4,keyK["while"]=5;keyK["do"]=6,keyK["struct"]=7,keyK["const"]=8,keyK["case"]=9,keyK["for"]=10;keyK["return"]=11,keyK["if"]=12,keyK["default"]=13,keyK["else"]=14;keyK["long"]=15,keyK["short"]=16,keyK["double"]=17,keyK["char"]=18;keyK["unsigned"]=19,keyK["signed"]=20,keyK["union"]=21,keyK["goto"]=22;keyK["switch"]=23,keyK["continue"]=24,keyK["typedef"]=25,keyK["cout"]=26;keyK["cin"]=27,keyK["main"]=28,keyK["printf"]=29,keyK["scanf"]=30;keyP["-"]=1,keyP["/"]=2,keyP["("]=3,keyP[")"]=4,keyP["=="]=5,keyP["<="]=6;keyP["<"]=7,keyP["+"]=8,keyP["*"]=9,keyP[">"]=10,keyP["="]=11,keyP[","]=12;keyP[";"]=13,keyP["++"]=14,keyP["{"]=15,keyP["}"]=16,keyP["["]=17,keyP["]"]=18;}
int main()
{init();//for (auto i:keyK) cout<<i.first<<" "<<i.second<<"\n";//for (auto i:keyP) cout<<i.first<<" "<<i.second<<"\n";/*ifstream infile;infile.open("data2.txt",ios::in);if (!infile.is_open()){printf("Not found file!\n");return 0;}*/ //这里是文件输入输出,你就在cpp文件位置旁边建一个data2.txt文件就行cout<<"Token :";string input;while(getline(cin,input)){for (int i=0;i<(int)input.size();i++){string tmp;//cout<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";if (kind(input[i])==3) {//cout<<"i=P"<<i<<" ";string tt;if (input[i+1]=='='||input[i+1]=='+') {tt+=input[i];tt+=input[i+1];cout<<"(P "<<keyP[tt]<<")";i++;}else {tt+=input[i];cout<<"(P "<<keyP[tt]<<")";}}else if (kind(input[i])==2) {//cout<<"i=C"<<i<<" ";bool flag=false;while (kind(input[i])!=3) {if (kind(input[i])==1) flag=true;tmp+=input[i];i++;}i--;if (keyI.find(tmp)!=keyI.end()) {cout<<"(I "<<keyI[tmp]<<")";}else if (keyC.find(tmp)!=keyC.end()) {cout<<"(C "<<keyC[tmp]<<")";}else {if (flag) {keyI[tmp]=idxI;I.push_back(tmp);cout<<"(I "<<idxI<<")";idxI++;}else {keyC[tmp]=idxC;C.push_back(tmp);cout<<"(C "<<idxC<<")";idxC++;}}}else if (kind(input[i])==1) {//cout<<"i=K"<<i<<" ";bool Find=false;while (kind(input[i])!=3) {tmp+=input[i];if (keyK.find(tmp)!=keyK.end()) {Find=true;cout<<"(K "<<keyK[tmp]<<")";break;}i++;}if (Find) continue;i--;if (keyK.find(tmp)!=keyK.end()) {cout<<"(K "<<keyK[tmp]<<")";}else if (keyI.find(tmp)!=keyI.end()) {cout<<"(I "<<keyI[tmp]<<")";}else {keyI[tmp]=idxI;I.push_back(tmp);cout<<"(I "<<idxI<<")";idxI++;}}//cout<<"2 "<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";}}cout<<"\nI :";bool flag=false;for (auto i:I) {if (!flag) flag=true;else cout<<" ";cout<<i;}cout<<"\n";cout<<"C :";flag=false;for (auto i:C) {if (!flag) flag=true;else cout<<" ";cout<<i;}return 0;
}

2. 扩展题:扫描器类的设计

【问题描述】

熟悉并实现一个简单的扫描器,设计扫描器的自动机;设计翻译、生成Token的算法;编写代码并上机调试运行通过。

扫描器可识别的单词包括:关键字、界符、标识符和常数(常数包括如:123 123.567 0.567 12.34e+23 …);

要求常整数输出按十进制输出(测试数据中只有16进制与10进制整数),浮点数考虑到精度问题按输入格式输出(测试数据只有10进制浮点数)。同时使用科学计数法的数字都是浮点数。为降低难度,样例3给出一种边界情况供大家调试。

在面对诸如"a+++++b"以及"a+++b"这种丧心病狂的输入时,界符匹配按照从左向右贪心匹配最长界符的策略进行匹配。

判断字符常量及字符串常量单词,将字符和字符串常量分别保存进单独的常量表CT、ST。例如’a’、”OK”;同时字符串与字符常量均不考虑转义字符("“和带”"的都不考虑)。

可以识别简单的词法错误主要形式为’sdddd’、1.sdasf等,尚未定义的单词等。

其中关键字表、界符表、标识符表、常整数表、常实数表、字符表、字符串表如下:(表中除关键词与界符表的表都可以接着编号继续扩展)

在这里插入图片描述
【输入形式】一行带空格的输入。其中关于数字,对于整型保证仅需考虑10进制与16进制数据,对于浮点型保证仅需考虑10进制数据。

【输出形式】

相应单词的Token序列;

标识符表,整数表,实数表,字符表,字符串表

如果错误则输出"ERROR"。
样例输入】

样例1输入:
120+10.3*12.3e-1;样例2输入:
a="xyz";样例3输入:
int a=12.1; float b=15e2, c=0x15e2;样例4输入:
int a='label';

【样例输出】

样例1输出:
Token :(C1 1)(P 8)(C2 1)(P 9)(C2 2)(P 13)
I :
C1 :120
C2 :10.3 12.3e-1
CT :
ST :样例2输出:
Token :(I 1)(P 11)(ST 1)(P 13)
I :a
C1 :
C2 :
CT :
ST :xyz样例3输出:
Token :(K 1)(I 1)(P 11)(C2 1)(P 13)(K 4)(I 2)(P 11)(C2 2)(P 12)(I 3)(P 11)(C1 1)(P 13)
I :a b c 
C1 :5602 
C2 :12.1 15e2 
CT :
ST :样例4输出:
ERROR

语文不好看这第二题题目看的实在蛋疼,小弟这两天事比较多,日后有缘再补下题

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

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

相关文章

nosql数据库 redis

一、介绍 1、redis与mysql的区别&#xff1a; Redis是一种基于键值对的内存数据库&#xff0c;数据存储在内存中&#xff0c;因此读写速度非常快。它支持多种数据结构&#xff0c;如字符串、哈希、列表等。 MySQL是一种关系型数据库&#xff0c;数据以表格的形式组织存储在磁…

探索 Python 的动态类型系统:变量引用、不可变性及高效内存管理与垃圾回收机制的深入分析

文章目录 1. 动态类型及其内存管理解析1.1 变量与对象的引用关系1.2 对象的不可变性和内存地址的变化 2. 垃圾回收与内存优化策略2.1 动态内存分配的基础2.2 Python 的垃圾回收 Python作为一种流行的高级编程语言&#xff0c;以其代码的易读性和简洁性著称。尤其是它的动态类型…

泛私域新引擎:小程序AI智能名片S2B2C商城的分销式导购策略与案例剖析

在数字化浪潮的推动下&#xff0c;小程序AI智能名片S2B2C商城以其独特的分销式导购能力&#xff0c;逐渐在泛私域的特殊场景中占据了一席之地。这种模式不仅打破了传统线上线下的界限&#xff0c;更通过以人为核心的营销方式&#xff0c;实现了利益驱动的深度分销。 分销式导购…

Git学习笔记(四)远程仓库

根据前面几篇文章的介绍&#xff0c;在本地使用Git基本不成问题了&#xff0c;常用的基本命令和一些基本概念基本也介绍完毕了。这一张主要讲讲远程仓库的创建和使用。 概念 其实在前面第一篇文章中&#xff0c;我们就简单介绍过远程仓库&#xff0c;它其实就是一个托管在远程服…

yolo-驾驶行为监测:驾驶分心检测-抽烟打电话检测

在现代交通环境中&#xff0c;随着汽车技术的不断进步和智能驾驶辅助系统的普及&#xff0c;驾驶安全成为了公众关注的焦点之一 。 分心驾驶&#xff0c;尤其是抽烟、打电话等行为&#xff0c;是导致交通事故频发的重要因素。为了解决这一问题&#xff0c;研究人员和工程师们…

19-ESP32-S3外设IIC

ESP32-S3的IIC 引言 ESP32-S3是一款集成了Wi-Fi和蓝牙功能的低成本、多功能微控制器。在这篇博客中&#xff0c;我们将详细介绍ESP32-S3的IIC&#xff08;Inter-Integrated Circuit&#xff09;接口&#xff0c;也被称为I2C。 IIC简介 IIC是一种串行、同步、多设备、半双工…

CTF网络安全大赛详情

网络安全已成为现代社会的一个关键挑战&#xff0c;随着互联网技术的飞速发展&#xff0c;从个人隐私保护到国家安全&#xff0c;网络安全的重要性日益突显。为了应对这一挑战&#xff0c;CTF&#xff08;Capture The Flag&#xff0c;中文&#xff1a;夺旗赛&#xff09;应运而…

openEuler-22.03下载、安装

一、下载 下载地址&#xff1a;openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网 下载版本&#xff1a;openEuler-22.03-LTS-x86_64-dvd.iso 二、安装 配置完后开启虚拟机 设置完后&#xff0c;重启虚拟机 设置桥接模式的网络 cd /etc/sysconfig/network-scripts/ vi if…

LeetCode 2739. 总行驶距离

题目链接https://leetcode.cn/problems/total-distance-traveled/?envTypedaily-question&envId2024-04-25 简单题&#xff0c;看代码思考一下即可理解 class Solution {public int distanceTraveled(int mainTank, int additionalTank) {int res 0;while (mainTank >…

RK3568 学习笔记 : u-boot 千兆网络无法 ping 通PC问题的解决

前言 开发板型号&#xff1a; 【正点原子】 的 RK3568 开发板 使用 虚拟机 ubuntu 20.04 收到单独 编译 RK3568 u-boot 【问题】u-boot 千兆网络无法ping 通&#xff1f;Linux 下千兆网络正常&#xff0c;说明&#xff1a;开发板硬件正常 u-boot 下网络如果通了&#xff0c;…

【高频】基于GBDT-FM模型的level-2高频数据实证研究(二)

【高频】基于GBDT-FM模型的level-2高频数据实证研究&#xff08;二&#xff09; 原创 Yud. 2AMquant 2024-04-04 11:30 广东 上一篇中初步提及了Level2数据中常见变量指标的构建方式&#xff0c;以及其带来的价格冲击。此篇将使用GBDT-LM模型对短程价格走势进行简单预测。 ps…

Nginx下载安装,什么是nginx,什么是反向代理,Windows下、linux下安装nginx(保姆级教程)

文章目录 一、Nginx简介为什么要使用NginxNginx的特点Nginx的相关概念正向代理反向代理动静分离负载均衡 二、Nginx安装1. Windows安装2. Linux安装 一、Nginx简介 Nginx 是一个高性能的 HTTP&#xff08;静态资源服务器&#xff09; 和 反向代理 Web 服务器。 为什么要使用N…

AI-数学-高中-44导数的运算法则

原作者视频&#xff1a;【导数】【一数辞典】3导数的运算法则&#xff08;略难&#xff09;_哔哩哔哩_bilibili 三种求导表达方式一样的&#xff0c;中间的比较常用&#xff1a; 链式法则&#xff1a;从外向内&#xff1a;

如何部署Tensorrtx

因为模型跑起来太慢了&#xff0c;所以想要运用tensorrtx进行加速。但是这个是有难度的&#xff0c;且网络上的教程大多写的不是很好。我将以一个新人的视角&#xff0c;从头开始部署基于yolov5的tensorrtx加速。 知识补充&#xff1a;TensorRT和TensorRTX的区别 tensorRT是英…

统一SQL 支持Oracle cast函数转换

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库&#xff1a;Oracle 目标数据库&#xff1a;Postgresql&#xff0c;TDSQL-MySQL&#xff0c;达梦8&#xff0c;LightDB-Oracle 操作目标 在Oracle中&#xff0c;cast函数允许将一种…

yolov8 区域声光报警+计数

yolov8 区域报警计数 1. 基础2. 报警功能2. 1声音报警代码2. 2画面显示报警代码 3. 完整代码4. 源码 1. 基础 本项目是在 yolov8 区域多类别计数 的基础上实现的&#xff0c;具体区域计数原理可见上边文章 2. 报警功能 设置一个区域region_points&#xff0c;当行人这一类别…

链栈的基本操作(c语言实现)

栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 栈的结构 定义栈…

JVM虚拟机监控及性能调优实战

目录 jvisualvm介绍 1. jvisualvm是JDK自带的可以远程监控内存&#xff0c;跟踪垃圾回收&#xff0c;执行时内存&#xff0c;CPU/线程分析&#xff0c;生成堆快照等的工具。 2. jvisualvm是从JDK1.6开始被继承到JDK中的。jvisualvm使用 jvisualvm监控远程服务器 开启远程监控…

智能家居—ESP32开发环境搭建

相关文章 毕业设计——基于ESP32的智能家居系统(语音识别、APP控制) 智能家居—ESP32开发环境搭建 一、下载安装二、验证三、资料获取 一、下载安装 下载安装 vscode 安装插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup c…

SpringMVC笔记——SpringMVC基础Tomcat环境配置

Tomcat安装配置 下载Apache Tomcat 进入官网https://tomcat.apache.org/&#xff0c;选择tomcat 9 这边使用idea开发&#xff0c;建议直接下载压缩包 无法访问下载的可以直接用我的下载链接&#xff1a;https://cloudreve.zxbdwy.online/s/6nSA 提取码&#xff1a;w1pwk3将压…