Java编译器的内部结构
我从事Java编译器的内部结构,java,javacompiler,Java,Javacompiler,我从事Java已有8年多了 上周,在我公司的一次小型会议上,我的一位同事问我,Java编译器到底是如何工作的?我没有回答 我试着解释,就像Java编译器一个接一个地获取语句,并将它们转换为字节码,而不是针对任何OS,而是针对JVM 没有人对这个答案感到满意,即使是我 现在主要的问题是java编译器到底是如何工作的。i、 e.编译Java文件时,编译器将完成多少步骤、阶段或阶段 Java的编译器体系结构是什么 如果在同一个.Java文件中有多个Java类,该怎么办。那么将编译多少类 如果有指向未编
Java
已有8年多了
上周,在我公司的一次小型会议上,我的一位同事问我,Java编译器
到底是如何工作的?我没有回答
我试着解释,就像Java编译器一个接一个地获取语句,并将它们转换为字节码,而不是针对任何OS
,而是针对JVM
没有人对这个答案感到满意,即使是我
现在主要的问题是java编译器到底是如何工作的。i、 e.编译Java
文件时,编译器将完成多少步骤、阶段或阶段
Java的编译器体系结构是什么
如果在同一个.Java文件中有多个Java类
,该怎么办。那么将编译多少类
如果有指向未编译Java类的导入呢?那么应该编译还是忽略未编译的类
我在谷歌上搜索了半天多,所有人都给出了和我给同事们一样的答案
但最后我找到了一些有用的教程
但本教程的内容也不太深入,我无法想象该教程
我仍然不满足,也不渴望从你那里学到更多
因此,如果有人比我和上面的博客更了解一些东西,那么我可以通过这些东西直观地了解Java编译器的内部架构,请向我解释。一些基本步骤:
解析:读取一组*.java源文件并映射生成的令牌
序列到AST(抽象语法树)-节点
输入:在符号表中输入定义的符号
流程注释:如果请求,可以在中找到流程注释
指定的编译单元
属性:语法树的属性。此步骤包括名称
分辨率、类型检查和恒定折叠
流:对上一步中的树执行数据流分析。
这包括检查分配和可达性
desugar:重写AST并翻译掉一些语法糖
生成:生成源文件或类文件
详情如下:
Lex-将源文件分解为单个单词或标记
解析-分析程序的短语结构
语义动作——构建一个对应于每个短语的抽象语法树
语义分析-确定每个短语的含义,将变量的使用与其定义联系起来,检查表达式的类型,请求翻译每个短语
框架布局-以机器相关的方式将变量、功能参数等放入激活记录(堆栈框架)中
翻译-生成中间表示树(IR树),表示法
这与任何特定的源语言或targetmachine体系结构无关
规范化-从表达式中提取副作用,并清理条件分支,以方便下一阶段
指令选择-将IR树节点分组为对应于目标机器指令操作的集群
控制流分析-将指令序列分析成控制流图,该图显示程序可能的所有可能的控制流
当它执行时跟随
数据流分析-通过程序变量收集有关信息流的信息;例如,活动性分析计算每个程序变量保存仍然需要的值(是活动的)的位置
寄存器分配-选择一个寄存器来保存程序使用的每个变量和临时值;变量不能同时存在
可以共享同一寄存器
代码排放-将每个机器指令中的临时名称替换为
机器寄存器
有一本好书:
Java中的现代编译器实现
您可能需要查看javac代码:
编译器有不同的步骤,但以下是最重要的步骤:
词汇分析
第一步是词汇分析。基本上,这个步骤从java代码中提取标记(关键字、运算符、分隔符、注释、变量名…)
语法分析(解析器)
第二步是语法分析。标记作为词法分析的输入,并组合成表达式和指令
优化和字节码转换
最后一个宏步骤是将上一个步骤转换为字节码。在这里,代码可以修改为与原始代码等效,但效率更高
注意:此过程不仅与java相关,而且对所有编译器都是通用的。也包括不生成中间字节代码而是生成机器代码的编译器(如C或C++编译器)
通常,有一些工具可以创建词法分析器和语法分析器,因为这些步骤在不同语言之间有许多通用部分
提供了一个开源的词法分析器
一个有用的语法分析器是
两种语言都是C和C++的,它们是最常用的语言来创建编译器(java和其他语言),但是也有类似的替代方案用于其他编程语言(在< <强> >另一种语言中创建编译器<强>,而不是<强> >另一种语言>。基本上,编写编译器所用的语言与编译器编译的语言无关。
JVM规范非常详细:…@Würgspaß是的,你绝对正确。但是你自己看看文档就可以了。它相当复杂,需要花很多时间去理解。现在一天的时间是我们没有的。所以我想这里有些人可能已经有了同样的问题,可能已经有了答案