标签:
java源代码(符合语言规范)-->javac-->.class(二进制文件)-->jvm-->机器语言(不同平台不同种类)
如何让java的语法规则适应java虚拟机的语法规则?这个任务由javac编译器来完成java语言规范转换成java虚拟机语言规范。
编译流程:
流程:
ps:要获取javac编译器,可以通过OpenJDK来下载源码,可以自己编译javac的源码,也可以通过调用jdk的com.sun.tools.javac.main.Main类来手动编译指定的类。
目的:将源码转换为Token流
流程:
一个字符一个字符的读取源代码,形成规范化的Token流。规范化的Token包含:
源码关键:
词法分析过程是在的JavacParser.parseCompilationUnit()中完成的
com.sun.tools.javac.parser.JavacParser 规定哪些词符合Java语言规范,具体读取和归类不同词法的操作由scanner完成
com.sun.tools.javac.parser.Scanner 负责逐个读取源代码的单个字符,然后解析符合Java语言规范的Token序列,调用一次nextToken()都构造一个Token
com.sun.tools.javac.parser.Tokens$TokenKind 里面包含了所有token的类型,譬如BOOLEAN,BREAK,BYTE,CASE。
com.sun.tools.javac.util.Names 用来存储和表示解析后的词法,每个字符集合都会是一个Name对象,所有的对象都存储在Name.Table这个内部类中。
com.sun.tools.javac.parser.KeyWords 负责将字符集合对应到token集合中,如,package zxy.demo.com; Token.PACKAGE = package, Token.IDENTIFIER = zxy.demo.com,(这部分又分为读取第一个token,为zxy,判断下一个token是否为“.”,是的话接着读取下一个Token.IDENTIFIER类型的token,反复直至下一个token不是”.”,也就是说下一个不是Token.IDENIFIER类型的token,Token.SEMI = ;即这个TIDENTIFIER类型的token的Name读完),KeyWords类负责此任务。
例子:
package compile; public class Cifa { int a; int c = a + 1; }
以上代码转化为的Token流:
目的:将进行词法分析后形成的Token流中的一个个Token组成一句句话,检查这一句句话是不是符合Java语言规范。
流程:
源码关键:
com.sun.tools.javac.tree.TreeMaker 所有语法节点都是由它生成的,根据Name对象构建一个语法节点
com.sun.tools.javac.tree.JCTree$JCIf 所有的节点都会继承jctree和实现**tree,譬如 JCIf extends JCTree.JCStatement implements IfTree
com.sun.tools.javac.tree.JCTree的三个属性
例子:
package compile; public class Yufa { int a; private int c = a + 1; //getter public int getC() { return c; } //setter public void setC(int c) { this.c = c; } }
最终语法树
ps:左边还少一个import的语法节点
说明:
目的:将语法树转化为注解语法树
流程:
源码关键:
com.sun.tools.javac.comp.Enter 将java类中的符号输入到符号表中,主要是两个步骤:
com.sun.tools.javac.processing.JavacProcessingEnvironment 处理注解
com.sun.tools.javac.comp.Attr 检查语义的合理性并进行逻辑判断,类型是否匹配,是否初始化,泛型是否可推导,字符串常量合并
com.sun.tools.javac.comp.Check 协助attr,变量类型是否正确
com.sun.tools.javac.comp.Resolve 协助attr,变量方法类的访问是否合法,是否是静态变量
com.sun.tools.javac.comp.ConstFold 协助attr,常量折叠
com.sun.tools.javac.comp.Infer 协助attr,推导泛型
com.sun.tools.javac.comp.Flow 数据流分析和替换等价源代码的分析(即上面的进一步语义分析)
目的:将注解语法树转化成字节码,并将字节码写入*.class文件。
流程:
源码关键:
com.sun.tools.javac.jvm.Gen 遍历语法树生成最终的java字节码
com.sun.tools.javac.jvm.Items 辅助gen,这个类表示任何可寻址的操作项,这些操作项都可以作为一个单位出现在操作栈上
com.sun.tools.javac.jvm.Code 辅助gen,存储生成的字节码,并提供一些能够影射操作码的方法
标签:
原文地址:http://www.cnblogs.com/wade-luffy/p/5925728.html