编译,利用编译程序从源语言编写的源程序产生目标程序的过程。计算机只认识1和0,编译程序把高级语言语言换成二进制。
编译分为五个阶段:词法分析;语法分析;语义检查和中间代码生成;代码优化;目标代码生成。
Lex
Lex
是美国Bell实验室M.Lesk等人用C语言开发的一种词法分析器自动生成工具,提供一种供开发者编写词法规则的语言以及这种语言的翻译器。基本工作原理为:由正规式生成NFA,将NFA变换成DFA,DFA经化简后,模拟生成词法分析器。
Lex源程序分为三部分,三部分之间以符号%%分隔。以%开头的符号和关键字,或者词法规则段的各个规则一般顶着行首来写,前面没有空格。
1 | 第一部分:定义段 |
第一部分定义段写法
第二部分词法规则段写法
第三部分辅助函数段写法
GCC/G++
gcc [options] [filenames]
参数 | 描述 |
---|---|
-c | 只编译,不链接成为可执行文件 |
-o | 指定输出文件名称 |
-g | 产生符号调试工具所必要的符号信息 |
-O | 对程序进行优化编译、链接 |
-O2 | 比 -O 更好的优化编译、链接 |
-Idirname | dirname 所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数 |
-E | 预编译后停下来,生成后缀为 .i 的预编译文件 |
-c | 编译后停下来,生成后缀为 .o 的目标文件 |
-S | 汇编后停下来,生成后缀为 .s 的汇编源文件 |
-pedantic | gcc在编译不符合ANSI/ISO C 语言标准的源代码时,将产生相应的警告信息 |
-Wall | 使 gcc 产生尽可能多的警告信息 |
-Werror | 所有的警告当成错误进行处理 |
-Wcast-align | 地址不需要对齐的指针指向一个地址需要对齐的变量地址时,则产生一个警告 |
-I | 向 gcc 的头文件搜索路径中添加新的目录 |
-L | 向 gcc 的库文件搜索路径中添加新的目录 |
-l | 链接时装载函数库 |
-static | 强制使用静态链接库 |
-shared | 生成一个共享的目标文件 |
-g/-ggdb | 不会将调试符号插入到生成的二进制代码中,因为这样会增加可执行文件的大小 |
-p/-pg | 将剖析(Profiling)信息加入到最终生成的二进制代码中 |
-save-temps | 保存编译过程中生成的一些列中间文件 |
测试 example.c
1 | #include <stdio.h> |
编译原理之美
前端
指的是编译器对程序代码的分析和理解过程。通常只跟语言的语法有关,跟目标机器无关。前端
技术分为词法分析、语法分析和语义分析三个部分,主要涉及自动机和形式语言方面的基础的计算理论。
后端
生成目标代码的过程,跟目标机器有关。
词法分析
词法分析器分析整个程序字符串,当遇到不同的字符时,会驱使它迁移到不同的状态。
语法分析
词法分析是识别一个个的单词,而语法分析就是在词法分析的基础上识别出程序的语法结构。
程序有定义良好的语法结构,语法分析过程就是构造这么一棵树。程序就是一棵抽象语法树(Abstract Syntax Tree,AST)。
树的每个节点(子树)是一个语法单元,这个单元的构成规则就叫语法
。每个节点还可以有下级节点。
AST让计算机很容易去处理。
Reference: