BIT 2024 编译原理 Lab. 4 四代编译器实验说明和要求

实验四:四代编译器实验

一、实验要求

详细实验要求请参考文件《Lab4实验说明和要求.pdf》。

二、实验思路

1、与 lab3 的对比

如果你在 lab3 就已经像我一样单独写了个函数处理表达式,那么理论上,lab4 相比于 lab3,不过就是多了对 ifwhile 等语句的处理,而其他部分几乎不需要任何改变!

这样一来,lab4 就非常简单了。因此,本文是基于 lab3 的代码上进行修改,关于 lab3 的文章在这里:http://t.csdnimg.cn/sQcsP

2、函数的划分

现在,不能简单地通过 } 的出现位置来区分不同的函数块,这是因为函数内的 ifwhile 语句块通常也会出现 }.

如果你仍然希望实现预先对函数进行划分,一种可行的做法是:维护一个变量 left_brace_minus_right_brace,它等于 左大括号的数量-右大括号的数量,当且仅当 } 的位置满足left_brace_minus_right_brace = 0 时,表明这个 } 用于划分函数是有效的。

3、句子的识别

现在,句子不总是以 ; 作为结尾,因为 ifwhile 语句块通常以 } 结尾,这意味着仅使用 ; 分割两个句子是不完全正确的。为了解决这个问题,你需要添加一些其他的条件判断。

4、句子的处理

注意:这里仅提供我的方法,实际上你应该结合自己的理解和自己的代码进行修改!

对于 ifwhile ,你觉得一个句子应该在什么地方进行划分?

我这里的做法简单来说,是按照有效的 } 进行划分,我举一个例子。有如下代码:

if ( a>3 ) {if ( a<10 ) {println_int(a);}while ( a<b ) {println_int(b);a=a+1;}
}

那么,对于上面的例子,我认为

if (a>3) { if (a<10) { println_int(a); } while (a<b) { println_int(b); a=a+1; } }Δ																		Δ

是一个句子。在这个句子中,含有两个子句,它们分别是

if (a<10) { println_int(a); }Δ					Δ
while (a<b) { println_int(b); a=a+1; }Δ					 	 Δ

对于前者,它又含有一个子句

println_int(a);

对于后者,它含有两个子句,分别是

println_int(b);
a=a+1;

这样的结构,令我想到了递归。显然,如同我在 lab3 中单独写一个函数处理表达式,现在,我要单独写一个函数处理句子

对于一个句子,直接调用该函数;如果句子内部又含有句子,则递归调用这个函数。

说实话,到这个时候,我也不敢说自己的做法是不是高明,所以请你自己思考一下,你会用什么样的方法来处理 ifwhile 的语句块?

5、if 对应的汇编语句

if 语句处理十分简单,它的代码结构一定是:

if ( 表达式 ) {一些句子
}

对应的汇编是:

if结构

6、while 对应的汇编语句

while 语句处理相比于 if 稍微复杂一些,我们先不考虑 continuebreak,它的代码结构一定是:

while ( 表达式 ) {一些句子
}

对应的汇编是:

while结构

while 的内部每多一个 continue,就多一对 jump,如下图所示:(可以交换 jump1:jump3:

continue结构

while 的内部每多一个 break,就多一对 jump,如下图所示:(可以交换jump2:jump4:

break结构

你最好先理解了再写代码,不然写起来会很费劲的。

三、实验注意

  1. 该部分主要阐述本人在做该实验时踩过的坑

  2. 提交方式:和 lab3 一样

  3. 任何跳转的入口名都不能一样,例如有汇编语句:

    ...
    je .L_while_end_1	# 入口名一样
    ...
    je .L_while_end_1	# 入口名一样
    ...
    .L_while_end_1:... 
    

    这样写就会报错。

  4. 局部变量

    这里指的是 ifwhile 内部定义的变量,例如:

    if (a==b) {int c;c = a+b;println_int(c);
    }
    

    有时候,你可能需要注意对这种变量的处理。

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

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

相关文章

ComfyUi安装OOTDiffusion插件的diffusers版本问题

OOTDiffusion换装 在github上有近5K的star了&#xff08;https://github.com/levihsu/OOTDiffusion&#xff09;。 diffusers版本问题 最新版是0.27.2&#xff0c;不能低于0.25&#xff0c;但是OOT换装需要0.24&#xff0c;否则会报错&#xff1a; ComfyUI\custom_nodes\Comf…

系统架构设计师【第14章】: 云原生架构设计理论与实践 (核心总结)

文章目录 14.1 云原生架构产生背景14.2 云原生架构内涵14.2.1 云原生架构定义14.2.2 云原生架构原则14.2.3 主要架构模式14.2.4 典型的云原生架构反模式 14.3 云原生架构相关技术14.3.1 容器技术14.3.2 云原生微服务14.3.3 无服务器技术14.3.4 服务网格 14.4 云原生…

HTML+CSS 文本动画卡片

效果演示 实现了一个图片叠加文本动画效果的卡片&#xff08;Card&#xff09;布局。当鼠标悬停在卡片上时&#xff0c;卡片上的图片会变为半透明&#xff0c;同时显示隐藏在图片上的文本内容&#xff0c;并且文本内容有一个从左到右的渐显动画效果&#xff0c;伴随着一个白色渐…

Python命令行参数处理:详解argparse模块

Python命令行参数处理&#xff1a;详解argparse模块 在Python开发中&#xff0c;能够处理命令行参数是一项非常实用的技能。argparse模块是Python标准库中用于解析命令行参数的模块&#xff0c;它能够轻松地处理复杂的命令行接口。本文将详细介绍如何使用argparse模块来处理命…

YOLOV10训练自己的数据集

*************************************************** 码字不易&#xff0c;收藏之余&#xff0c;别忘了给我点个赞吧&#xff01; *************************************************** Start YOLOV10训练自己的数据集 官方论文&#xff1a;https://arxiv.org/abs/2405…

使用busybox快速创建rootfs系统(硬件:atk-dl6y2c)

目录 概述 1 编译busybox 1.1 配置Makefile 1.2 需改参数 1.3 配置busybox 1.4 编译busybox 2 完善 rootfs下文件 2.1 rootfs 的“/lib”目录添加库文件 2.2 rootfs 的“usr/lib”目录添加库文件 2.3 创建其他目录 3 完善其他文件 3.1 完善etc/init.d/rcS 3.2 完善…

Golang | Leetcode Golang题解之第128题最长连续序列

题目&#xff1a; 题解&#xff1a; func longestConsecutive(nums []int) int {numSet : map[int]bool{}for _, num : range nums {numSet[num] true}longestStreak : 0for num : range numSet {if !numSet[num-1] {currentNum : numcurrentStreak : 1for numSet[currentNum…

【CMake】CMake入门(五)打包安装程序 使用CMake管理库 打包调试版和发行版

本篇文章不是新手入门教学文章&#xff0c;主要是记录笔者个人的学习笔记 CMake入门&#xff08;五&#xff09; 一、打包二、使用CMake管理库三、打包调试版和发行版 一、打包 发布程序可以有多种形式&#xff0c;比如安装包、压缩包、源文件等。CMake也提供了打包程序cpack可…

YOLOv8训练自定义项目

训练内容&#xff1a;基于yolo的筒纱实例分割 数据设置&#xff1a; 1&#xff09;https://ultralytics.com/assets/coco8-seg.zip&#xff0c;下载coco8-seg.zip&#xff0c;解压&#xff0c;记住各个文件夹内的文件名&#xff08;12为为长度&#xff0c;如000000000001.jpg…

8、架构-分布式的共识

概述 在正式探讨分布式环境中面临的各种技术问题和解决方案前&#xff0c;我 们先把目光从工业界转到学术界&#xff0c;学习几种具有代表性的分布式共识 算法&#xff0c;为后续在分布式环境中操作共享数据准备好理论基础。下面笔 者从一个最浅显的场景开始&#xff0c;引出本…

金钱的认知,你如何理解呢?

金钱的认知 建立在金钱之上的爱情是纯真的爱&#xff0c;朋友关系也才够纯粹&#xff0c;才是单纯的世界&#xff0c;反之没了钱的条件爱情和友情的美好关系极易破碎&#xff0c;也极易反目成仇。 心若美好钱就美好&#xff0c;心有欲望狰狞钱就是只咬人的老虎&#xff0c;钱…

python练习五

Title1&#xff1a;请实现一个装饰器&#xff0c;每次调用函数时&#xff0c;将函数名字以及调用此函数的时间点写入文件中 代码&#xff1a; import time time time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # 获取当前的时间戳 # 定义一个有参装饰器来实…

Linux 僵尸进程和孤儿进程

一.Z(zombie)-僵尸进程 1.僵死状态&#xff08;Zombies&#xff09;是一个比较特殊的状态。当进程退出并且父进程&#xff08;使用wait()系统调用后&#xff09;没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 2.僵死进程会以终止状态保持在进程表中&#xff0c;并且会…

【代码随想录37期】Day24 回溯 组合

理论基础 回溯是一种搜索方式&#xff0c;通常通过穷举来解决问题&#xff0c;核心思想是从一个初始状态出发、暴力搜索所有可能的方案&#xff0c;遇到正确的解法则记录下来&#xff0c;直到结束&#xff0c;这是一个典型的深度优先搜索思想&#xff1a;不撞南墙不回头 回溯…

Java17 --- SpringCloud之seate

目录 一、创建seata需要的mysql数据库表 二、修改seata的配置文件 三、启动nacos及seata 四、创建需要的数据库及表 一、创建seata需要的mysql数据库表 CREATE DATABASE seata;CREATE TABLE IF NOT EXISTS global_table(xid VARCHAR(128) NOT NULL,…

C++ | Leetcode C++题解之第128题最长连续序列

题目&#xff1a; 题解&#xff1a; class Solution { public:int longestConsecutive(vector<int>& nums) {unordered_set<int> num_set;for (const int& num : nums) {num_set.insert(num);}int longestStreak 0;for (const int& num : num_set) {…

隐马尔可夫链

1 马尔可夫链 马尔科夫链&#xff08;Markov Chain&#xff09;是一种数学模型&#xff0c;它描述了一系列可能事件的概率&#xff0c;其中每个事件的发生仅依赖于前一个事件的状态。这一特性称为“无记忆性”或“马尔可夫性质”。我将用一个简单的天气预测模型作为例子来解释马…

【组合数学 隔板法 容斥原理】放球问题

本文所属分类 组合数学汇总 8类放球问题 放球问题是一类很有意思的排列组合问题。通俗来说&#xff0c;就是把n个小球放到m个盒子里&#xff0c;问有几种放法。具体可以从3个维度&#xff0c;每个维度2种情况&#xff0c;共8种情况&#xff1a; 维度一&#xff1a;小球是否相…

对象业务的追加写接口

类似文件的追加写操作&#xff0c;在对象的末尾增加新的数据内容。 本文有如下假定&#xff1a; 对象存储服务基于文件语义实现。使用PUT方式上传的对象&#xff0c;内部使用一个文件和对应的元数据来承载。使用多段方式上传的对象&#xff0c;内部使用多个段文件、元数据来承…

【面试题-012】什么是Spring 它有哪些优势

文章目录 Spring有哪些优势有哪些优势Spring和Springboot区别在 Spring 框架中&#xff0c;什么是AOP核心概念应用场景 Spring有哪些通知类型 Spring 是一个开源的 Java 平台&#xff0c;由 Rod Johnson 创建&#xff0c;用于简化企业级 Java 应用程序的开发。它于 2003 年首次…