自己动手构造编译原理 & CSAPP 笔记

来源:互联网 发布:ds数据精灵破解 编辑:程序博客网 时间:2024/06/03 18:31

1.编译原理入门

1.1编译的流程:

这里写图片描述

1.2静态链接 & 动态链接:

这里写图片描述

相比静态链接,动态链接不会把公用哭的目标文件合并到可执行文件内,而仅仅记录动态链接库的路径信息

1.3将hello.c编译并静态链接为可执行文件:

$gcc hello.c -o hello -static --verbose

1.4预编译:

$gcc -E hello.c -o hello.i

1.5编译:

$gcc -S hello.i -o hello.s

1.6汇编:

$gcc -c hello.s -o hello.o

1.7链接:

$gcc hello.o -o hello

2.编译程序设计

2.1编译器结构:

这里写图片描述

2.2词法分析:通过词法分析器将输入的高级语言源程序识别出不同形式的词法记号,通过使用一些有限自动机就可以识别出所有的词法记号,并且将这些词法记号记录下来,作为下一步语法分析的输入。如果使用一遍编译方式,就不用记录这些词法记号,而是直接将识别的词法记号送入语法分析器进行处理。

这里写图片描述

2.3语法分析:语法分析的输入是词法分析器识别的词法记号序列,而输出是一种树形的数据结构,称之为语法树。

这里写图片描述

而语法分析器的作用,便是通过不同高级语言的文法表示,选择不同的文法分析算法,而在《自己….》一书中使用的相对简单的LL(1)分析器。而递归下降子程序是LL(1)算法的一种便捷的实现方式。它的基本原则是将产生式左边的非终结符转化为函数定义,将产生式右边的非终结符转化为函数调用。例如var2 = var1 + 100;这个语句对应的子程序伪代码大致:

void 赋值语句(){    match(标识符);    match(等号);    表达式();    match(分号);}

这里写图片描述

如图为var2 = var1 + 100;的语法树

2.4符号表管理:符号表是记录符号的数据结构。

这里写图片描述

对于变量符号,需要在符号表中记录变量的名称,类型,区分变量的声明和定义的形式。对于函数符号,需要在符号表中记录函数的名称,返回类型,参数列表,以及函数内定义的所有局部变量等等。而且在代码分析的过程中,符号表还需要根据作用域的变化动态维护变量的可见性。

2.5语义分析:考虑语法模块上下文之间联系的合法性。

这里写图片描述

2.6代码生成:代码生成阶段,编译器根据识别的语法模块翻译出目标机器的指令。

这里写图片描述

2.7编译优化:编译优化是指在现代编译器中,一般被设计成前端、优化器、后端三部分。前端包括词法分析,语法分析和语义分析。后端包含指令选择、指令调度和寄存器分配。而优化器则负责对中间代码进行优化操作。
如下列代码:

var2 = var1 + 100

生成的中间代码:

tmp = var1 + 100var2 = tmp

而通过了常量传播优化后的代码可能如下:

var1 = 100tmp = 200var2 = 200

通过了死代码消除优化后的代码可能如下:

var2 = 200

最终生成的汇编代码为:

mov [var2],200

2.8 x86指令格式:

这里写图片描述

在汇编器语法分析阶段,应该记录生成的二进制指令需要的信息。指令的名称决定操作码,指令的寻址方式决定ModR/M和SIB字段,指令中的常量决定偏移量和立即数部分。

2.9ELF文件格式

这里写图片描述

2.10汇编程序设计:

这里写图片描述

汇编器和编译器十分的相似,而最大的不同是汇编器需要对源文件进行两次扫描,其根本原因是汇编语言允许符号的后置定义,因此汇编器需要通过第一遍扫描获取符号的信息,第二遍扫描时使用符号的信息。

2.11链接程序的设计??????????

这里写图片描述

3.编译器构造

3.1词法分析:

#define BUFLEN 80int lineLen = 0;int readPos = 1;char line[BUFLEN];int lineNum = 1;int colNum = 0;char lastch = ch;char scan(FILE*file){    if(!file){        return -1;    }    if(readPos == lineLen - 1){        lineLen = fread(line,1,BUFLEN,file);        if(lineLen == 0){            lineLen=1;            line[0] = -1;        }        readPos = -1;    }    readPos ++;    char ch = line[readPos];    if(lastch == '\n'){        lineNum ++;        colNum = 0;    }    if(ch == -1){        fclose(file);        file = NULL;     }else if(ch != '\n'){        colNum ++;    }    lastch = ch;    return ch;} 
原创粉丝点击