《编译原理》笔记整理

2023-10-26

编译原理 笔记整理

1.1 《编译原理》引论

基本概念——发展

  1. 机器语言
  2. 汇编语言
  3. 高级语言
  4. 工具语言

基本概念——翻译程序

某一种语言程序(称为源语言程序)等价的转换成另一种语言程序(称为目标语言程序)的程序

如:中英互译系统、DBMS语言(DDL、DCL)

翻译程序

基本概念——编译程序

某一种高级语言程序等价的转换成另一种低级语言程序(如:汇编语言或机器语言程序)的程序

编译程序分类:

  1. 诊断编译程序&优化编译程序
  2. 交叉编译程序&可变目标编译程序运行

编译程序

基本概念——解释程序

把源语言写的源程序作为输入,但不产生目标程序,而是边解释边执行源程序本身

解释程序


编译程序与解释程序的区别:编译生成目标程序,而解释不会生成


基本概念——执行高级语言程序的步骤

步骤

1.2 编译过程

1. 词法分析

  1. 任务:输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个单词符号
  2. 依循的原则:构词原则
  3. 描述工具:正规式和有限自动机

2. 语法分析

  1. 任务:在词法分析的基础上,根据语言的语法规则把单词符号串分解成各类语法单位
  2. 依循的原则:语法规则
  3. 描述工具:上下文无关文法

3. 中间代码产生

  1. 任务:对各类不同语法范畴按语言的语义进行初步翻译
  2. 依循的原则:语义规则
  3. 中间代码:三元式、四元式、树形结构等

4. 优化

  1. 任务:对前阶段产生的中间代码进行加工变换,以期在最后阶段产生更高效的目标代码
  2. 依循的原则:程序的等价变换规则

5. 目标代码产生

  1. 任务:把中间代码变换成待定机器上的目标代码

    依赖于硬件系统结构和机器指令的含义

  2. 目标代码的三种形式:

    • 绝对指令代码【可直接运行】
    • 可重新定位指令代码【需要连接装配】
    • 汇编指令代码【需要进行汇编】

编译程序的逻辑结构

逻辑结构

表格与表格管理

常见的表格:符号名表、常数表、标号表、入口名表、过程引用表

格式:

格式

例子:

例子1

例子2

出错处理

出错处理程序:发现源程序中的错误,把有关错误信息报告给用户【语法错误、语义错误】

源程序或源程序的中间结果从头到尾扫描一次,并做有关的加工处理,生成新的中间结果或目标程序

由从外存上获得前一的工作结果开始,完成工作后,把结果存放在外存上。每工作完成后所占用的存贮空间大部分被释放

编译前端与后端

前端与后端

  • 编译前端:与源语言有关,如词法分析、语法分析、语义分析与中间代码产生,与机器无关的优化
  • 编译后端:与目标机有关,与目标机有关的优化,目标代码产生

1.3 高级语言程序简介

一、参数传递

传地址

把实在参数的地址传递给相应的形式参数

传值

调用段把实在参数的值计算出来并放在被调用段可以拿到的地方,把值代入

传名

调用过程的作用相当于 把被调用的过程抄到调用出现的地方,但把其中任一出现的形式参数都替换成相应的实在参数

二、存贮管理

静态存贮分配

编译时就安排好目标程序运行时的全部数据空间,并能确定每个数据项目的单元地址。

动态存贮分配

如果允许递归、可变数据结构,则必须动态分配。

  1. 栈式:整个程序数据空间安排在一个栈中
  2. 堆式:允许自由地申请和退还空间

2.1 程序语言的定义

一个程序设计语言使一个记号系统,其完整的定义应包括语法语义两个方面

  1. 语法是一组规则,用它可以形成和产生一个合适的程序
  2. 语法只定义什么样的符号序列是合法的,与这些符号的含义毫无关系

阐明语法的一个工具是文法,这是形式语言理论的基本概念之一

字符串集合的一些运算

运算

文法

文法是定义或描述语法结构的一组形式规则

2.2 文法的形式化定义和分类

文法的定义

文法定义为一个四元组G=(VN, VT, S, P)

对于这些符号的阐述:

  • VN非空 有限的非终结符集【字符集】

  • VT非空 有限的终结符集【字符集】

  • S:开始符号

  • P:产生式集合

  • 其中, VN ∩ VT =Φ,S∈ VN

    这句话也就是说:

    • 非终结符集【VN】与终结符集【VT】没有相同元素
    • 开始符号为非终结符集【VN】中的一个元素
  • P中产生式一般形式为: A→α|β,其中 A∈ VN ,α, β ∈( VN ∪ VT )*

    这句话也就是说:

    • 一个产生式,表示为一个非终结集中的一个元素可以变成【→】一个为α或者β的字符串,这个字符串为 终结集和非终结集的并集的自反闭包

文法的分类

产生式施加不同的限制得到不同类型的文法

  • 0型(无限制文法)

    规则形式:

    ɑ→β:

    1. α ∈ ( VN∪VT ) +
    2. β ∈ ( VN ∪ VT )*
    3. 且 α中至少含有一个非终结符

    解释:

    这个基本没有限制,只要求左边非空且至少有一个非终结符即可

    PS:但是如果左边都没有非终结符,全是终结符了,那么这个产生式也就没有意义了呀,所以说基本没有限制

  • 1型(上下文有关)

    规则形式:

    α→β:

    1. 有 1≦|α|≦|β|
    2. 其中α=γ12
    3. A ∈ VN
    4. γ1, γ2, β ∈ ( VN ∪ VT )*

    解释:

    这个文法又叫做【上下文有关】,这个所谓的上下文就是γ1和γ2,那么其实这个与0型的区别就在于,左边的α字符串的长度不能大于右边的β字符串的长度

  • 2型(上下文无关)

    规则形式:

    A→δ:

    1. A ∈ VN
    2. δ ∈ ( VN ∪ VT )+

    解释:

    这个就是:产生式的左边A为一个非终结字符,而右边β是一个非终结集和终结集的并集的正闭包【一个非空字符串】

  • 3型(右线性)

    规则形式:

    A→αB或A→α(右线性):

    1. A,B ∈ VN
    2. α ∈ ( VT )*

    解释:

    这个产生式的形式如下:

    • 左边的A为一个非终结字符
    • 右边的字符串有如下的性质:左边全为终结字符,最右边有一个或者没有非终结字符

  • 其他:

    • 左线性(比较右线性即可)

    • 正规文法:

      规则形式:

      A→αB或A→α

      1. 其中A,B ∈ VN
      2. α ∈ VT
      3. 如果 S → ε ∈ P,则S不能出现在任何产生式右边

      解释:

      【前面两条】右边只能是 单个的终结符 或者 一个终结符+一个非终结符的字符串

      【第三条】如果有一个非终结符可以变成空串,那么这个非终结符不能出现在右边的字符串中

    • 2型文法扩充:

      规则形式:

      A → δ,A ∈ VN

      1. δ ∈ ( VN ∪ VT )*

      解释:

      比2型文法多了一条:

      允许有空产生式: A → ε


  • 四个文法类的定义是逐渐增加限制的,因此每一种正规文法都是上下文无关的,每一种上下文无关文法都是上下文有关的,而每一种上下文有关文法都是0型文法。

  • 0型文法 产生的语言为 0型语言

    上下文有关文法(1型文法) 产生的语言为 上下文有关语言

    上下文无关文法(2型文法) 产生的语言为 上下文无关文法

    正规文法 产生的语言为 正规语言

  • 现今大多数高级程序设计语言采用**上下文无关文法(2型文法)**来描述其语法已经足够了。

2.3 文法和语言

推导

设文法G = ( VN, VT, P, S),A → α是其中的产生式

若有符号串γ,δ ∈ ( VN ∪ VT )*,使得

U = γAδ,w = γαδ,则称w为U使用产生式A → α所得到的直接推导,记为U ⇒ w,即γAδ ⇒ γαδ【也称w可直接归约到U】

在这里插入图片描述

在这里插入图片描述

最左推导和最右推导

【最左推导】:每一步推导操作的都是字符串最左边的非终结符

【最右推导】:每一步推导操作的都是字符串最右边的非终结符

规范推导

  • 最右直接推导称规范直接推导
  • 最右推导又称规范推导

最右归约和最左归约

归约

【最右归约】——【最左推导】

【最左归约】——【最右推导】

句型、句子、语言的定义

  1. 这S是文法G的识别符号(也就是开始字符),

    如果S=(*)=>u【经过0步或多步推导】,

    则称符号串u为文法G的句型

  2. 这S是文法G的识别符号(也就是开始字符),

    如果S=(*)=>u【经过0步或多步推导】,且u ∈ (VT)*【u为终结集的自反闭包,也就是说u是由非终结符组成的字符串】

    则称符号串u为文法G的句子

  3. 这S是文法G的识别符号(也就是开始字符),

    文法G的语言L(G) = {u|S=(*)=> 且 u ∈ ( VT )*},

    即文法的语言是文法所有句子的集合

文法等价

若L(G1) = L(G2),则称文法G1和文法G2是等价的

2.4 语法分析树

  • 我们用一张树型结构的图来描述一个句子的推导,这种表示称为语法树。
  • 语法树的根结由文法开始符号标记。随着推导的进行,当某个非终结符被它的候选式所替换时,此非终结符生出其下一代新结,候选式中自左至右没有符号对应着一个新结。

【IMPORTANT】性质:在语法树生长的任何时候,所有那些没有后代的端末结自左至右的排列起来,就是一个句型。

语法树

文法的二义性

  • 一个文法,如果它的一个句子有两棵或两棵以上的语法树,则称此句子具有二义性。如果一个文法含有二义性的句子,则该文法具有二义性。
  • 换一个说法:如果一个文法存在某个句子对应两棵或两棵以上不同的语法树,则称该文法是二义的

3.1 词法分析概述

词法分析程序的任务

从左至右逐个字符地扫描源程序,产生一个个单词符号

把作为字符地源程序改造为单词符号串组成地中间程序,执行词法分析任务地程序称为词法分析器或称扫描器

词法分析程序的功能

  • 主要功能
    • 读入源程序字符串,识别开具有独立含义地最小语法单位——单词(符号)
    • 把单词变换成长度统一地且为定长地属性字
  • 其他功能
    • 滤掉空格,跳过注释、换行符
    • 某些预加工处理

词法分析程序的安排

常常把词法分析程序作为独立的一遍或作为被语法分析程序所调用的子程序

  • 作为独立的一遍:

    语法分析前进行词法分析,把单词符号串形成中间文件存贮

在这里插入图片描述

  • 作为被语法分析器所调用的子程序:

子程序

词法分析程序的实现方式

  • 相对独立方式

    当采用递归下降分析等技术实现一趟编译程序时常采用这种方式

实现方式

  • 完全独立方式

    采用词法分析工作完全独立的原因:

    • 简化设计,降低语法分析的复杂性
    • 提高编译效率
    • 增加编译系统的可移植性

在这里插入图片描述

词法分析程序的输出形式

单词——程序语言的基本语法符号

如:基本字,标识符,常熟,运算符,界符等

词法分析器中,单词的输出形式:

【二元式】(单词类别,单词内部码值)

  • 单词类别:表示单词种类,常用整数编码,它是语法分析需要的

    一般分为以下5种:

    1. 关键字(基本字):个数确定,可全体编为一类(不同的关键字靠内部码值区分),也可一字一类
    2. 标识符(变量名):个数不确定,作为一类
    3. 常数:各种类型的常数,个数不确定,按类型分类(整型、浮点型)
    4. 运算符:如/*-+等,个数确定,一符一类
    5. 界符:如,
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《编译原理》笔记整理 的相关文章

  • Explicit 关键字简介

    Explicit 关键字简介 explicit关键字用来修饰类的构造函数 表明构造函数是显示的 相对的是implicit关键字 首先这个关键字只能用在类内部的构造函数声明上 而不能用在类外部的函数定义上 它的作用是不能进行隐式转换 clas
  • 更换编译器,CODE::BLOCKS 无法DEBUG 至断点

    想在LINUX下使用CODE BLOCKS 编写调试并编译连接ARM运行程序 IDE编译环境默认为 GNU GCC 编译器 修改如下 1 至Settings gt Compiler and debugger settings 将Setect
  • 开源静态代码检测工具Splint

    如果想用一个有效的工具察看C C 源代码中的错误 遗漏 不确定的构建过程 以及移植问题等等 你应该来看看Lint 可以把Lint当成一个编译器 除了不产生代码之外 对于错误和警告的报告来说已经非常足够了 通常 一个C C 的编译器假设程序是
  • 微观的C/C++编译执行过程

    前言 相信能看到这篇文章的同学 是对C语言很热爱的人 最开始学习C语言的时候 我们大多数人都是用集成开发环境 VS VC devc 等 当我们把C语言源代码写好了之后 在集成开发工具中这里点一下 哪里点一下 代码就跑起来了 这种快乐的感觉的
  • vs编译与停止调试时卡顿、无响应的问题

    这是由于VS运行太久参数大量的缓存导致 1 单击 开始 选择 运行 或者win r快捷键 2 键入 devenv exe resetuserdata 此命令会运行几分钟时间 Visual Studio 清除设置并将其自身重置到其最初的状态
  • ESOE-IDE v0.3 技术说明书

    ESOE IDE v0 3 技术说明书 Author Feng WeiGuo 冯卫国 Email forxm 21cn com Web http www supertree org Tel 86 0755 81030955 All Righ
  • linux汇编编译器:GAS和NASM的比较

    GAS即GNU AS汇编编译器 其属于AT T风格 我们常用的GNU的产品还有GCC G NASM是Linux平台下常用的汇编编译器 是intel风格的汇编编译器 MASM是Windows平台下的汇编编译器 也使用Intel风格 我们学80
  • LLVM系列第十五章:写一个简单的中间代码生成器IR Generator

    系列文章目录 LLVM系列第一章 编译LLVM源码 LLVM系列第二章 模块Module LLVM系列第三章 函数Function LLVM系列第四章 逻辑代码块Block LLVM系列第五章 全局变量Global Variable LLV
  • crmeb 前端源码uniapp编译成微信小程序上传开发工具教程

    1 下载登录微信开发工具 下载地址 https developers weixin qq com miniprogram dev devtools download html 推荐使用稳定版 安装完成后后 打开 微信扫码登陆 2 下载HBu
  • 多个DLL之间的Static变量以及模板实例化

    结论如下 1 DLL之间调用类public静态成员变量 不能使用A m static形式调用 其中A为类名 m static为A中的static成员变量 若使用 编译出现链接错误 必须使用函数调用方式 为m static增加set get函
  • 在 Ubuntu 操作中安装Code::Blocks

    在 Ubuntu 操作 中安装Code Blocks 步骤如下 安装步骤 1 先把编译环境 C库 C 库和Boost库装好 如下 sudoapt get install build essential 有可能安装 build essenti
  • MATLAB下配置C和C++编译器(MinGW)

    很多时候需要在Matlab下使用C或C 边写的代码 这时候就需要先用编译器将代码编译成Matlab可以用的mex文件 检测Matlab有没有可以使用的编译器 可以在命令行窗口下 输入mex setup 如果有的话就会显示出可以用的编译器 无
  • C++11各编译器支持情况对比

    原文地址 http sd csdn net a 20120813 2808540 html C 11标准在去年8月份获得一致通过 这是自1998年后C 语言第一次大修订 对C 语言进行了改进和扩充 迄今为止已整整一年啦 想知道C 11在这一
  • 编译器何时调用默认构造函数

    总的来说 编译器只在它需要的时候才会合成一个默认构造函数 或者扩张所有已存在的构造函数 一个类满足下列其中任何一个条件 1 包含了一个类的对象 这个对象有一个构造函数 包括编译器合成的默认构造函数 2 如果继承自一些基类 其中某些基类有一个
  • 拷贝构造函数和赋值构造函数声明为私有的作用

    转贴地址 http blog csdn net winer632 archive 2009 01 12 3762292 aspx 每个类只有一个赋值函数 由于并非所有的对象都会使用拷贝构造函数和赋值函数 程序员可能对这两个函数有些轻视 请先
  • 《程序员的自我修养——链接、装载与库》

    先不说别的 就单看书名就知道是什么意思了 作者的意思是想 演员的自我修养 的作者 斯坦尼斯拉夫斯基 致敬 老斯的那本书我没看过 但我看这本书的意思就是培养程序员的基本素质 你说啥叫基本素质 那就是你能够了解你编写的程序的任何一个运行的细节
  • Cpp关键字破解(三)【volatile】篇

    关键字总结 volatile 文章目录 关键字总结 volatile 0 前言 1 概念 2 作用 3 使用场景 4 volatile成员函数 5 代码体验 0 前言 参考几位前辈博客 汇总整理了一下 C 中volatile关键字的使用详解
  • dynamic_cast报错 异常

    转载请标明是引用于 http blog csdn net chenyujing1234 代码 http www rayfile com zh cn files 89459c23 7a0b 11e1 908f 0015c55db73d UnH
  • 为什么栈的数组长度必须是一个常量?而堆的数组长度可以是变量。为什么栈的大小有限制?

    为什么栈的数组长度必须是一个常量 而堆的数组长度可以是变量 栈区数组长度使用变量会报错 其原因就在于栈是编译器管理的 在程序运行前就已经分配好了空间的大小 而使用变量 编译器无法知道该分配多大的内存空间 于是报错 但堆上的内存是动态创建的
  • C++-必知必会_类模板成员特化(条款48)

    类模板成员特化 再提醒一下 虽然模板的特化和类的派生之间没有任何关 系 但在特化模板的时候 不妨借鉴一下派生的精神 也就意味 着一个完全特化或局部特化通常必须重新实现 主模板具备的 所有能力 例1 主模板 template lt typen

随机推荐

  • 网络层_数据平面_四(题目完成)

    网络 引入网络层学习 分组交换 虚电路VC 数据报网络 CIDR DHCP 路由器 IP数据报格式 IPv4 IPv6 过渡策略 双栈 隧道 特殊IP地址即内部IP地址 流表中匹配 动作 计算机自顶向下方法 第七版课后习题及答案 正在更新中
  • 论文解读:Investigating the Factual Knowledge Boundary of Large Language Models with Retrieval Augmentati

    论文解读 Investigating the Factual Knowledge Boundary of Large Language Models with Retrieval Augmentation 一 动机 Knowledge in
  • C++ 智能指针我得用用看

    文章目录 0 前言 0 1 使用智能指针的原因 0 2 智能指针和普通指针的区别 什么是智能指针 1 auto ptr 1 1 基本说明 1 2 例子 chestnut 1 3 使用建议 3 unique ptr 3 1 实现原理 3 2
  • [游戏开发]网络同步方式

    状态同步 优点 数据在服务器运算 客户端接收到的数据一定准确 防止数据作弊 角色数据在服务器 客户端只上传操作 想作弊没门 网络波动不敏感 多端表现可以不一致 重视数值准确 缺点 前后端数据包体大 服务器压力比较重 计算量 传输量 研发特点
  • java中冒号(:)的用法

    java中冒号的用法大概可以分为四种 用在for循环中 用来遍历数组 集合 中的元素 for x nums print x 用在三目运算符中 表达式 执行语句1 执行语句2 这里的冒号是用来根据前面表达式的值正确与否 选择后面对应执行语句的
  • 多线程实现的方式

    1 继承Thread类 通过继承Thread类 并重写run方法 public class MyThread extends Thread public static void main String args MyThread myThr
  • sudo vim找不到命令(Ubuntu16.04)

    在使用vim配置环境变量时 提示 sudo vim 找不到命令 原因是因为没有安装vim 下面我们就来在终端进行安装一下 前提是需要连上网了 没有联网不在此考虑范围 1 进入终端 Ctrl Alt T 出现终端窗口 2 输入命令 sudo
  • Linux:WSL 下 CTS 环境搭建及无法识别设备问题

    WSL Windows Subsystem for Linux 简称WSL 是一个在Windows 10上能够运行原生Linux二进制可执行文件 ELF格式 的兼容层 它是由微软与Canonical公司合作开发 其目标是使纯正的Ubuntu
  • mysql [Err] 1118 - Row size too large (> 8126).

    错误代码 1118 Row size too large gt 8126 Changing some columns to TEXT or BLOB may help In current row format BLOB prefix of
  • 获取服务器系统,获取服务器操作系统

    获取服务器操作系统 内容精选 换一换 服务器安装上架 服务器基础参数配置 安装操作系统等操作请参见 Atlas 500 Pro 智能边缘服务器 用户指南 型号 3000 安装操作系统完成后 配置业务网口IP地址 请参见配置网卡IP地址 At
  • arduinows2812灯条程序_Arduino 控制WS2812 LED灯条

    传统的LED限制总是很多 比如需要很多的引脚 所以有一种很好的解决方案是用灯条 理论上这种灯条可以通过通讯 用一根数据总线可以控制达到无上限个数的RGB LED灯珠 并且在数量在1024以下时 延迟是不可察觉的 使用手册可查 主要功能 通过
  • Day 3 Mastering the Interface Definition Language (IDL)

    Teach Yourself CORBA In 14 Days Day 3Mastering the Interface Definition Language IDL Overview IDL Ground Rules Case Sens
  • momentJS时间加减处理

    计算最近在使用JavaScript计算时间差的时候 发现很多问题需要处理 在查看momentJS之后 发现非常容易 console log moment format YYYY MM DD HH mm ss 当前时间 console log
  • 基于nodejs的在线跑腿管理系统

    末尾获取源码 开发语言 nodejs 框架 Express 数据库 MySQL5 7 数据库工具 Navicat 11 开发软件 Hbuilder VS code 浏览器 edge 谷歌 目录 一 项目简介 二 系统功能 三 系统项目截图
  • go语言context保存上下文

    contxt保存上下文适合全局参数传递 而普通的参数传递就没必要用context 因为不好维护 关于context具体用法可以参考 https studygolang com articles 23247 fr sidebar packag
  • java函数的定义方法_java函数的定义以及使用方法介绍

    java函数的定义以及使用方法介绍 发布时间 2020 04 24 16 28 40 来源 亿速云 阅读 116 作者 小新 今天小编给大家分享的是java函数的定义以及使用方法介绍 相信很多人都不太了解 为了让大家更加了解java函数 所
  • AJAX&&JSON

    课程笔记Day46 AJAX JSON 综合案例 第一章 AJAX 第01节 基础理论 1 概念说明 1 什么是 AJAX AJAX是一项技术合集 他是由一套技术组合得到的新技术方案 异步请求技术 2 AJAX有什么作用呢 使用Ajax技术
  • C++ 删除文本数据中第一个元素

    由于项目需要删除第一个字符 然后按照相同顶格显示 如下 v 279 268005 37 345402 2 081520 v 280 971985 37 074699 1 353890 v 279 015991 44 888100 1 609
  • 手把手教你搭建国产嵌入式模拟器SkyEye开发环境

    SkyEye介绍 SkyEye是一个开源软件 OpenSource Software 项目 中文名字是 天目 SkyEye的目标是在通用的Linux和Windows平台上实现一个纯软件集成开发环境 模拟常见的嵌入式计算机系统 这里假定 仿真
  • 《编译原理》笔记整理

    编译原理 笔记整理 1 1 编译原理 引论 基本概念 发展 机器语言 汇编语言 高级语言 工具语言 基本概念 翻译程序 把某一种语言程序 称为源语言程序 等价的转换成另一种语言程序 称为目标语言程序 的程序 如 中英互译系统 DBMS语言