编译原理实验课

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

东大编译原理实验课原题,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,一经查实,立即删除!

相关文章

Spring从零开始学使用系列(三)--依赖注入(DI)

目录 1.DI的核心概念 1.1优势 2. Spring中的DI实现 2.1 构造器注入 2.1.2 优势和缺点 2.2 设置器注入 2.2.1 如何使用设置器注入 2.2.2 示例代码 2.2.3优势和使用场景 2.3 字段注入 2.4 方法注入 2.4.1 方法注入的概念 2.4.2 找方法注入 2.4.3 Lookup 注解的作用 2…

nosql数据库 redis

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

【Python】使用Pandas和随机森林对鸢尾花数据集进行分类

我在鼓楼的夜色中 为你唱花香自来 在别处 沉默相遇和期待 飞机飞过 车水马龙的城市 千里之外 不离开 把所有的春天 都揉进了一个清晨 把所有停不下的言语变成秘密 关上了门 莫名的情愫啊 请问 谁来将它带走呢 只好把岁月化成歌 留在山河 &#x1f3b5; 鹿…

鸿蒙原生应用元服务-访问控制(权限)开发应用权限列表二

ohos.permission.ACCELEROMETER 允许应用读取加速度传感器的数据。 权限级别 &#xff1a;normal 授权方式 &#xff1a;system_grant ACL使能 &#xff1a;TRUE ohos.permission.GYROSCOPE 允许应用读取陀螺仪传感器的数据。 权限级别 &#xff1a;normal 授权方式 &a…

探索 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是一种串行、同步、多设备、半双工…

Python中, 介绍面向对象及三大特征

面向对象(Object Oriented Programming) OOP, 是一个重要的编程范式, 它主要基于"对象"的概念, 这些对象具有属性(数据)和方法(函数) 三个特征: 封装, 继承,多态 简单来说: 封装: 隐藏内部实现细节, 只保留功能接口 继承: 类与类之间的关系 (比如说父和子的关系…

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;…

寄存器和变量有什么区别

2024年4月25日&#xff0c;周四晚上 寄存器和变量是计算机编程和计算机硬件中两个不同的概念&#xff0c;它们在内存管理和数据存储方面有着不同的作用和特点。 寄存器&#xff1a; 硬件实现&#xff1a;寄存器是计算机处理器&#xff08;CPU&#xff09;内部的一组高速存储单…

【高频】基于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…

JavaScript常问面试题

css 1.HTML5新增了哪些内容 语义化更好的内容标签(header,footer,main,nav,aside,article,section)音频 ,视频标签(audio, video)画布(canvas)表单控件 calendar , date , time , email , url , search , tel , file , number地理位置API(geolocation)拖拽释放API(Drap and d…

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

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

Redis学习(三)| Redis高可用和容错机制详解

文章目录 高可用性主从复制&#xff08;Master-Slave Replication&#xff09;哨兵&#xff08;Sentinel&#xff09; 容错性数据持久化哨兵&#xff08;Sentinel&#xff09; 高可用vs容错性概念关联 结论 Redis&#xff08;Remote Dictionary Server&#xff09;是一种高性能…