![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
编译器
文章平均质量分 79
山姆哥up
这个作者很懒,什么都没留下…
展开
-
编译器-最优寄存器分配
而全局寄存器分配是刚好相反的 在comile time需要跟多的时间 但是performance会表现很好 注意全局寄存器分配不需要像局部分配一样在每一个block结束以后需要把所有的def和use都store 然后在新的block中又把需要的所有def和use进行load 全局分配需要通过conlict graph算法求出以插入最少的store和load为代价使得代码能流畅的作为一个整体运行下去。指需要在最左边的block中def b后面插入一个store b 在use b之前插入一个load b即可。.原创 2022-08-18 02:52:26 · 676 阅读 · 0 评论 -
编译器-条件/循环代码生成
BB代表的basic block 这里遇到分支branch 或 jump 或 一个新的label 都是一个basic block。在得到AST之后 编译器会构建这样的一个CFG作为一部分中间表达 每一个baisc block里面有一些线性的汇编指令。在优化代码的时候 划分成这些basic block会使逻辑更加清晰 使得优化工作更加简单。这里的com_LT是比较less than 如果r1比r2小 返回true到r3。cbr是condition branch 如果r3是true 走L1 否则走L2。...原创 2022-08-15 20:03:33 · 248 阅读 · 0 评论 -
编译器-基于AST表达式代码生成
执行完t2 = Expr(node.right);接下来return后 就回到了乘号Op的t1 = Expr(node.left);接下来执行下一行t2 = Expr(node.right);已经执行完毕 return r3 开始执行t2 = Expr(node.right);首先第一步call root 加号+ 调用Expr函数 push进栈中 +是Op 所以会call t1 = Expr(node.left);然后再次进入到Op中的t1 = Expr(node.left);...原创 2022-08-14 22:36:43 · 326 阅读 · 0 评论 -
编译器-语法制导翻译STD
GNU Bison 是一个通用的解析器生成器,它可以将注释的无上下文语法转换为使用 LALR (1) 解析表的确定性 LR 或广义 LR (GLR) 解析器。一旦您熟练使用 Bison,您可以使用它开发广泛的语言解析器,从简单的桌面计算器中使用的解析器到复杂的编程语言。最后Term作为$1 mult作为$2 Factor作为$3 它们的cost分别为 4 3 1 加起来是8 传给上面的$$也就是说 每次在LR(1)文法中执行reduce 7的时候 执行的其实是$$ = $1来生成AST。...原创 2022-08-14 19:09:10 · 227 阅读 · 0 评论 -
编译器-LR(1)
这里其实是无法明确置换的 比如Expr+Term*Factor可以reduce 4 但同时也可以reduce 6形成Expr+Term*Term 也是合规的 这就说明虽然我们通过表达式逻辑可以很容易的做出选择 但是系统没有一个明确的算法去确定合适的选择。但其实在这个例子中就能发现 一旦shift读取一个字符到栈中 只要有合理的置换方式 就需要一直置换下去 直到没有任何一个可以置换且遵循follow的时候 才会继续去shift读取下一个字符到栈中。发现d可以置换成B且不违背follow集 所以形成了aAB。.原创 2022-08-13 04:22:12 · 201 阅读 · 0 评论 -
编译器-LL(1)-First集与Follow集
first集合非常简单 但是要注意follow集合 主要是先看语法箭头右边的内容找到需要判断的符号类型所在位置 如果在行尾 那么就包含箭头左边符号类型的所有follow集合 其次如果不在行尾 就包含后面紧跟着的符号类型的first集 但是要注意的是如果紧跟着的符号类型在first集可以为∈ 那么又要包含箭头左边的符号类型的follow集。//同时第三行Term ‘可以为∈ 那么说明Factor可以作为Term的最后出现 所以要包含Follow(Term)第三行:Term → Factor Term '..原创 2022-08-11 15:45:08 · 542 阅读 · 0 评论 -
编译器-LL1-parsing tree左右递归
第八步:此时读取的是乘号* Term '有三个选择 Term ' → * Factor Term ' | / Factor Term ' | ∈ 刚好对应上了* 而且Term作为一个项也是不允许把*作为结尾的 不能选空 所以构建第一个 并开始读取下一个字符y。第四步:此时读取的是加号+ 而Term '中有三个选择Term ' → * Factor Term ' | / Factor Term ' | ∈ 然而即不是*也不是/ 所以只能选择∈。接下来用转换好的右递归来parse x + 5 * y。.原创 2022-08-10 22:20:00 · 532 阅读 · 0 评论 -
编译器-上下文无关语法
在计算机高级语言中 我们把变量名(identifier) 这一个类作为计算机语言表中的一个symbol 在scanner(词法分析)的过程中 无疑就是传入了一个字符串 返回一个类别 把各种类别组合在一起 形成了context-free language 然后用特定的grammar语法定义去判断这一堆类别组合是不是符合所规定的语法 如果不合规就会出现编译错误。这时在数学中(a + b)是一个factor c也是一个factor (a + b) * c是一个term。......原创 2022-08-10 16:31:45 · 186 阅读 · 0 评论 -
编译器-NFA转DFA
d1是E-closure of q1 即为集合{q1,q2,q3,q4,q6,q9} 这个集合中没有任何一个state走的通a 所以为d空 走b的话集合中q4可以走到E-closure of q5 是个集合需要设为d2 同理走c的话q6可以走到E-closure of q7 是个集合 需要设为d3。d3是E-closure of q7 走a走不通 设为d空 走b的话q4可以走到E-closure of q5 就是d2 走c的话q6可以走到E-closure of q7 即为自己d3本身。.........原创 2022-08-07 20:58:53 · 1194 阅读 · 0 评论 -
编译器-正则表达式转NFA
2.Concatenation 串联、链接的意思。Regular operation (正则操作符)2.Concatenation在NFA中的体现。1.Union 或的意思。3.Star 重复的意思。a (b U c)* 的 NFA。3.Star在NFA中的体现。(b U c)* 的NFA。b U c 的NFA。...原创 2022-08-07 15:32:58 · 140 阅读 · 0 评论 -
编译器-有限自动机和正则表达式
编译器的词法分析是基于finite automata(有穷自动机) 和 regular expression(正则表达式)alphabet:finite set of symbols 字母表:有限符号的集合string:sequence of symbols from a given alphabet 字符串:给定字母表的符号序列language:set of string 字符串的集合例如x12 = 32;中有token;......原创 2022-08-05 22:48:20 · 486 阅读 · 0 评论 -
编译器概述-指令调度的概念
假设每个指令为了得到结果都有一个周期load为3周期mult为2周期div为5周期store为2周期add为1周期注意:这里的周期可以理解为占用的cpu运算资源时间r1r2r3r4r5r6r7x可以看到 第一个load从周期1开始到3经历了1 2 3 三个周期第二个load不依赖于第一个load 所以不需要等待第一个load执行完毕 就可以直接开始执行第三个mult需要依赖于r1和r2的数据 所以必须等上面都执行完毕 再从周期5开始执行。...原创 2022-08-05 19:06:06 · 738 阅读 · 0 评论 -
编译器概述-寄存器分配的概念
可以看出 当只有两个物理寄存器的时候 不能把每一个虚拟寄存器都映射到物理寄存器上 而是需要临时存入内存 这种情况英文中叫spill 就是溢出到内存中的意思 register allocation会尽可能的不去发生spill的情况。其次这里发现r1和r2都存储着真实的变量(variable)a和b 而r3却是一个中转的临时变量(temporaries) 实际中的汇编是没有变量这个概念的 实际中只有寄存器和内存地址。//第一个行抽象汇编指令实际是第二行的简化 第二行才是抽象汇编指令的完整写法。......原创 2022-08-05 16:06:07 · 752 阅读 · 0 评论 -
编译器概述-结构和主要组件
并不是说所有的编译器优化都能保证提高代码速度 只能说优化是有可能提高代码速度 例如上面那个优化就会使得代码在cpu中运行的负担加重 因为t其实只是维护了两个变量的相加 但却要多占用一个寄存器的位置 到不如直接算两遍a+b了 如果t中维护了很多变量 显然这个优化是有用的 所以编译器中的优化无疑不是绝对意义上的智能优化。虽然说看上去优化的这个过程和cpu内部设计是无关的 但是其实这也不是绝对的 寄存器的数量 cpu内部的设计逻辑其实也会影响到优化设计的过程。看一个例子 x = a*b + c*d;...原创 2022-08-04 19:56:20 · 294 阅读 · 0 评论