美文网首页码农庄园
[转]编译原理概述

[转]编译原理概述

作者: 小马过河R | 来源:发表于2022-03-17 09:32 被阅读0次

参考原文

程序员的入门其实非常简单。

打开任何一个文本编辑器(例如vim),输入下面的C代码:

#include<stdio.h>

int main()

{

printf(“hello world\n”);

return 0;

}

保存为一个扩展名为.c的文件hello.c,

然后用gcc去编译它,命令为:

gcc hello.c

就可以生成一个可执行文件a.out,

运行它就可以让计算机打印出字符串hello world。

以上就是C语言入门教材的第一节内容,其他语言的第一节内容也大同小异。

但是,你要是多问一下为什么可以这样,就可能把教你C语言的人直接问住,这就是编译原理。

C语言的源程序是一个文本文件

要想把它们转化为01机器码,首先要根据空格、换行、加减乘除等符号把程序文本分割为一个个的单词,这一步就叫作词法分析

词法分析之后的程序文本,与人眼看到的源程序是一样的程序从一个各种单字符构成的一个大型字符串,变成了一个个的有意义的单词

经过词法分析之后的程序,已经属于编译器的内部表示了,脱离了源程序选择的基础母语(英文、中文、或其他语言)。

接下来要做的是语法分析这一步是基于编程语言的语法进行的已经与编程语言的基础母语无关了。条件语句的关键字不管是叫if还是如果,到了这一步时都会被编译器给一个数字编号,例如15

语法分析是编译器里最复杂的代码,它会处理各种复杂的程序逻辑,最终构建一颗抽象语法树(AST)

像多个if只有一个else的情况下,else应该隶属于哪个if,就是语法分析时要处理的问题。

例如:

int a = 0;

if (1 == 1)

if (2 == 2)

a = 2;

else

a = 1;

上面的else属于最近的if,即第二个if,这种代码都是在语法分析时处理的。

当然也可以规定它属于最远的if,但这么搞会让程序员用起来很不舒服。在技术上可以实现,但在产品体验上非常不好。

语法分析完成之后,只要遍历语法树,就可以获得类似汇编语言的三地址码序列。它是具有复杂逻辑的源程序的线性化结果。源程序都是有反应人类思维的复杂逻辑结构的,最终要转化成01数字构成的线性表,才可以装入内存运行。内存,本质上也是一个高达几个G的线性表。

三地址码序列,就是这个转化的起点

从这里开始,程序像汇编语言一样,依赖条件判断和跳转来表达复杂的循环结构。例如源代码中的for循环。

然后,把三地址码换成汇编码,再把汇编码换成机器码,就可以在电脑上运行了。

当然机器码也可以是运行在虚拟机上的,而不是直接运行在CPU上的,就像java那样。使用虚拟机可以更容易的跨平台。

汇编码和机器码是一一对应的,只是汇编更容易被人读懂,机器码是用于电脑的

在三地址码转化到机器码时有一个非常难的问题,就是机器指令的选择和寄存器的分配。这是一个NP问题,在现有数学理论上只能求得近似解。

在编译原理的后端,实际上会涉及到很难的数学问题。优化的越好,涉及的数学越难。

总结:

文本文件=>词法分析(文本字符切成有意义的单词)=>语法分析[如少括号]+语义分析[如变量赋值类型不符合](单词if或如果都将是同一个数字编号,并带有逻辑意义的抽象语法树AST)=>遍历语法树(获得类似汇编语言的三地址码序列)=>三地址码换成汇编码=>汇编码换成01机器码(汇编码和机器码是一一对应的,只是汇编更容易被人读懂,机器码是用于电脑的)=>运行

相关:

一个程序从源代码到可执行程序的过程

相关文章

网友评论

    本文标题:[转]编译原理概述

    本文链接:https://www.haomeiwen.com/subject/yjqvdrtx.html