当前位置: 首页 > news >正文

笔记 | 编译原理L1

重点关注过程式程序设计语言编译程序的构造原理和技术

1 程序设计语言

1.1 依据不同范型

过程式(Procedural programming languages–imperative)函数式(Functional programming languages–declarative)逻辑式(Logical programming languages–declarative)对象式(Object-oriented programming languages)
程序中指明如何完成一个计算任务程序中指明要进行哪些计算事实+推理规则支持面向对象编程
FORTRAN, PASCAL, CLISP, HASKELL, ML, OCAML, SCALA…PROLOGSmalltalk, Java, C++, Eiffel, Ruby
说明式语言(Declarative programming): 与上述命令式(Imperative language) 不同,没有控制结构,甚至没有赋值,仅有问题说明,或者 说纯数学定义

1.2 依据不同转化方式

编译型语言解释型语言混合型语言
需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言。一般需经过编译(compile)、链接(linker)这两个步骤。编译是把源代码编译成机器码,链接是把各个模块的机器码和依赖库串连起来生成可执行文件。不需要编译,相比编译型语言省了道工序,解释性语言在运行程序的时候才逐行翻译。比如C#,C#在编译的时候不是直接编译成机器码而是中间码,.NET平台提供了中间语言运行库运行中间码,中间语言运行库类似于Java虚拟机。.net在编译成IL代码后,保存在dll中,首次运行时由JIT在编译成机器码缓存在内存中,下次直接执行(博友回复指出)。
优点:编译器一般会有预编译的过程对代码进行优化。因为编译只做一次,运行时不需要编译,所以编译型语言的程序执行效率高。可以脱离语言环境独立运行。优点:有良好的平台兼容性,在任何环境中都可以运行,前提是安装了解释器(虚拟机)。灵活,修改代码的时候直接修改就可以,可以快速部署,不用停机维护。
缺点:编译之后如果需要修改就需要整个模块重新编译。编译的时候根据对应的运行环境生成机器码,不同的操作系统之间移植就会有问题,需要根据运行的操作系统环境编译不同的可执行文件。缺点:每次运行的时候都要解释一遍,性能上不如编译型语言。
代表语言:C、C++、Pascal、swift代表语言:JavaScript、Python、Erlang、PHP、Perl、RubyJava先生成字节码再在Java虚拟机中解释执行。

不同的程序设计语言机制(函数式、过程式、逻辑式、对象式),需要采用不同的技术编写编译程序,过程式语言的编译是对象式语言编译的基础

1.3 另一种角度

动态类型语言(Dynamically Typed Language)静态类型语言(Statically Typed)强类型定义语言(Explicit type)弱类型定义语言(Implicit type)
编译时不知道变量类型,运行时才决定,类型错误属于运行错误,运行时报错编译时候决定变量,类型错误属于语法错误,编译器报错偏向于不容忍隐式类型转换偏向于容忍隐式类型转换

image.png

2 编译器概述

编译器(Compiler) 将某种语言(源语言)编写的程序翻译成语义等价的另一种语言(目标语言)编写的程序

image.png|700

依据目标程序的类型:

目标程序若是可执行的机器语言程序目标程序若是汇编语言的程序
可以被用户调用,处理输入并产生输出。image.png
则须经汇编器汇编后方可执行

编译器的重要任务之一是报告它在翻译过程中发现的源程序中的错误。

2.1 编译器的翻译包括哪些步骤

  1. 阅读并理解程序
  2. 准确地确定需要采取什么行动
  3. 弄清楚如何忠实地执行这些行动
  4. 指示计算机执行这些步骤

[[编译器概述.excalidraw|示例图]]
image.png

2.2 编译程序的伙伴程序

编辑器 (editor)预处理器(preprocessor)汇编程序(assembler)连接程序(linker)装入程序(loader)
除一般的文本编辑功能外,还可以对正在编辑的文本进行分析、提示、自动提供关键字匹配等功能;删除源程序中的注释、执行宏替换以及包含文件的嵌入等将编译程序生成的汇编代码汇编成机器代码将不同的目标文件连接到一个可执行的文件中将程序加载到内存中以便执行
image.png

3 编译器的组成

3.1 自然语言翻译过程总结

掌握源语言和目标语言:词法、语法和语义, 翻译过程包括:

分析源句子是否正确将句子翻译成目标语言
拼写,包括识别单词及其属性,依据源语言的语法建立语法结构,检查句子是否有意义翻译每个语法部分,将其组合成有意义的目标语言句子

3.2 编译器组成模块

image.png

[!Note]- 分析部分

  1. 源程序 - 语法结构 - 中间表示
  2. 搜集源程序中的相关信息,放入符号表
  3. 分析、定位程序中可能存在的错误信息(语法、语义错误)
  4. 又称编译器的前端(front end),是于机器无关的部分
符号表管理词法分析/扫描(lexical analysis, scanning)语法分析语义分析
记录源程序中使用的变量的名字,收集各种属性(名字的存储分配,类型,作用域,过程名字的参数数量、参数类型等等)1.读入源程序的字符流,输出有意义的词素(lexeme)。基于词素,产生词法单元token: <token-name, attribute-value>
2.关于token:程序语言处理的最小单位,token-name由语法分析步骤使用,attribute-value指向相应的符号表条目,由语义分析/代码生成步骤使用
1.词法分析后,需要得到词素序列的语法结构
2.语法分析/解析(syntax analysis/parsing):sentence是对单词的再次重组,程序设计语言规定了词法单元、语句的重组规则 — >语句的类别.
使用语法树和符号表中的信息,检查源程序是否满足语言定义的语义约束。同时收集类型信息,用于代码生成。类型检查,类型转换。
符号表可由编译器的各个步骤使用程序语言规定了单词构成的规则和单词类别image.png
根据各个词法单元的第一个分量来创建树形中间表示形式。通常是语法树(syntax tree/parse tree),指出了词法单元流的语法结构image.png


[!Note]- 合成部分

  1. 根据符号表和中间表示构造目标程序
  2. 又称编译器的后端(back end),是于机器相关的部分
中间代码生成代码优化目标代码生成
根据语义分析的输出,生成类机器语言的中间表示通过对中间代码的分析,改进中间代码,得到更好的目标代码(快、短、能耗低把中间表示形式映射到目标语言:(寄存器的分配,指令选择,内存分配)
三地址代码:每个指令最多包含三个运算分量image.png
优化有具体的设计目标image.png
image.png

3.3 编译器的趟(Pass)

趟(Pass):以文件为输入输出单位的编译过程的个数,每趟可由一个或若干个步骤构成。就是对源程序或源程序的中间表示形式从头到尾扫描一次,并作加工处理,生成新的中间结果或目标程序。

  • 可以词法分析、语法分析、语义分析等阶段各作为单独一趟
  • 也可以词法分析作为语法分析的子程序
  • 还可以整个编译程序一遍扫描完成

与编译器组成模块的关系:前者作为“步骤”是逻辑组织方式,“趟”和具体的实现相关

4 解释器

  1. 定义:解释器(Interpreter):解释器直接利用用户提供的输入执行源程序中指定的操作。
  2. 解释过程中若发现错误,则返回修改源程序,修改后重新解释执行。
  3. 解释器与编译器的区别理解:解释器可以直接输出结果,而编译器最终的输出是一个目标程序,是把一种程序设计语言翻译成另外一种语言,编译器的重要任务之一是报告它在翻译过程中发现的源程序中的错误。

4.1 解释器与编译器的比较

image.png

二者比较:

相同点区别
使用相同的实现技术实现机制: 翻译 (程序 to 程序)vs. 解释(指令 to 指令序列)

二者特点:

解释器编译器
可移植性好,支持交互式程序设计,边解释,边执行,错误诊断效果好效率高,一次编译,多次运行,存储代价小,目标程序的执行速度比解释器快很多

二者结合的一种应用:Java

  1. javac 前端编译器:先编译成字节码(bytecode, .class文件)
  2. 由JVM解释执行,可移植性好
  3. JIT即时编译器(just-in-time compiling)
  4. image.png
  5. 为了提高热点代码的执行效率,在运行时虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各层次的优化(判断热点代码的方法:基于采样的热点探测;基于计数器的热点探测)

5 构建(Build),构建工具(Make)与编译的关系

  • 代码变成可执行文件,叫做编译(compile)
  • 安排编译的顺序,叫做构建(build)
  • Make是最常用的构建工具,诞生于1977年,主要用于C语言的项目,实际上任何只要某个文件有变化,就要重新构建的项目,都可以用Make构建,构建规则都写在Makefile, “make [选项][参数]”

6 编译器的实现

编译器的开发代价是非常昂贵的,在可能的情况下,可以将一种语言的程序转换成另一种语言的程序,利用另一种语言的编译器进行编译。

前提条件:两种语言在语法和语义上很近似,或者一种语言是另一种语言的扩展;实例:C++ —> C

image.png

相关文章:

笔记 | 编译原理L1

重点关注过程式程序设计语言编译程序的构造原理和技术 1 程序设计语言 1.1 依据不同范型 过程式(Procedural programming languages–imperative)函数式(Functional programming languages–declarative)逻辑式(Logical programming languages–declarative)对象式(Object-or…...

k8s存储卷 PV与PVC 理论学习

介绍 存储的管理是一个与计算实例的管理完全不同的问题。PersistentVolume 子系统为用户和管理员提供了一组 API&#xff0c;将存储如何制备的细节从其如何被使用中抽象出来。为了实现这点&#xff0c;我们引入了两个新的 API 资源&#xff1a;PersistentVolume 和 Persistent…...

【WPF应用32】WPF中的DataGrid控件详解与示例

在WPF&#xff08;Windows Presentation Foundation&#xff09;开发中&#xff0c;DataGrid控件是一个强大的数据绑定工具&#xff0c;它以表格的形式展示数据&#xff0c;并支持复杂的编辑、排序、过滤和分组等操作。在本文中&#xff0c;我们将详细介绍DataGrid控件的功能、…...

numpy,matplotilib学习(菜鸟教程)

所有内容均来自于&#xff1a; NumPy 教程 | 菜鸟教程 Matplotlib 教程 | 菜鸟教程 numpy模块 numpy.nditer NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。 for x in np.nditer(a, orderF):Fortran order&#xff0c;即是列序优先&#x…...

Web API(四)之日期对象节点操作js插件重绘和回流

Web API(四)之日期对象&节点操作&js插件&重绘和回流 日期对象实例化方法时间戳DOM 节点插入节点删除节点查找节点父子关系兄弟关系M端事件js插件重绘和回流进一步学习 DOM 相关知识,实现可交互的网页特效 能够插入、删除和替换元素节点能够依据元素节点关系查找…...

27.WEB渗透测试-数据传输与加解密(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;26.WEB渗透测试-BurpSuite&#xff08;五&#xff09; BP抓包网站网址&#xff1a;http:…...

山寨windows

我的目标是能够运行windows 下的大部分PE格式的程序&#xff0c;这一点通过实验已经证明完全是可行的。 PE格式主要有exe dll sys等文件&#xff0c;这三个文件可以用相同的函数解析&#xff0c; 主要有以下段组成&#xff0c; 1、文件头&#xff0c;包含DOS文件头、PE文件头…...

unity工程输出的log在哪里?

在编辑器里进行活动输出的log位置&#xff1a; C:\Users\username\AppData\Local\Unity\Editor\Editor.log ------------------------------------ 已经打包完成&#xff0c;形成的exe运行后的log位置&#xff1a; C:\Users\xxx用户\AppData\LocalLow\xx公司\xx项目...

【力扣】7. 整数反转

7. 整数反转 题目描述 给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] &#xff0c;就返回 0。 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。 …...

Android Apk签名算法使用SHA256

Android apk签名算法使用SHA256 本文不介绍复杂的签名过程&#xff0c;说一下Android签名算法使用SHA256。 但是SHA1不是相对安全签名算法&#xff0c;SHA256更加安全一些。 一般大公司才会有这种细致的安全要求。 如何查看apk签名是否是SHA1还是SHA256 1、拿到apk文件&…...

2024.3.13力扣每日一题——最大二进制奇数

2024.3.13 题目来源我的题解方法一 贪心 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2864 我的题解 方法一 贪心 统计1的个数&#xff0c;满足要求的字符串的末尾一位一定是1&#xff0c;所以需要将一位1放到末尾&#xff0c;然后将剩余的1从最高位开始放&#xff0…...

2024.4.1力扣每日一题——故障键盘

2024.4.1 题目来源我的题解方法一 直接利用StringBuilder的反转函数方法二 字符数组 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2810 我的题解 方法一 直接利用StringBuilder的反转函数 使用StringBuilder构造结果&#xff0c;并利用其反转函数进行翻转 时间复杂度…...

第十四届蓝桥杯C/C++大学B组题解(一)

1、日期统计 #include <bits/stdc.h> using namespace std; int main() {int array[100] {5, 6, 8, 6, 9, 1, 6, 1, 2, 4, 9, 1, 9, 8, 2, 3, 6, 4, 7, 7,5, 9, 5, 0, 3, 8, 7, 5, 8, 1, 5, 8, 6, 1, 8, 3, 0, 3, 7, 9,2, 7, 0, 5, 8, 8, 5, 7, 0, 9, 9, 1, 9, 4, 4, 6,…...

4.网络编程-websocket(golang)

目录 什么是websocket golang中使用websocket Server端 Client端 什么是websocket WebSocket是一种在互联网上提供全双工通信的协议&#xff0c;即允许服务器和客户端之间进行双向实时通信的网络技术。它是作为HTML5的一部分标准化的&#xff0c;旨在解决传统HTTP协议在实…...

docker安装部署mysql后忘记root密码

应用场景是&#xff1a;用docker安装完mysql后&#xff0c;使用安装时候设置的密码登录不上MySQL&#xff1b; 1、修改docker映射出mysql的配置文件&#xff1a;my.cnf 在mysqld最下方添加skip-grant-tables进入安全模式&#xff08;随意一个密码即可登录mysql&#xff09; [m…...

c++的学习之路:14、list(1)

本章讲一下如何使用list&#xff0c;代码在文章末 目录 一、list介绍 二、增 三、删 四、查和改 五、交换 六、代码 一、list介绍 首先还是看一看官方文档的介绍如下图&#xff0c;如下方五点&#xff1a; 1. list是可以在常数范围内在任意位置进行插入和删除的序列式…...

huawei 华为交换机 配置 VLAN 聚合示例

组网需求 某公司拥有多个部门且位于同一网段&#xff0c;为了提升业务安全性&#xff0c;将不同部门的用户划分到不同VLAN 中&#xff0c;如 图 5-7 所示&#xff0c; VLAN2 和 VLAN3 属于不同部门。各部门均有访问Internet需求&#xff0c;同时由于业务需要&#xff0c;不同部…...

【QT+QGIS跨平台编译】056:【pdal-dimbuilder+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、pdal介绍二、dimbuilder介绍三、pdal下载四、文件分析五、pro文件六、编译实践七、生成Dimension.hpp八、生成pdal_features.hpp一、pdal介绍 PDAL(Point Data Abstraction Library)是一个开源库,用于处理点云数据的获取、过滤、转换、分析和…...

【Python】探索Python中的aiohttp:构建高效并发爬虫

后来 我总算学会了 如何去爱 可惜你 早已远去 消失在人海 后来 终于在眼泪中明白 有些人 一旦错过就不再 &#x1f3b5; HouZ/杨晓雨TuTu《后来》 在数据密集和网络密集的任务中&#xff0c;提高程序的执行效率是非常重要的。Python作为一门强大的编程语言…...

创建真实项目vue2项目

1. 创建 vue create 项目名 2. 选择自定义 3. 勾选以下必备选项 4.选择使用vue2 5. 选择哈希模式&#xff08;n&#xff09;; css选择Less 6. ESLint校验 选择 7. 保存&#xff08;按照默认&#xff09; 8. 在哪里添加ESLint文件 9. 要不要把这个改成将来的预设&am…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...