![](https://img-blog.csdnimg.cn/20200822232722754.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
编译原理
编译原理
pudding_art
这个作者很懒,什么都没留下…
展开
-
编译原理(二十)——目标代码生成
一、目标代码二、虚拟目标机的指令系统三、虚拟目标机的寄存器四、四元式转化为目标指令五、多寄存器的分配六、对目标程序的评价原创 2020-11-04 22:36:44 · 9541 阅读 · 0 评论 -
编译原理(十九)——运行时存储空间管理(变量访问环境)
一、变量访问环境二、调用链、动态链三、活跃活动记录(LAR)四、声明链和变量访问环境五、如何计算当前过程的变量访问环境六、Display方法七、静态链方法八、全局Display表原创 2020-11-03 18:01:59 · 5619 阅读 · 2 评论 -
编译原理(十八)——运行时存储空间管理
一、目标程序运行时内存的划分二、语言影响空间分配策略三、存储管理模式的分类四、静态存储分配五、动态存储分配六、模式管理中的过程活动记录七、栈式管理中的过程活动记录八、地址分配原则回顾九、过程活动记录的申请和释放十、变量的地址映射...原创 2020-11-02 12:21:51 · 2495 阅读 · 0 评论 -
编译原理(十七)——中间代码优化(2)
一、公共表达式节省这种情况在自己写的代码中直接出现的可能性不大,但是在写程序的时候特别是有下标变量的时候通常会有很多这样的情况,比如二维数组a[i][j] 和a[i][k]前三条四元式是完全相同的,没有必要重复的计算这样三条四元式。所以在实际的使用中,公共子表达式出现的情形还是比较多的。公共表达式:指两个表达式中的子表达式他们的计算结果相同公共表达式节省在局部进行的时候是针对基本块的。有两种方法——相似性方法和编码方法如何在一个四元式序列中将公共子表达式提取出来?形式相同的表达式未必可以原创 2020-10-27 19:47:08 · 2487 阅读 · 1 评论 -
编译原理(十六)——中间代码优化(1)
一、代码优化的阶段欲提高源程序的运行速度,需要经过几个阶段的优化:用户对源程序进行优化(和编译器无关,与coder设计的算法有关)编译器前端对中间代码进行优化编译器后端对目标代码进行优化两个编译器必须等价,编译的结果必须是正确的,即使有99.99%的可能性是不正确的,但是效率很好也不行,正确性是根本。二、中间代码优化的分类从优化的种类来看,中间代码的优化可有如下分类:局部优化循环上的优化(所有优化方法效果最好的)1. 循环不变体外提循环中不因循环而改变的部分可以提到循环的原创 2020-10-23 11:38:21 · 6640 阅读 · 5 评论 -
编译原理(十五)——中间代码生成(3)
一、过程调用和函数调用的中间代码1. 背景信息形参种类:值参、变量参数、函数参数需要的信息:形参的种类、传送的内容、偏移、传送的个数、函数类型(实在函数、形式函数)过程调用和函数调用的语法形式 ProcFunCall -> id (E1, …… , En)2. 中间代码结构首先生成参数E1,E2,E3…的中间代码然后将实参的计算结果传递到行参中,后面的ti就是前面实参通过中间代码生成的结果最后通过四元式(CALL,<f>,true/false,Resul原创 2020-10-19 21:52:03 · 4354 阅读 · 0 评论 -
编译原理(十四)——中间代码生成(2)
一、表达式的中间代码生成基于LL(1)方法原始不带有语义动作的LL(1)文法:简单表达式带有语义动作的LL(1)文法:GenCode安排在一个运算符的右分量后面,因为这个时候涉及到这个运算符的所有操作数都已经进入语义栈Gem中,可以进行该运算符的计算,生成对应的四元式。简单表达式的LL(1)分析表表达式的中间代码生成过程分析举例语义栈看上去压入的是x,但是实际上压入的是x的语义信息。首先对应输入流的第一个字符x,文法从E开始推导,(这里的语义栈是从左往右写的),使用E->T Es原创 2020-10-14 20:32:08 · 2374 阅读 · 0 评论 -
编译原理(十三)——中间代码生成(1)
一、生成中间代码的目的便于优化让生成的目标代码效率更高优化不等同于对代码的精简和算法的优化(对于高级程序设计语言中可能不能继续进行优化,但是仍然可以在编译中进行优化)比方说多维下标变量地址计算过程,比方说a[i][j]和 a[i][k],我们在计算他们的地址的时候都先要计算a[i]的地址然后再计算j k 的地址,实际上a[i]的计算过程实际上是重复计算了便于移植编译前端:与目标机无关编译后端:与目标机相关中间代码起到一个将一对一翻译转换成一对多对一的关系,通过编译前段可以不用改变,编译后原创 2020-10-12 23:40:35 · 6713 阅读 · 0 评论 -
编译原理(十二)——语义分析、符号表管理、goto语句
一、符号表管理1.1 语义分析部分三个核心知识点abcd选择和当前位置最近的声明性出现映射关系建立之后,变量的名字即无用,知道语义信息即可1.2 处理原则在程序运行到某一个位置的时候是有效的。1.3 Pascal语言的符号表的管理二、goto语句...原创 2020-10-07 18:24:13 · 4432 阅读 · 0 评论 -
编译原理(十一)——抽象地址、符号表
一个标识符的语义信息含有三部分内容,种类 类型 抽象地址种类可以分为:常量标识符、类型标识符、变量标识符、域名标识符、过函标识符类型可以有:基本数据类型、子界、数组、枚举、结构体、集合、文件、指针等等语义分析:静态分析——静态语义动态分析——动态语义核心:程序中是否有语义错误在语义分析阶段要构建一个符号表为整个后序过程提供支持一、抽象地址1.1 地址分配在进行编译的时候为每一个变量标识符都分配一个相对地址,当目标程序在真正运行的时候,一旦首地址确定下来,那么所有的变.原创 2020-10-05 22:22:38 · 2731 阅读 · 0 评论 -
编译原理(十)——语义分析基础
一、语义检查的内容1. 1语法和语义的区别1.2 程序设计语言语义的分类1.3 语义分析的功能1.4 语义错误检查首先可能要检查程序中标识符的声明问题,程序设计语言可以分为强类型语言和弱类型语言。强类型:要求所有用到的表示符必须经过声明,而且在一个程序的作用域内只声明一次,因此需要检查有没有变量的声明、标识符有没有重复声明。涉及到条件表达式的部分都要求是bool类型或者是逻辑值类型,大多数语言要求是一个逻辑值,现在很多语言用0或非0来进行判断,原来的语言一般要求是逻辑类型。运算符是否原创 2020-10-05 21:06:06 · 5976 阅读 · 0 评论 -
编译原理(九)——递归下降法
背景:自定向下的语法分析方法,LL(1)是一种非常直观的方法,它的分析过程是按照句子的定义来进行的,也就是说从开始符出发对要分析的串进行推导,如果推导成功就证明这个被分析的串是一个合法的句子,否则的话就有语法错误,但是在推导过程中,对文法进行了一些限定,保证推导过程是唯一的 。总体上说,LL(1)就是在选择规则的时候加入了约束条件,考虑到输入流中的第一个符号,以及推导过程中的非终极符的规则选择,只有当头符属于当前Vn为左部的某条规则的Predict 集的时候,才使用该规则进行推导,否则即错。对规则的.原创 2020-09-24 10:11:45 · 13748 阅读 · 3 评论 -
编译原理(八)——LL(1)语法分析
一、LL(1)语法分析原理LL(1)文法定义中的条件是为了满足选择规则时的唯一性,在我们选择规则的时候只能选择其中的一条规则进行推导,依据这样的思想构造的语法分析程序叫做LL(1)语法分析程序替换就是直接使用右部代替左部,而待判断字符串不变匹配需要分析栈和字符串同时改变整个语法分析器的结构:stack就是所谓的栈,栈顶是X1,分析的对象是输入流,这是我们用到的两个分析对象:VT是终极符集合(Terminal),非终极符集合。二、LL(1)分析表的构造终极符VT里还要增加一个#,竖着写非终原创 2020-09-22 11:42:07 · 4168 阅读 · 0 评论 -
编译原理(七)——自顶向下语法分析概述
自定向下语法分析从起始符出发,按照所给规则进行尝试性推导看是否能够得到当前所给字符串abbd每一步从第一条规则进行匹配,如果没有匹配上则回溯,一直回溯到起点如果没有找到相应的字符串则当前字符串不符合规则(注意不要遗漏情况)先分析所给子串具有的特点然后再去选择对应的规则进行归约。把不可能实现的内容直接删除,在分析的过程中考虑输入流的信息。First集(alpha短语)根据串进行定义的,可以根据一个串来求first集,指的是能用这个串推出来的所有可以作为终极符的集合。推出以哪些终极符作为开头的串,这原创 2020-09-21 21:31:20 · 1257 阅读 · 0 评论 -
编译原理(六)——语法树、二义性文法、正则文法与自动机
语法树的定义eg:while分析叶节点从左到右得到一个句型语法树应该是一种什么样的直观形式,首先它是一颗树,每个节点都有一个语法符号,根节点是开始符,每个节点的子节点从左到右连在一起都是符合某一个语法规则,满足这样的条件比如循环语句while循环 while(E) do F 然后E条件可以从E处继续生长,循环体F可以从F继续生长,长到最后都变成终极符的时候是一个具体的循环语句,这种形式让我们在对语句真正进行处理的,提取循环的条件 或者是提取循环体边的很容易,因为每个语句又是一些复合语句,循环体原创 2020-09-21 21:12:17 · 11829 阅读 · 0 评论 -
编译原理(五)语法分析
语法分析一、语言与文法程序设计语言与自然语言有一个重要的区别,程序设计语言需要把语言的三个基本要素设计出来:语法、语义、语用;但是在自然语言叙述的时候只需要通话双方可以相互理解即可。(程序设计语言必须清晰)那么为什么要定义文法呢?为什么没有直接讨论语法?语法的形式化表达方式——文法,在程序设计中需要将语言使用形式化的方式来表达,用程序解决问题的时候需要使用比较规范的形式描述出来才容易实现。(目的就是清楚的描述问题)也就是说文法是语法的一种载体,通过文法的规则来描述实际上的语法。通俗说法就是把原创 2020-09-09 19:56:34 · 1264 阅读 · 0 评论 -
编译原理(四)——自动机与正则表达式
一、自动机与正则表达式的关系DFA到正则表达式结构化程序语言:(非结构化转换成结构化再转换成正则表达式)顺序、分支、循环终止状态集的处理增加一个终止状态,所有原有的终止状态都有一个null输入转换为同一个终止状态,然后进行正则表达式的转换比较方便。a(ab|ba)a*b正则表达式到NFA(考点)往回转换的话,给一个正则表达式,怎么构造自动机这个构造过程相当于一个逆过程,开始的时候是开始状态然后是表达式然后是终止状态。注意一下循环的格式:2 在自己本身的同时前面和后面要有一个n原创 2020-09-07 20:31:07 · 3544 阅读 · 0 评论 -
编译原理——非确定有限自动机(三)
非确定有限自动机一、非确定有限自动机的定义(NFA)NFA和DFA的区别:接收的字符可以是空(即当前状态可以接收一个null字符然后转移到另一个状态);一个状态接收一个字符之后可以转换到多个状态。描述问题可能更加灵活。NFA所能接收的串是否和DFA相同?NFA所能接收的串和DFA所能接收的串的定义相同:从开始状态出发到终止状态的路径中的字符所连成的串,构成了NFA所能接收的符号串。二、NFA的一些问题输入null也可以把1状态看成是初始状态。描述方便但是实现困难(DFA实现的时候我们知道原创 2020-09-02 18:56:47 · 4527 阅读 · 0 评论 -
编译原理——确定有限自动机(二)
一、确定有限自动机1. 确定有限自动机的定义⚠️注意这里说的是终止状态集,即终止状态不唯一包含定义:字符集(圈中内容)、状态集(圆圈)、状态转移函数(箭头)、初始状态S、终止状态集(同心圆)2. DFA的确定性2的解释:一个状态接收一个符号得到一个值(相当于函数的一一映射)3. DFA的表示状态转移矩阵二元函数直接填写对应的数值;要满足表示5元组,初始和终止要单独表示出来。无值地方填缺省。优势:是一种更为直观的表现形式,是真实在程序使用的实现手段,是一种更加容易实现的方法,用一原创 2020-08-31 21:34:39 · 3539 阅读 · 1 评论 -
编译原理——词法分析(一)
词法分析词法分析器的接口:作为语法分析程序的子程序(每次将词法分析程序作为一个函数,得到一个token发给语法分析程序)——实际使用的编译器常用的实现形式作为编译器的独立一遍处理器——课堂理解单词的分类及内部表示定义:单词语言中具有独立含义的最小语义单位lexical analysis method//划分的形式:这三个单词即最小x1+y//x1 + y,x1不能继续划分,与用户写这段程序时的含义要符合分类:程序中会出现什么类型的单词,每种类型的单词处理的方式不同保留字(一个语言保原创 2020-08-26 16:22:14 · 4452 阅读 · 1 评论 -
编译原理历年试题分析(大题向待补充)
前言2020.9.6近几年的大题考法以及【】中出现的为出题次数,大致就这些题型,下面的问题还需要再整理(挖了3个坑):将题目归一化有序化;每种类型的题目给出例题;每种类型的题目根据题目的发展给出一般的答题模版和巧思请画出编译器的功能结构图(简述典型编译器的构成以及各个部分的功能和作用)【2】典型编译程序在逻辑功能上由哪几部分组成【3】简述DFA和NFA有哪些主要区别?a/NFA有多个初始状态b/NFA的输入可以是nullc/NFA同一个输入可以转换到多个不同的状态设计确定有原创 2020-09-06 09:33:10 · 1572 阅读 · 1 评论