字节码的编译原理

1.编译原理

    java编译器在将java源码编译为一个有效的字节码文件,主要会经历4个步骤:词法解析à语法解析à语义解析à生成字节码


2.词法解析步骤

2.1词法解析过程

     词法解析是javac编译器执行字节码编译的第一步。主要任务就是将java源码中的关键字和标示符等内容转换为符合java语法规范的Token序列,然后按照指定的顺序规则进行匹配校验,以便为后续的语法解析步骤做准备。


2.2 Token序列

Token无非就是一组对应源码字符集合的单词序列。简单来说,Token其实就一个枚举类型,其内部定义了许多符合java语法规范并与源码字符集合相对应的枚举常量。


2.3源码字符集合与Token之间的对应关系

问题一:源码字符集合究竟是如何转换成Token的?

    答:当词法解析器需要将源码字符集合转换为Token时,就会通过Names类去调用Name类的fromChars()方法获取一个Name对象,然后在调用Keywords类的key()方法时传入这个Name对象就可以成功获取出对应Token,这样一来词法解析器即可成功地将源码字符集合转换为Token.

 

     问题二:源码字符集合转成Token后,词法解析器是采用什么方式保存源码字符集合与Token之间的对应关系?

     答:词法解析器在将源码字符转换为Token之前,会先将每一个字符集合都转换为一个对应的Name对象,也就是说,每一个源码字符集合其实就是一个Name对象,然后再由com.sun.tools.javac.parser.Keywords负责实际的Token转换任务。Keywords类会将Token中所有枚举常量全部转换为Name对象,然后将其存储在Name对象的内部类Table中,这样一来源码字符集合与Token之间对应关系就成功构成建起来了。


2.4词法解析例子——package关键字


3. 语法解析步骤

1)        语法解析指的就是将匹配后的Token序列整合为一颗结构化的抽象语法树。也就是说,词法解析后的Token序列其实还并不完善,因为这些Token所代表的只是一个对应的单个源码字符集合,还并没有按照指定的语法规则将其相关的一组或者一段Token整合起来。

2)        语法解析的主要任务恰恰就是将零散的Token按照指定的Java语法规范整合起来形成一个有机的整体,比如:一个try语句后面肯定会接上一个catch或者finally子句,这就是语法解析步骤的任务。

3)        JCTree类实际上与语法树中的每一个语节点都保持着密不可分的关系,因为语法树中的每一个语法节点实际上都直接或者间接地继承了JCTree类,并且这些语法节点对象都以静态内部类的形式定义在该类中。

4.语义解析步骤

1)        为没有构造方法的类型添加缺省的无参构造方法;

2)        检查任何类型的变量在使用前是否都已经经历过初始化;

3)        检查变量类型是否与值匹配;

4)        检查STRING类型的常量进行合并处理[OW1] 

5)        检查代码中所有操作语句是否可达;

6)        异常检查;

7)        解除Java语法糖。


 [OW1]

(1).编译器在执行语义解析时,会检查String变量中是否包含多个常量信息并通过符号“+”组合在一起,如果确实存在,语义解析器则会将其合并为一个字符串,这就是常量折叠操作

(2).使用Unicode编码格式的char类型可以用于存储世界上所有的文字信息,但类型的二进制位数只有16bit,也就是说,char类型的变量只能够存储单个字符。

(3).String类型就是Java语法层面定义的一种专门用于存储字符串信息的数据结构,其底层实现无非就是替大家封装过程而已。

5.生成字节码

所谓编译字节码,无非就是将符合Java语法规范的java代码转换为符合JVM规范的字节码文件。

在R语言中,字节码编译是通过R的解释器和编译器的协作来实现的。下面是R语言字节码编译的简要原理: 1. 解释器:当你运行R代码时,解释器会逐行读取代码并执行。解释器会将代码翻译成一条条的指令,然后逐个执行这些指令。这种逐行解释执行的方式可以实现动态语言的灵活性和交互性。 2. 编译器:R语言还有一个即时编译器(Just-in-Time Compiler,JIT Compiler),它可以将一段代码(称为函数)编译成字节码形式,以提高执行效率。编译器会将函数的源代码分析并转换为字节码表示形式。 3. 字节码字节码是一种中间形式的代码,它比源代码更接近于机器指令。字节码是由一系列的指令(例如,操作数栈操作、变量存取等)组成的,每条指令都对应着一种特定的操作。 4. 解释执行和即时编译:当解释器遇到已经被编译的函数时,它会直接执行对应的字节码指令,而不需要逐行解释执行源代码。这样可以提高函数的执行效率。 5. 缓存和优化:为了提高性能,R语言的编译器通常会将编译后的字节码缓存起来,以便下次再次调用相同的函数时可以直接使用缓存的字节码。此外,编译器还会进行一些优化,例如代码内联、循环展开等,以进一步提高执行效率。 需要注意的是,R语言的字节码编译是在函数级别进行的,并不是将整个脚本都编译成字节码。只有在函数被调用时,才会将函数的代码编译成字节码。这样可以灵活地处理不同函数的执行需求。 希望这个简要的解释能够帮助你理解R语言字节码编译的原理。如果你有更多具体的问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值