编译原理实战课
宫文学
北京原点代码 CEO
26066 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 55 讲
真实编译器解析篇 (19讲)
编译原理实战课
15
15
1.0x
00:00/00:00
登录|注册

10 | Java编译器(二):语法分析之后,还要做些什么?

Env
ScopeImpl类
visitVarDef()方法
CompileState枚举类型
课程小结
示例程序
注解的处理程序
与Scope有关的类
Scope
符号
Enter类
compile()方法
CompileStates类
compile()方法
注解的处理
符号表的建立
引用消解
语法分析
词法分析
缺省的构造函数
TypeEnter类
系统符号表
处理注解
建立符号表
com.sun.tools.javac.main.JavaCompiler
com.sun.tools.javac.comp包
课程中用到的类图的图表说明
JavaCompiler类
编译状态
生成IR
语义分析
语法分析
扩展知识
PROCESS阶段
ENTER阶段
整个编译过程
编译过程
Java编译器

该思维导图由 AI 生成,仅供参考

你好,我是宫文学。
上一讲,我带你了解了 Java 语言编译器的词法分析和语法分析功能,这两项工作是每个编译器都必须要完成的。那么,根据第 1 讲我对编译过程的介绍,接下来就应该是语义分析和生成 IR 了。对于 javac 编译器来说,生成 IR,也就是字节码以后,编译器就完成任务了。也就是说,javac 编译器基本上都是在实现一些前端的功能。
不过,由于 Java 的语法特性很丰富,所以即使只是前端,它的编译功能也不少。那么,除了引用消解和类型检查这两项基础工作之外,你是否知道注解是在什么时候处理的呢?泛型呢?还有各种语法糖呢?
所以,今天这一讲,我就带你把 Java 编译器的总体编译过程了解一遍。然后,我会把重点放在语义分析中的引用消解、符号表的建立和注解的处理上。当你学完以后,你就能真正理解以下这些问题了:
符号表是教科书上提到的一种数据结构,但它在 Java 编译器里是如何实现的?编译器如何建立符号表?
引用消解会涉及到作用域,那么作用域在 Java 编译器里又是怎么实现的?
在编译期是如何通过注解的方式生成新程序的?
为了方便你理解 Java 编译器内部的一些对象结构,我画了一些类图(如果你不习惯看类图的话,可以参考下面的图表说明,比如我用方框表示一个类,用小圆圈表示一个接口,几种线条分别代表继承关系、引用关系和接口实现)。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入剖析了Java编译器的语义分析阶段,重点讨论了建立符号表和处理注解两个方面。文章首先概述了整个编译过程,包括词法和语法分析、生成字节码以及8个语义分析工作阶段。然后详细介绍了Enter阶段,即建立符号表的过程,以及处理注解的重要性。通过代码示例和类图说明,帮助读者理解Java编译器内部的对象结构和编译处理的步骤。文章还探讨了建立符号表算法的两个阶段处理过程,解释了为什么需要两个阶段以及上下文相关情况的算法复杂性。此外,文章还介绍了系统符号表和处理注解的重要性,以及注解在编译期的解析和使用方法。总体而言,本文内容丰富,对Java编译器的语义分析阶段进行了深入剖析,适合对编译器内部原理感兴趣的读者阅读学习。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编译原理实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(4)

  • 最新
  • 精选
  • 宫文学Richard
    置顶
    上一讲的参考: 对于a>b*2+3, step1: a 移进a step2: a,b > * 移进>,再移进b。那现在能否对a>b做规约呢?不能,因为后面跟的是*,优先级更高。 step3: a,b,2 >,* + 所以继续移进*和2.那现在能不能对b*2做规约呢?可以的。因为后面跟的是+,优先级更低。 step4: a,b*2 > + 规约掉b*2 step5: a,b*2,3 >,+ 继续移进+和3。现在后面已经是$了,所以不需要再移进了,接下来就连续做规约。 step6: a,b*2+3 > 规约掉+操作,把操作数栈顶弹出两个值来,构建一棵加法子树。 step7 a>b*2+3 再把>操作规约掉。 注意,我可能一步会做两个移进,而你的步骤会比我多。但没关系,只要掌握算法规则就行了。
    2020-06-30
    6
  • wusiration
    我的理解是有四个作用域,一个ScopeTest类的作用域,一个foo函数内部的作用域,if语句a>0分支中的作用域以及if语句else分支中的作用域。

    作者回复: 我已经在下一讲发了参考解答,你可以对照一下:-)

    2020-06-29
    2
  • lion_fly
    老师,您好,HelloWorldProcessor中是通过直接写文件的方式来生成相应的编译后的目标类,想问下老师,如何去通过修改语法树的方式来修改目标的类呢?我个人这边看到的资料,都是基于JDK8的来实现的,因为JDK8中是可以直接访问jdk.compiler中的定义的语法树的节点的,但是现在的JDK15这些数据结构已经无法直接在JDK的外部来直接访问了

    作者回复: 一个方法,Hack进去,修改编译器,然后发布你自己的版本的JDK。因为Graal都是开源的嘛。这个方法的麻烦之处,是你的程序只能运行在你的版本的JDK上。 更常用的方法,是直接生成字节码,这样就不用改编译器了。不过,你需要熟悉一下字节码的原理,然后用字节码生成工具去生成。我前两天参加鸿蒙的会议,碰到一个哥们,就是用这个思路,生成.NET的字节码,实现了一个游戏编程平台。

    2021-05-19
    2
    1
  • lion_fly
    老师可以提供一下这个类HelloWorldProcessor.java的源代码吗?

    作者回复: 在Github上是有的。 https://github.com/RichardGong/CompilersInPractice/blob/master/javac/src/main/java/HelloWorldProcessor.java

    2021-03-03
    2
    1
收起评论
显示
设置
留言
4
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部