java的编译原理_java学习编译原理

一个.java文件的"沉浮"之路

1:引言:

昨天的分享大概分为一下几个模块来讲解的:

2:分享初衷:

基于以上内容,希望能够找到一些技术。分享给大家,而这些技术必须具备如下特征:

可能实用价值不高,但是希望能够在未来很长一段时间对你而言都有帮助

可以很好的和目前的编码统一起来,不能由于新的技术加入,导致和目前的学习工作没有关系

3:分享内容大纲

基于刚才的内容,我大概在自己有限的学习数据库中整理了一下。我会在以下内容开始分享:

4:建议

大家也能看到我这里所有的内容都是加了一个字,所以我尽自己的最大能力把这个东西分享的好玩一点。并且也希望大家意识到,我和大家分享的内容只是我的理解,千万不能全信。

我希望如果你真的想和我一起增强自己的知识脉络,最好能做到以下几件事情:

存疑+坚持+广而告之+参与感

如果这些你都能做到,那么就和我一起并肩前行吧!😁

5:.java文件的沉浮之路

接下来进入到这次分享的主要内容,看看小J同学在执行过程中都经历了什么!😊

编写一个.java文件然后依次编译,执行。过程如下:

5-1:编写一个.java文件

format,png

编写一个.java文件

5-2:通过javac和java指令执行

这个运行过程就不赘述了,我们直接上图:

format,png

java跨平台原理

5-3:揭秘第一部分.java文件如何变为.class文件

编译器遵守什么规则,将.java文件编译为.class文件

5-3-1:编译规则:

format,png

编译过程

5-3-2:词法分析:

.java文件编译为.class文件时,先进行词法分析 如下图:

format,png

词法分析

总结:这里着重解析.java文件编写的第5行代码,可以将例子后的代码理解为java中的第5行代码。

在进行词法分析时,会将内容进过线性分析,变成一张符号表。符号表为上图中的右侧内容。右侧的表格内容由三部分构成:

由词法分析我们将整个.java文件中的内容变成了一张表。接下来:

5-3-2:语法分析:

词法分析变为一张符号表,继续语法分析

format,png

语法分析

总结:通过形成的符号表,会生成一颗语法二叉树。在这里有一个很有意思的东西,就是我们观察二叉树,发现符号作为了根节点,而且+号的节点在*号的节点之上。这里解析时倒叙解析。那么为什么*号会在+号节点之下,其实如果你要定义一个语言时,一定要告知这个语言一定是一个形式化的,这个形式化的方式可以通过BNF定义。在形式化的定义规则里,*号的优先级别高于+号。

5-3-3:java的bnf定义:

format,png

java的bnf定义

总结:大家可以根据上面的bnf扩展语法,我们发现java的bnf定义如果要声明一个类class_declaration被这样定义: 需要编写一个修饰符,修饰符的定义:modifier:=="public"|"private"...,这里我们可知定义类的时候必须时这些关键词,关键词已经给出来了。如果你写的class的修饰符不是modifier定义的词,那么编译时语法就会报错。依次类推。“class”是必须要写的,同理如果定义类是不写则编译语法报错。在到后面的identifier,也是有对应定义的值:identifier:=="a..z,$,_"

5-3-4:语义分析:

语义分析,注意计算机的语义分析一定要知道,计算机语言不能存在二意性。这个和自然语言不通。

format,png

语义分析

总结:在语义分析是会做类型检查,控制流检查,类型检查等等。我们回想之前的java程序,在进行*发运算时,由于rate时float类型,而60时一个int类型的字面值。此时会将60这个int类型转换为float,其实类型转换是在编译时发生的。回想我们编写程序时的基本数据类型的类型转换错误,是不是发生在编译阶段呢?

5-3-5:中间代码生成,优化以及生产对应的目标文件:

产生最后的目标文件

f7aa048d85af69dec6b700f9421cb282.png

中间代码生成,优化以及生产对应的目标文件

总结:经过语义分析的语法二叉树开始准备生产对应的中间代码。这里我们发现第一行代码:temp1=int_to_float(60),注意,这里的语法二叉树相当于只是在二叉树上给了一个标示,说明60需要做类型转换。而将60转换为float这个是在生成中间代码中得到实际体现的。第二行代码temp2=id3*temp1,id3是什么意思呢?如果你还记得符号表的组成部分,那么这个应该不能猜出来。它就是符号表中的唯一表示。id为3的符号表,id为3的符号表中的变量为rate,对应的值为3.1。然后继续操作,直到中间代码生成结束。

我们发现中间的代码有一些代码是不需要做的,这里做代码优化。将一部分不需要的代码省略。

最后生成目标的代码,这里因为截图不是java代码,所以最后显示的目标文件是一个汇编指令。movl id3 R2,意思就是将id3的值也就是rate中的值存储到寄存器R2中,MUL #60.0,R2,意思就是将60.0和R

2寄存器中的值进行相乘,将结果存放到R2寄存器。依次类推。movl R1,id1,意思将R1寄存器中的值存储到id1中,id1其实就是变量position,值为R1寄存器的值。

到此,我们的.class文件也就生成了。

5-4:揭秘第二部分.class文件如何被java指令开始解析执行的。

5-4-1:操作系统执行可执行程序,调度计算机

5-4-1-1:计算机结构:

704b8dd462c80f780beca1d126f637f0.png

中间代码生成,优化以及生产对应的目标文件

总结:

当然这里链接以及调度的方式如果深究还是挺复杂的,暂时我们不做讨论,简单点就是"连找发"三元素理论。如果你不是本专业的,其实目前来讲这个对于我们不太重要,后续老薛会稍微展开再聊聊。当然,也可以参考下面的博文:参考博文地址。

这里之所以采用IO总线的方式链接各个设备,原因是很方便我可以删除,增加设备,你如果使用辐射式链接,就要主机连接各个设备,每个设备都有一套自己的控制线路,很麻烦。我们可以不防将总线理解为一个链表,而辐射式理解为数组。并且总线很清晰能够规划出各个设备之间的关系,但是辐射的话,设备的相连关系会很复杂。

5-4-1-2:计算机结构遗留问题:

总结:计算机的产生是基于图灵计算模型,而根据数据和指令集存放位置的不同分为了:芬诺依曼结构,哈弗结构。有兴趣大家可以稍微展开看看,老薛后续会展开来聊这两个东西。

5-4-2:.class文件如何执行

注意:jvm的加载过程不是本次分享的内容,老薛后续会展开聊,我们这次主要聊的点是,为什么jvm虚拟机可以去执行.class文件,这个文件中到底有什么东西?

format,png

执行过程

总结:在整个执行过程中,我们发现一个程序编译为字节码文件之后,其实就是一大堆的二进制数据。这里字节码展示是通过16进制查看的。然后进过jvm加载,解析,在jvm中构建一个运行时结构,然后开始执行。我们接下来就编写程序,以及通过反汇编指令去深究一下.class文件中到底有哪些内容。

5-4-2-1:将我们之前编写的Demo.java编译之后进行读取:

注意:通过流的方式将Demo.class读取进来,且按照16进制显示数据如下

9fafbe6587d6688e076b2257120d4285.png

读取16进制内容

下图是16进制对应一览表

7a98a2e2526c33447fbd5117c01061f6.png

16进制对应一览表

总结:

也就也为者有48个常量,往后数48个字节,都代表的是常量值。这里注意,48要加上本身常量池的个数 也会占空间,也就以为着一共只有47个常量。

6: 再往后的u2,代表的是访问标志,该类的修饰符,以及是否可以使用比如多态,如果可以使用那么意 味着就可以使用invokespecial,这个是java字节码调用指令,代表可以调用私有实例方法,构造器以 及使用super调用父类的实例方法等。剩下的依次类推。

大小端资料参考

通过javap -c -v反汇编,查看内容:

以下内容中两个`中间的内容是老薛写的注释

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华中科技大学 编译原理 面向过程的C语言的编译器设计 功能包括:词法分析和语法分析、语义分析、中间代码生成的 源码 题目:c--语言编译器设计与实现(请为自己的编译器命名) 源语言定义:或采用教材中Decaf语言,或采用C语言(或C++语言或C#语言或JAVA语言)部分关键语法规则。源语言要求至少包含的语言成分如下: 数据类型至少包括char类型、int类型和float类型 基本运算至少包括算术运算、比较运算、自增自减运算和复合赋值运算 控制语句至少包括if语句和while语句 实验内容:完整可运行的自定义语言编译器 实验一:词法语法分析器的设计与实现:建议使用词法语法生成工具如:LEX/FLEX ,YACC/BISON等专业工具完成。 实验二:符号表的设计与属性计算:设计符号表数据结构和关键管理功能。动态展现符号表变化过程。无论语法分析使用工具还是自己设计,都必须对符号表进行设计和管理,属性计算可以语义子程序实现。 实验三:语义分析和中间代码生成:生成抽象语法树,进行语义分析,实现类型检查和控制语句目标地址计算,生成中间代码。中间代码的形式可以采用不同形式,但实验中要求定义自己的中间形式。 实验四:目标代码生成:在前三个实验的基础上实现目标代码生成。也可以使用工具如LLVM来生成目标代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值