第10章 前端编译与优化
文章目录
10.2 Javac编译器
10.2.1 Javac的源码与调试
10.2.2 解析与填充符号表
词法、语法分析
- 词法分析: 将源代码的字符流转变为标记(Token)集合的过程,单个字符是程序编写时的最小元素,但标记才是编译时的最小元素。关键字、变量名、字面量、运算符都可以作为标记,如“inta=b+2”标记是int、a、=、b、+、2。由com.sun.tools.javac.parser.Scanner类来实现。
- 语法分析: 根据标记序列构造抽象语法树的过程,抽象语法树(Abstract Syntax Tree,AST)是一种用来描述程序代码语法结构的树形表示方式,抽象语法树的每一个节点都代表着程序代码中的一个语法结构(Syntax Construct),例如包、类型、修饰符、运算符、接口、返回值甚至连代码注释等都可以是一种特定的语法结构。由com.sun.tools.javac.parser.Parser类实现
填充符号表
符号表(Symbol Table)是由一组符号地址和符号信息构成的数据结构。符号表中所登记的信息在编译的不同阶段都要被用到。譬如在语义分析的过程中,符号表所登记的内容将用于语义检查和产生中间代码,在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的直接依据。由com.sun.tools.javac.comp.Enter类实现,该过程的产出物是一个待处理列表,其中包含了每一个编译单元的抽象语法树的顶级节点,以及package-info.java的顶级节点
10.2.3 注解处理器
10.2.4 语义分析与字节码生成
语义分析的任务是对源程序进行上下文检查,譬如类型检查、控制流检查、数据流检查等
- 标注检查
检查变量使用前是否已被声明、变量与赋值之间的数据类型是否能够匹配等,还会顺便进行一个称为常量折叠(Constant Folding)的代码优化(例如int a = 1 + 2;优化为3).实现类是com.sun.tools.javac.comp.Attr类和com.sun.tools.javac.comp.Check类 - 数据及控制流分析
对程序上下文逻辑更进一步的验证,检查程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确处理了等.编译时期与类加载时校验范围有所区别,有一些校验项只有在编译期或运行期才能进行(例如final语义校验).由com.sun.tools.javac.comp.Flow类来完成 - 解语法糖
由desugar()方法触发,在com.sun.tools.javac.comp.TransTypes类和com.sun.tools.javac.comp.Lower类中完成 - 字节码生成
由com.sun.tools.javac.jvm.Gen类来完成。不仅是把前面各个步骤所生成的信息(语法树、符号表)转化成字节码指令 写到磁盘中,还进行了少量的代码添加和转换工作