语法分析器 java_Kotlin 编译之路 "JAVA编译器"

本文详细介绍了Java的编译过程,包括词法分析、语法分析、语义分析和字节码生成,强调了Javac如何将源代码转化为JVM能识别的字节码。通过对Java编译的理解,有助于进一步掌握Kotlin等与Java兼容的编程语言的编译原理。
摘要由CSDN通过智能技术生成

d32c254c5ed2e0435788f0d14420201e.png

背景

最近同事技术分享时讲到了Kotlin,主要从语法角度和业务实战角度进行了详细的剖析,当然我们大家都知道Kotlin是基于JVM(Java 解释器/Java 虚拟机)的,也就是说通过Kotlin编译器生成的字节码与Java通过Java编译器生成的字节码应该是相同的,都同属JVM字节码,所以它与Java可以完美兼容,同时语法更加简洁,不由让我对Kotlin的编译过程产生了浓厚的兴趣。Kotlin是开源的,但是代码量还是比较庞大的,无从下手,那既然它和Java编译过程如此相似,就让我们来探究一下Java编译器都干了什么。

Java 温习

f3b9c04c529922a5ddfb942308a888ba.png
编译&执行

上图是Java的编译和执行的基本过程,由Javac编译器来完成。

Javac能将一种语言规范转化成另外一种语言规范,通常编译器都是将便于人理解的语言规范转化成机器容易理解的语言规范,如C/C++或者汇编语言都是将源代码直接编译成目标机器码,这个目标机器代码是CPU直接执行的指令集合。这些指令集合也就是底层的一种语言规范,详细了解可参阅下面的链接。
小萝卜:源程序->可执行程序​zhuanlan.zhihu.com
dcdcd0c7d68cfce51d88630ba097d297.png

Javac编译器的主要目的主要是将程序员都能理解的编程语言编译成对对所有机器都非常友好的一种语言。这种语言不是针对某种机器或某个平台。如何消除不同种类,不同平台之间的差异就是JVM应该来处理的事情,而Javac的主要任务就是将Java源代码语言转化为JVM能够识别的一种语言,然后由JVM将JVM语言再转化成当前这个机器能够识别的机器语言。

词法分析

将源代码逐字节读取,从而找出这些词法中我们定义的语言关键词,例如:if、else、for等等,识别哪些if是合法的哪些是不合法的。这个步骤就是词法分析过程。

词法分析就是将关键词组织成token流即检查源码中的的关键词是否真确并组织成token流。

70222cf78d3f641e02c35b4beb65b527.png
词法分析
词法分析的结果:就是从源代码中找出了一些规范化的token流,就像人类语言中,给你一句话你要分辨出哪些是一个词语,哪些是标点符号,哪些是动词,哪些是名词。

语法分析

针对词法分析中得到的token流进行语法分析,这一步就是检查这些关键词组合在一起是不是符合语言规范(Java)。如if的后面是不是紧跟着一个布尔型判断表达式。

语法分析就是检查源码是否符合java语法规范并将词组成语句。

fa5d6b6d1d37f7ede699045261f08bc5.png
语法分析
语法分析的结果:就是形成一个符合语言(Java)规范的抽象语法树,抽象语法树是一个结构化的语法表达形式,它的作用是把语言的主要词法用一个结构化的形式组织在一起。这棵语法树可以被后面按照新的规则再重新组织。

语义分析

语法分析完成之后也就不存在语法问题了,语义分析的主要工作就是把一些难懂的,复杂的语法转化成更简单的语法。就如难懂的文言文转化为大家都懂的百话文,或者是注释一下一些不懂的成语。

语义分析就是简化复杂的添加缺少的,检查变量类型是否合法。

482ced6654c4b739f22509e0c2f05f4e.png
语义分析
语义分析结果:就是将复杂的语法转化为简单的语法,对应到Java就是将foreach转化为for循环,还有一些注释等。最后生成一棵抽象的语法树,这棵语法树也就更接近目标语言的语法规则。

字节码生成

根据注释的抽象语法树生成字节码,也就是将一个数据结构转化为另外一个数据结构。就像将所有的中文词语翻译成英文单词后按照英文语法组装文英文语句。代码生成器的结果就是生成符合Java虚拟机规范的字节码。

ab756311d11e7beeaff8b42e898660c4.png
字节码生成
javac编译器调用com.sun.tools.javac.jvm.Gen类遍历这棵语法树将java方法中的代码块转换成符合JVM语法的命令形式的二进制数据。按照JVM的文件组织格式将字节码输出到以class为扩展名的文件中,也就是生成最终的java字节码。

总结

从以上过程的描述我们可以知道编译就是将一种语言通过分析分解,再按照一定的方式先形成一个简单的框架(将Java源文件的字节流转化为对应的token流)然后在通过详细的分析按照一定的规定在这个框架里添加东西使这个token流形成更加结构化的语法树(就是将前面生成的token流中的一个个单词组装成一句话),但是这棵树离我们的目标Java字节码还有点差距,所以再进行语义分析使那棵粗糙的树更加完整完善(给类添加默认的构造函数,检查变量在使用前有没有初始化,检查操作变量类型是否匹配)。

以上我们简单概述了下Java编译器的编译过程,由于Kotlin和Java的编译过程及其相似,所以这篇文章对于我们理解Kotlin编译器和Kotlin源码非常重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值