Javac编译原理

一、解释型与编译型语言

1)解释型语言:在运行时使用解释器将源程序代码翻译成机器语言并执行,如JavaScript、Python等,解释型语言不需要事先编译,所以只要平台提供了相应的解释器就可以执行该语言代码,方便移植,但是效率相对来说比较低;

2)编译型语言:在程序执行前,需要一个编译过程,使用专门的编译器将程序源代码编译成目标机器码,在执行时直接使用编译好的目标机器码,如C/C++、Objective-C等,编译型语言执行时不需要再次编译,因此效率高,但是编译好的机器码与特定平台相关,无法移植;

3)介于两者之间的语言:编译时将源代码编译成中间代码(前端编译),运行时加载中间代码再次编译成目标机器码(后端编译)然后执行,如Java、C#等,中间代码具有平台无关性,因此编译好的中间代码可以跨平台运行,中间代码执行性时还是需要再次编译的,效率相对编译型语言来说会更低,但是比解释型语言又更高。

编译过程如下图所示,其中绿色模块根据不同语言选择性实现:在这里插入图片描述
二、Javac编译流程

Javac是一种Java前端编译器,它将符合Java语言规范的Java源码(.java文件)转化成符合JVM语言规范的Java字节码(.class文件),在执行时JVM会先将字节码转化成相应平台的机器码,即后端编译,然后执行。

编译流程
123456
如图所示,编译流程可以分四个步骤:

1)词法分析:读取Java源代码,逐个字符读取,分出一个个单词和符号,根据Token中定义的符合Java规范的关键词形成Token序列,比如package对应Token的类型为Token.PACKAGE,else对应Token的类型为Token.ELSE,自定义变量名称对应的Token的类型为Token.IDENTIFIER,示例:

package learn.jee.demo;
public class HelloWorld {
	public static void main(String[] args) {
		System.out.println("Hello world!");
	}
}

这段代码对应的Token流为:
在这里插入图片描述

2)语法分析:将Token流组成更加结构化的语法树,一个或多个Token对应语法树上的一个节点,每个节点都有对应的类型。比如下面示例中,public class Sample 形成的Token流为Token.PUBLIC、Token.CLASS、Token.IDENTIFIER,这三个Token对应语法树上的一个JCClassDecl节点,此节点包含了Token.PUBLIC对应的JCModifiers,Token.IDENTIFIER对应的Name,分别表示这个类的修饰符,类名。这个节点下又有JCVariableDecl、JCMethodDecl等节点,对应类中成员变量、方法等。一个package对应一棵语法树,这个package中所有import以及所有类都是顶层节点的分支,package包名也作为这课树的pid存在于树中。因为构成语法树要清晰的分析出每个Token是修饰符、关键字、类名还是变量等,所以这个过程要检查Token流是否符合Java规范,一旦出错便停止编译并报错。

package learn.jee.demo;
import java.util.Map;
public class Sample {
	private int value;
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	public int add(int n) {
		return value + n;
	}
}

这段代码对应的语法树为:
在这里插入图片描述

3)语义分析:语法分析生成的这棵语法树由Token流直接转化而来,与JVM字节码对应的语法规则还有一定差距,语义分析的目的就是将这棵语法树更加完善化,使得后续生成字节码更加方便。这过程包括:给类添加默认构造函数、检查变量使用前是否已经初始化、检查变量类型是否匹配、去掉永假代码、检查所有异常是否已捕获、处理注解、检查所有代码是否都会被执行、去掉语法糖(例如foreach转化为for循环,assert转化为if条件判断)等等。最终会形成一棵更加细致完善,更加接近JVM字节码语法规则的注解语法树。

4)代码生成:将结构化的注解语法树转化成符合JVM规范的字节码,并写入.class文件,文件结构如下图所示:
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值