首页 > 编程语言 >Javac编译器

Javac编译器

时间:2022-11-21 23:33:38浏览次数:40  
标签:符号表 Javac 检查 语法 编译 编译器 注解

Javac编译器

Java技术下的编译期在不同的语境下会有不同的编译器实现产品:

  • 1、前端编译器:jdk的javac、Eclipse JDT中的增量式编译器
  • 2、即时编译器:hotspot虚拟机中的c1、c2编译器,graal编译器。
  • 3、提前编译器:jdk的jaotc、gcj。

这里讨论javac编译器。
Javac编译过程大致可以分为1个准备过程和3个处理过程:

  • 1、准备过程:初始化插入式注解处理器。
  • 2、解析与填充符号表过程:
    • 词法、语法分析。将源代码的字符流转变为标记集合,构造出抽象语法树,
    • 填充符号表。产生符号地址和符号信息。
  • 3、插入式注解处理器的注解处理
  • 4、分析与字节码生成过程,包括:
    • 标注检查。对语法的静态信息进行检查。  
    • 数据流及控制流分析。对程序动态运行过程进行检查。  
    • 解语法糖。将简化代码编写的语法糖还原为原有的形式。  
    • 字节码生成。将前面各个步骤所生成的信息转化成字节码。  

上面的处理过程中,执行插入式注解时又可能会产生新的符号,如果有新的符号产生,就必须转回到之前的解析、填充符号表的过程中重新处理这些新符号。

 

一、解析与填充符号表

解析过程包括了经典程序编译原理中的词法分析和语法分析俩个步骤

1、词法、语法分析

词法分析是将源代码的字符流转变为标记集合的过程,单个字符串是程序编写的最小元素,但标记才是编译时最小元素,关键字、变量名、字面量、运算符都可以作为标记。
语法分析是根据标记序列构造抽象语法树的过程,抽象语法树是一种用来描述程序代码语法结构的树形表示方式,抽象语法树的每一个节点都代表着程序代码中一个语法结构,例如包、类型、修饰符、接口、返回值等。
经过词法和语法分析生成语法树之后,编译器就不会再对源码字符进行操作了,后续的操作都建立在抽象语法树上。

2、填充符号表

符号表是由一组符号地址和符号信息构成的数据结构。符号表中所登记的信息在编译阶段都要被用到。譬如在语义分析过程中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的声明是否一致)和产生中间代码,在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的直接依据。

二、注解处理器

jdk5之后,Java语言提供了对注解的支持。注解的设计原本上是与普通的Java代码一样,都只会在程序运行期间发挥作用的,但在jdk6设计了一组插入式注解处理器的标准api,可以提前至编译期对代码中的特定注解进行处理,从而影响到前端编译器的工作过程。我们可以把插入式注解处理器看作是一组编译器的插件,当这些插件工作时,允许读取、修改、添加抽象语法树中的任意元素。如果这些插件在处理注解期间对语法树进行过修改,编译器将回到解析及填充符号表的过程重新处理,直到所有插入式注解处理器都没有再对语法树进行修改为止,每一次循环过程称为一个轮次。

三、语义分析与字节码生成

经过语法分析之后,编译器获得了抽象语法树。抽象语法树能够表示一个结构正确的源程序,但无法保证源程序的语义是符合逻辑的。
语义分析的主要任务则是对结构上正确的源程序进行上下文相关性的检查,譬如进行类型检查、控制流检查、数据流检查等

1、标注检查

标注检查步骤要检查的内容包括诸如变量使用前是否已被声明、变量与赋值之间的数据类型是否能够匹配,等等。在标注检查中,还会顺便进行一个成为常量折叠的代码优化。

2、数据及控制流分析

数据流分析和控制流分析是对程序上下文逻辑更进一步的验证,他可以检查诸如程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确的处理了等问题。
编译时的数据及控制流分析与类加载时数据及控制流分析的目的基本上可以看作是一致的,但是检验的范围会有所区别,有一些校验项只有在编译器或运行期才能进行。

3、解语法糖

语法糖指的是在计算机语言中添加的某种语法,这种语法对语言的编译结果和功能没有实际影响,但是却能更方便程序员使用该语言。通常来说语法糖能够减少代码量、增加程序的可读性,从而减少程序代码出错的机会。
Java中常见的语法糖包括泛型、变长参数、自动装箱拆箱等,Java虚拟机运行时并不直接支持这些语法,它们在编译阶段被还原回原始的基础语法结构。即解语法糖。

4、字节码生成

字节码生成是Javac编译过程的最后一个阶段。字节码生成阶段不仅仅是把前面各个步骤所生成的信息(语法树、符号表)转化成字节码指令写到磁盘中,编译器还进行了少了的代码添加和转换工作。例如实例构造器init方法和类构造器clinit方法,字符串的加操作使用stringbuilder或者stringbuffer替换等。

 

参考:

《深入理解Java虚拟机》周志明

转自:https://www.cnblogs.com/ldsggv/p/15789845.html

标签:符号表,Javac,检查,语法,编译,编译器,注解
From: https://www.cnblogs.com/fulaien/p/16913819.html

相关文章

  • go环境以及编译器安装
    go安装1.win10安装GO去Go官网下载,安装包验证安装cmd输入goversion,能出现版本号即可2.Goland安装Goland官网下载,下载好后直接安装即可3.创建go项目选择第一......
  • JavaCV音视频开发宝典:vb8和vp9编码的webm格式视频文件转成mp4文件
    本文转载自:https://blog.csdn.net/eguid_1/article/details/125251492《JavaCV音视频开发宝典》专栏目录导航《JavaCV音视频开发宝典》专栏介绍和目录​前言mp4不用......
  • 关于scanf函数不能在某些vs编译器中用的问题
    scanf在vs2022中是一个不安全的函数,vs自定义scanf_s是一个安全的函数,但是这在转给其他编译器可能不适用我们可以在开头加上一个#define_CRT_SECURE_NO_WARNINGS1可以解......
  • javac java file path
    1.packagemustcorrespondtofilepathpackageiscom.challengerpathmustbecom/challenger/ 2.javacuse-dtooutputclassesintofilepathautomaticlyja......
  • Qt 在Mac上无法识别编译器
    由于Mac系统更新,导致我之前的Xcode不能用了,然后我就把Xcode卸载了,结果悲剧了,Qt无法使用了,提示无法识别Apple的clang编译器。使用Qt前,必须先安装Xcode!!!!关闭QtCreator,在终......
  • 使用 Roslyn 编译器服务
    .NETCore和.NET4.6中的C#6/7中的编译器Roslyn一个重要的特性就是"CompilerasaService",简单的讲,就是就是将编译器开放为一种可在代码中调用的服......
  • SpringBoot 01: JavaConfig + @ImportResource + @PropertyResource
    springboot的前置知识:通过注解创建对象和读取配置文件1.JavaConfig设计思想使用java类作为xml配置文件的替代,是配置spring容器的纯java的方式可以创建java对象并把......
  • AI 模型编译器 MegCC 开源,解决推理引擎体积问题
    目前社区已经有多个移动端深度学习推理框架,如:NCNN、MNN...这些推理引擎都给社区的用户带来了在移动端上部署深度学习非常多的便利,但是他们也都有一个共性问题:随着不断地迭......
  • [Java反序列化]JavaCC链学习(8u71前)
    文章目录​​写在前面​​​​前置​​​​Transformer​​​​TransformedMap​​​​ChainedTransformer​​​​InvokerTransformer​​​​ConstantTransformer​​​​......
  • java 编译器
    1.javac介绍2. javac文件系统3. 词法分析4.语法分析之认识树节点5.语法分析之建立抽象语法树6.符号表的组织7. 填充符号表8. 插入式注解的实现9.语......