java编译原理

java编译原理4.Java编译原理1.javac是什么?(1)javac是一种编译器,能够将一种语言规范转换成另一种用语言规范,通常编译器是将便于人们理解的语言规范成机器容易理解的语言规范。(2)javac的任务就是将java源代码语言转换成jvm能够识别的语言,然后jvm将jvm语言再转化成当前机器能够识别的语言(这样使得对开发者屏蔽与机器相关的细节,并且使得语言的执行与平台无关)2.javac编译器的基本结…

大家好,又见面了,我是你们的朋友全栈君。

4.Java编译原理
java编译原理


1.javac是什么?
(1)javac是一种编译器,能够将一种语言规范转换成另一种用语言规范,通常编译器是将便于人们理解的语言规范成机器容易理解的语言规范。
(2)javac的任务就是将java源代码语言转换成jvm能够识别的语言,然后jvm将jvm语言再转化成当前机器能够识别的语言(这样使得对开发者屏蔽与机器相关的细节,并且使得语言的执行与平台无关)
2.javac编译器的基本结构
(1)步骤:
<1>读取源码,进行词法分析。也就是找出源码字节中的关键字,识别出合法的关键字,最后得出一些规范化的Token(中文意思是“标记“、”象征”等)流。
<2>对Token流进行语法分析,检查关键词的组合是否符合语法,最后得到抽象的语法树(语法树是吧语言的主要此法用一个结构化的形式组合在一起)
<3>进行语法分析,把难懂的,复杂的语法转化成更加简单的的语法(对计算机来说),最后得到一个注解过后的抽象语法树
<4>通过字节码生成器将经过注解的抽象语法树生成字节码
(2)Javac的四大模块:词法分析器、语法分析器、语义分析器和代码生成器
3.javac工作原理分析:(以openjdk源码为例)
(1)词法分析器:
其分析结果就是将这个类中的所有关键字匹配到Token类中的任何一项,最终得到Token流
<1>javac是如何分辨出一个个的Token?
javac进行词法分析时会根据java语言规范来控制什么顺序,在什么地方应该出现什么Token(如对package的读取,package语法规范上应该是第一个token,那么在构造javacParser的时候将读取这第一个token,然后往下就是读取IDENTIFIER即是用户定义的名称,在读取类名时如果遇到Token.Dot也就是‘.’将继续往下读,直到读得完成类名即遇到Token.SEMI(“;”)为止)。也就是说,读取每一个Token是由javacParser规定的而Token流的顺序是符合java语言规范的
<2>如何得知当前读到的Token是Token中的那一项,package就是Token.PACKAGE?
如何确定字符组合是一个Token的规则实在Scanner的nextToken方法中确定的,每调用该方法一次就会构造一个Token,并且这些Token必然是Token中的任一个项。java中锁由的字符集合都能找到Token中对应的项,Keywords类负责把每个字符集合对应到Token集合中,每一个字符集合都有一个Name对象,而Keywords会先把Token.name转化成Name对象,然后建立token和name的对应关系并保存在key数组中,而其他字符集将对应到Token.Identifier(用户定义的标识?)中。(也就是关键字会有对应表,指定关键字的字符集会对应到对应的Token中,而没找到的将当作用户自定义的Identifier)
(2)语法分析器
语法分析器就是将Token流组装成更加结构化的语法树,也就是将一个个的单词组装成语法树
<1>每个语法树上的语法节点都是JCTree的实例,语法树的一些规则如下:
[1]每个节点都会实现一个xxtree接口,该接口继承自com.sun.source.tree.Tree。如IfTree语法节点表示一个if类型表达式
[2]每个节点都是com.sun.tools.javac.tree.JCTree的子类并实现[1]中提及的接口,这个类的类名类似于JCxxx类,
[3]所有的JCxxx类都作为一个静态内部类定义在JCTree类中
<2>JCTree类中有如下三个重要的属性项
[1]Tree tag:每个节点都会用一个整形属性表示,别且每个节点的类型的数值都是前一个节点的类型数值加一(也就是这个属性代表节点的类型,并且类型的数值是上一个节点类型的数值加一?)
[2]pos:表示语法节点在源文件中的起始位置,文件的起始位置为0,-1的话表示不存在
[3]type:表示这个语法节点是什么类型,如int、float还是String
<3>按照顺序(与上述token流的顺序相关,也就是使用java语言规范控制顺序?)读取各个语法树(子树?)及其中的节点,最后把这些子树加到顶层语法节点之下,也就是以package作为pid并且持有JCClassDecl语法节点的集合JCCompilationUnit
(3)语义分析器
<1>通过语法分析器获得的语法树还是十分粗糙的,还需要给类添加默认的构造器,检查变量使用前是否已经初始化…等操作(检查是否有语法错误在这一步?),而这些操作将由语义分析器完成
<2>具体实现:
[1]主要由com.sun.tools.javac.comp.Enter类实现将java类中的符号(关于符号:转载的一句话——“在java代码中,一个类可能使用另外类或者接口的字段或者调用另外一个类的方法。在编译的时候,class文件中是通过叫做”符号引用”的方式来实现的”。)输入到符号表中:第一步将所有类中出现的符号输入到自身的符号表,并将类符号、类的参数类型符号(泛型参数类型)、超类符号,继承类型符号和继承的接口类型符号都存储到一个未处理列表中。第二步将这个未处理列表中的所有类都解析到各自的符号列表中。
[2]另外一种的Enter类还会为类 添加默认的构造函数
[3]处理注解
[4]检查语义的合法性和进行逻辑判断,如:变量的类型是否匹配,变量在使用前是否初始化,能够推导出泛型方法的参数类型,字符串常量的合并(常量折叠,会将一个字符串常量中的多个字符串合并成一个,如语句“String 是= “aa”+“bb”; “在语义转换后会变成” String s =”aabb”; “,所以写代码的时候多个常量字符串相加的代码其实会被优化成一个字符串而不会产生多个)等
[5]数据流分析:如检查变量使用前是否正确赋值(这里对比[4]主要是像String一样的对象引用是否赋值,估计上面是针对int等基础类型?),final变量是否不会被重复赋值,方法的返回值类型是否确定,检查异常是否已捕获或向上抛出,是否存在不会被执行的语句,消除无效语句(如永远为false的判断),解除语法糖(如foreach改为标准for循环,变量的自动转换如Integer等基本类型的封装类型与基本类型的赋值操作改为标准的操作内部类的转换(内部类名改为”外部类名$内部类名“),arsert语法的转换等等)
(4)代码生成器
<1>负责将结构化的语义树生成最终的java字节码
<2>生成java字节码主要经过两个步骤:
[1]将java
方法中的代码块
转成符合JVM语法的命令形式,jvm的所有操作都是基于栈的,所有操作都必须经过出栈和进栈来完成
[2]按照jvm的文件组织格式将字节码输出到以class文扩展名的文件中
4.设计模式解释之访问者模式
<1>其实上述的此法分析器、语法分析器,语义分析器,代码生成器等都会多次遍历语法树,并进行处理,这其实是访问这模式
<2>访问这模式的设计初衷是为了将稳定的数据结构和变化多端的对数据结构的操作解耦。
<3>转载资料:“
访问者模式是一种将算法与对象结构分离的
软件设计模式
这个模式的基本想法如下:首先我们拥有一个由许多
对象
构成的对象结构,这些对象的

都拥有一个accept
方法
用来接受访问者对象;访问者是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素作出不同的反应;在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中
回调
访问者的visit方法,从而使访问者得以处理对象结构的每一个元素。我们可以针对对象结构设计不同的实在的访问者类来完成不同的操作。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/142021.html原文链接:https://javaforall.net

(0)
上一篇 2022年5月9日 下午10:20
下一篇 2022年5月9日 下午10:20


相关推荐

  • Andon系统的工作流程介绍

    Andon系统的工作流程介绍Andon 系统本质是一款呼叫系统 应用场景以车间工厂为主 相比传统的呼叫 andon 系统具有记录事件时间点 事件呼叫原因 事件解决方法 升级呼叫等特点 记录的数据可以对设备 人员 工作流程可以进行分析 从而协同各单位更好的配合 提高整体的工作效率 下面给大家介绍下 andon 系统的基本工作流程 并把 andon 系统的特点详细介绍下 1 事件出现呼叫触发当车间出现异常事件人员通过工业按键或者虚拟按键

    2026年3月19日
    2
  • 1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程

    1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程//********写指令函数************voidLCD_write_command(uchardat){LCD_DB=dat;LCD_RS=0;//指令LCD_RW=0;//写入LCD_E=1;//允许LCD_E=0;delay_n40us(1);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。}//****************************…

    2022年7月16日
    16
  • 微型计算机原理与接口技术网课_微机原理接口技术答案

    微型计算机原理与接口技术网课_微机原理接口技术答案spContent=课程面向有志于从事计算机过程控制系统设计、或对计算机硬件结构感兴趣的学习者。总体目标是:具备输入/输出接口控制系统软硬件初步设计能力。课程以“家庭安全防盗系统”案例引导,主要介绍:计算机基础知识、微型机基本工作原理、80×86基本指令集、汇编程序设计、存储器接口设计、接口控制技术等。——课程团队课程概述在今天的信息化时代,计算机已成为了人类工作和生活中必不可少的一部分。计算机…

    2022年10月2日
    4
  • 块存储、文件存储、对象存储这三者和分布式文件存储系统的本质区别[通俗易懂]

    块存储、文件存储、对象存储这三者和分布式文件存储系统的本质区别[通俗易懂]https://blog.csdn.net/enweitech/article/details/51445087 块存储和文件存储是我们比较熟悉的两种主流的存储类型,而对象存储(Object-basedStorage)是一种新的网络存储架构,基于对象存储技术的设备就是对象存储设备(Object-basedStorageDevice)简称OSD。       首先,我们介绍这两种传统的存储类…

    2022年5月27日
    48
  • Restsharp_handler.post

    Restsharp_handler.post1.加入依赖RestSharpNewtonsoft.Json2.编写json、form-data请求代码usingMicrosoft.AspNetCore.Mvc;usingNewtonsoft.Json;usingNewtonsoft.Json.Linq;usingRestSharp;usingRestTemplate.model;namespaceRestTemplate.Controllers{[Route(“api/[controller]”)]

    2025年10月1日
    7
  • 我给大家整理了50个开源的Java项目

    我给大家整理了50个开源的Java项目大家好,我是孟哥。在学习交流群,其他小伙伴总是问我:孟哥,项目能不能搞得全一些。我想一次学个够。撸完50个项目,我住院了,但是好在项目总结完了。孟哥花了好几天,一次撸了50个项目给大家,非常的香,技术、知识非常的的全面。学起来贼带劲。源码开源,关注+评论(50个源码)+转发,私信我获取源码。系统的截图如下所示:源码开源,关注+评论(50个源码)+转发,私信我获取源码。…

    2022年7月7日
    22

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号