简单的编译流程

简易编译器流程图:

一个典型的编译器,可以包含为一个前端,一个后端。前端接收源程序产生一个中间表示,后端接收中间表示继续生成一个目标程序。所以,前端处理的是跟源语言有关的属性,后端处理跟目标机器有关的属性。

复杂的编译器:

词法分析器:

1.词法分析器读入源代码,然后对字符流(源代码)做切分成记号流。举个例子:

    这是一个程序员看到的字符流(源代码)

2.词法分析器将字符流读入,根据关键字、标识符、标点、字符串、整形数等进行划分,形成记号流(单词):

    

 举个例子: 假如源语句if(x>5),则词法分析器返回token{k=IF,lexeme=0};token{k=LPAREN,lexeme=0};token{k=ID,lexeme="X"};……

词法分析器的任务:字符流到记号流。

       字符流:和被编译语言密切相关(ASCII,Unicode,or……)

       记号流:编译器内部定义的数据结构,编码所识别出的词法单元

语法分析器:

 语法分析器(Parser)通常是作为编译器或解释器的组件出现的,它的作用是进行语法检查(检查语法是否符合这个语言的规则)、并构建由输入的单词组成的数据结构(一般是语法分析树、抽象语法树等层次化的数据结构)。语法分析器通常使用一个独立的词法分析器从输入字符流中分离出一个个的“单词”,并将单词流作为其输入。实际开发中,语法分析器可以手工编写,也可以使用工具(半)自动生成。

抽象语法树是对程序语法的抽象表示

例如,当在开发语言时,可能在开始的时候,选择LL(1)文法来描述语言的语法规则,编译器前端生成LL(1)语法树,编译器后端对LL(1)语法树进行处理,生成字节码或者是汇编代码。但是随着工程的开发,在语言中加入了更多的特性,用LL(1)文法描述时,感觉限制很大,并且编写文法时很吃力,所以这个时候决定采用LR(1)文法来描述语言的语法规则,把编译器前端改生成LR(1)语法树,但在这个时候,你会发现很糟糕,因为以前编译器后端是对LL(1)语树进行处理,不得不同时也修改后端的代码。

1.抽象语法树的第一个特点为:不依赖于具体的文法。无论是LL(1)文法,还是LR(1),或者还是其它的方法,都要求在语法分析时候,构造出相同的语法树,这样可以给编译器后端提供了清晰,统一的接口。即使是前端采用了不同的文法,都只需要改变前端代码,而不用连累到后端。即减少了工作量,也提高的编译器的可维护性。

2.抽象语法树的第二个特点为:不依赖于语言的细节。在编译器家族中,大名鼎鼎的gcc算得上是一个老大哥了,它可以编译多种语言,例如c,c++,java,ADA,Object C, FORTRAN, PASCAL,COBOL等等。在前端gcc对不同的语言进行词法,语法分析和语义分析后,产生抽象语法树形成中间代码作为输出,供后端处理。要做到这一点,就必须在构造语法树时,不依赖于语言的细节,例如在不同的语言中,类似于if-condition-then这样的语句有不同的表示方法

语义分析器:

对语法树的合法性进行处理(例如:一个变量在使用之前是否先定义声明,所调用的函数是否有对应的定义),产生相应的中间代码或目标代码.

语义分析是编译过程的一个逻辑阶段, 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查,进行类型审查。语义分析是审查源程序有无语义错误,为代码生成阶段收集类型信息。比如语义分析的一个工作是进行类型审查,审查每个算符是否具有语言规范允许的运算对象,当不符合语言规范时,编译程序应报告错误。如有的编译程序要对实数用作数组下标的情况报告错误。又比如某些程序规定运算对象可被强制,那么当二目运算施于一整型和一实型对象时,编译程序应将整型转换为实型而不能认为是源程序的错误。

经过上面的处理,程序中就没有在包括语言和语义的错误(除非编译器本身就有bug)

中间代码

  中间代码也叫中间语言

(Intermediate code /language)是:源程序的一种内部表示,不依赖目标机的结构,复杂性介于源语言和机器语言之间。

中间代码的优点

1、逻辑结构清楚;

2、利于不同目标机上实现同一种语言;

3、利于进行与机器无关的优化;

中间代码可以生成例如 三地址代码 SSA 控制流图 等 (中间码的生成也是取决于编译器设计中的考虑,例如需不需要优化,或者追求速度,性能等).

关于语法分析器和中间代码:

LINK: https://blog.csdn.net/yongchaocsdn/article/details/79056504

代码生成:

中间代码可以被最终的一个代码生成的阶段处理为最后的目标代码(例如机器码,JVM字节码)

符号表

符号表是存储程序编译过程中重要信息,可以给每个阶段提供支持

在计算机科学中,符号表是一种用于语言翻译器(例如编译器和解释器)中的数据结构。在符号表中,程序源代码中的每个标识符都和它的声明或使用信息绑定在一起,比如其数据类型、作用域以及内存地址。

符号表在编译程序工作的过程中需要不断收集、记录和使用源程序中一些语法符号的类型和特征等相关信息。这些信息一般以表格形式存储于系统中。如常数表、变量名表、数组名表、过程名表、标号表等等,统称为符号表。对于符号表组织、构造和管理方法的好坏会直接影响编译系统的运行效率。

举个例子:

一个加法表达式(sum)在编译中的过程:

例如sum的语法规则是:

1.整数数字 n

2.加法表达式式 n1+n2

根据上面的规则

3

1+2

1+2+3  (加法表达式遵循左结合也就是 1+2 的结果 3+3 这也属于加法表达式的一种)

这上面的三种都遵守了加法表达式的规则  所以都是加法表示式的一种

目标机器: 栈式计算机(stack)

是一个LIFO的一个先入后出存储器,跟它向对应的是FIFO存储器先入先出传统顺序

有两条指令:

1.push n (将指定的参数压入栈中)

2.add (将栈顶的两个索引的数据弹出并进行加法运算,再将运算后的结果压入栈中)

//x和y表示栈顶的数据 pop[]表示弹出栈顶的数据
x = pop[]y = pop[]//加法运算
n = x+y//压栈
push n

例如1+2+3加法运算经过语法分析器翻译抽象语法树(AST):

1+2+3 =语法分析器:      语法树(+)(+)     (3)(1)   (2)

先从左结合开始:

1+2 = 3

3+3 = 6

生成栈式计算机(stack)的代码:

代码生成使用树的后续遍历(从树的左边子节点开始遍历,然后遍历右边子节点最后遍历根节点)

代码生成规则:

1. 遍历树中时如果遇到整数 n 生成代码: push n

2.遍历树中时如果遇到 + 生成代码: add

最后生成的栈式计算机的代码:

push 1push 2addpush 3add

 

转载于:https://www.cnblogs.com/sybk/p/10004706.html

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

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

相关文章

广告投手_测量投手隐藏自己的音高的程度

广告投手As the baseball community has recently seen with the Astros 2017 cheating scandal, knowing what pitch is being thrown gives batters a game-breaking advantage. However, unless you have an intricate system of cameras and trash cans set up, knowing wh…

验证部分表单是否重复

1. 效果 图片中的名称、机构编码需要进行重复验证2. 思路及实现 表单验证在获取数据将需要验证的表单数据进行保存this.nameChangeTemp response.data.orgName;this.codeChangeTemp response.data.orgCode; 通过rule对表单进行验证 以名字的验证为例rules: {orgName: [// 设置…

python bokeh_提升视觉效果:使用Python和Bokeh制作交互式地图

python bokehLet’s face it, fellow data scientists: our clients LOVE dashboards. Why wouldn’t they? Visualizing our data helps us tell a story. Visualization turns thousands of rows of data into a compelling and beautiful narrative. In fact, dashboard vi…

用C#写 四舍五入函数(原理版)

doubled 0.06576523;inti (int)(d/0.01);//0.01决定了精度 doubledd (double)i/100;//还原 if(d-dd>0.005)dd0.01;//四舍五入 MessageBox.Show((dd*100).ToString()"%");//7%,dd*100就变成百分的前面那一部分了

浪里个浪 FZU - 2261

TonyY是一个喜欢到处浪的男人,他的梦想是带着兰兰姐姐浪遍天朝的各个角落,不过在此之前,他需要做好规划。 现在他的手上有一份天朝地图,上面有n个城市,m条交通路径,每条交通路径都是单行道。他已经预先规划…

C#设计模式(9)——装饰者模式(Decorator Pattern)

一、引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手…

nosql_探索NoSQL系列

nosql数据科学 (Data Science) Knowledge on NoSQL databases seems to be an increasing requirement in data science applications, yet, the taxonomy is so diverse and problem-centered that it can be a challenge to grasp them. This post attempts to shed light on…

C++TCP和UDP属于传输层协议

TCP和UDP属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它事先为要发送的数据开辟好连接通道(三次握手),然后再进行数据发送;而UDP则不为IP提供可靠性,一般用于实时的视频流传输,像rtp、r…

程序员如何利用空闲时间挣零花钱

一: 私活 作为一名程序员,在上班之余,我们有大把的时间,不能浪费,这些时间其实都是可以用来挖掘自己潜在的创造力,今天要讨论的话题就是,程序员如何利用空余时间挣零花钱?比如说周末…

python中api_通过Python中的API查找相关的工作技能

python中api工作技能世界 (The World of Job Skills) So you want to figure out where your skills fit into today’s job market. Maybe you’re just curious to see a comprehensive constellation of job skills, clean and standardized. Or you need a taxonomy of ski…

欺诈行为识别_使用R(编程)识别欺诈性的招聘广告

欺诈行为识别背景 (Background) Online recruitment fraud (ORF) is a form of malicious behaviour that aims to inflict loss of privacy, economic damage or harm the reputation of the stakeholders via fraudulent job advertisements.在线招聘欺诈(ORF)是一种恶意行为…

c语言实验四报告,湖北理工学院14本科C语言实验报告实验四数组

湖北理工学院14本科C语言实验报告实验四 数组.doc实验四 数 组实验课程名C语言程序设计专业班级 14电气工程2班 学号 201440210237 姓名 熊帆 实验时间 5.12-5.26 实验地点 K4-208 指导教师 祁文青 一、实验目的和要求1. 掌握一维数组和二维数组的定义、赋值和输入输出的方法&a…

rabbitmq channel参数详解【转】

1、Channel 1.1 channel.exchangeDeclare(): type:有direct、fanout、topic三种durable:true、false true:服务器重启会保留下来Exchange。警告:仅设置此选项,不代表消息持久化。即不保证重启后消息还在。原…

nlp gpt论文_GPT-3:NLP镇的最新动态

nlp gpt论文什么是GPT-3? (What is GPT-3?) The launch of Open AI’s 3rd generation of the pre-trained language model, GPT-3 (Generative Pre-training Transformer) has got the data science fraternity buzzing with excitement!Open AI的第三代预训练语言…

真实不装| 阿里巴巴新人上路指北

新手上路,总想听听前辈们分享他们走过的路。橙子选取了阿里巴巴合伙人逍遥子(阿里巴巴集团CEO) 、Eric(蚂蚁金服董事长兼CEO)、Judy(阿里巴巴集团CPO)的几段分享,他们是如何看待职场…

小程序学习总结

上个周末抽空了解了一下小程序,现在将所学所感记录以便日后翻看;需要指出的是我就粗略过了下小程序的api了解了下小程序的开发流程以及工具的使用,然后写了一个小程序的demo;在我看来,如果有前端基础学习小程序无异于锦上添花了,而我这个三年的码农虽也写过不少前端代码但离专业…

uber 数据可视化_使用R探索您在Uber上的活动:如何分析和可视化您的个人数据历史记录

uber 数据可视化Perhaps, dear reader, you are too young to remember that before, the only way to request a particular transport service such as a taxi was to raise a hand to make a signal to an available driver, who upon seeing you would stop if he was not …

java B2B2C springmvc mybatis电子商城系统(四)Ribbon

2019独角兽企业重金招聘Python工程师标准>>> 一:Ribbon是什么? Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如…

基于plotly数据可视化_[Plotly + Datashader]可视化大型地理空间数据集

基于plotly数据可视化简介(我们将创建的内容): (Introduction (what we’ll create):) Unlike the previous tutorials in this map-based visualization series, we will be dealing with a very large dataset in this tutorial (about 2GB of lat, lon coordinat…

Centos用户和用户组管理

inux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。1、添加新的用户账号使用useradd命令,其语法如下:useradd 选项 用户名-…