AST抽象语法树的基本思想
AST抽象语法树的基本思想
- 前言
- AST概述
- AST结构
- AST解析
- 转换
- 生成
前言
在阅读java ORM框架spring data jpa的源码时,发现Hibernate(spring data jpa依赖Hibernate核心代码)在底层使用了AST抽象语法树,将hql转换为sql,这激发了我研究AST的兴趣。
AST概述
AST(Abstract Syntax Tree)抽象语法树多用作编程语言的分析和转换,C语言编译器将c源码转换为汇编,java编译器将java代码转换为java字节码,还有一些比较高级的用法,比如同种语言代码的优化、不同种语言代码的相互转化等。
抽象语法树从术语定义上就能看出,本身是一种树状的数据结构,“1 + 2”使用抽象语法树可以表示为:
这样做的目的是,将原始语句分解成了单个的语法单元,同时保留了语法单元之间的层次结构,后续通过对语法单元的改造或者替换,重新按照某种规则遍历,即可完成原始语句到目标语句的转换。比如,以“1 + 2”为例,可以将“+”替换为add,1和2理解为add函数的参数,即可实现原始运算语句到函数调用的转换。
AST抽象语法树的使用,整体上可以分为三步:
- 解析:将原始语句解析为抽象语法树
- 转换:操作抽象语法树节点完成转换
- 生成:根据转换后的抽象语法树生成目标语句
其中,最重要的是需要理解抽象语法树的结构,这是解析和生成抽象语法树的基础。
AST结构
个人感觉,理解抽象语法树结构的最佳例子是xml格式文本,这两种形式的对比能够充分显示抽象语法树结构是为了表示空间或者时间或者逻辑关系上的层次。
<city><park>ZhongShan</park><people><id>123456</id><name>"Tom"</name><son><id>123457</id><name>"John"</name></son></people>
</city>
上面构造的xml是用来表示,有个城市中一个公园叫ZhongShan,这个城市住着一个人,他的id是123456,姓名叫Tom。Tom有一个儿子,id是123457,名叫John。这种嵌套的关系用AST表示,如图:
xml到AST图的转换,实际上是空间层次的对应关系。可能大家还是会对逻辑层次关系如果转换成AST有疑问,所以这里再以表达式“5-2*(3-1)+4”为例来进一步分析这种转换。
如图为“5-2*(3-1)+4”的抽象语法树,其实就是中缀表达式的树形表示。这里构造的基本逻辑是,越是排在后面的运算离根节点越近。括号中的表达式“3-1”最先被运算,因此位于最底层。而“+ 4”运算最后执行,所以这里的“+”位于根节点。表达式的AST图和xml的AST图不同之处在于,这里同层还存在顺序关系,左边的节点优先级要高于右边节点的优先级。
通过上述两个例子的演示,这里再介绍代码的抽象语法树似乎就容易理解多了。
while(b > 0)
{if(a < b)a = b-a;elseb = a-b;
}
return a;
在代码的构造抽象语法树之前,首先需要明白,这些语句之间存在执行上的顺序关系,也存在不同层级下的嵌套关系。比如上述代码,while循环语句块由大括号包裹,和return语句处于一个层级,但while语句块先会被执行。而while语句块中又包含了循环判断“b != 0”和if的判断语句块,这属于while下语句的嵌套。其次,语句结构也更加复杂,比如上例中的语句除了表达式、赋值语句之外,还有while、if和对应的判断条件,所以会拆分出更多的语法单元。
statement_list语法单元,用来表示子节点都是并列依次执行的语句。while子树中包含了while循环的条件判断和if的语句块,if语句块包含了if的条件判断和两个赋值语句。在编译器构造同样类型语法树时,一般会使用与具体语言无关的语法单元的命名,这样在后续转换的转换只是对节点采用不同的翻译模式而已,做到了和具体语言的解耦。
AST解析
使用AST对原始语句解析时,需要先进行词法分析。
词法分析会根据既定的语法单元表,将原始语句分割成一维数组语法单元列表(token表)。语法单元表根据场景不同,如上述三个例子,可以自行定义。一般而言,词法分析时会将连续的空格当做分割符,自动切分语法单元。
获得token表之后,再使用语法分析,将一维无结构的token表转化为树形结构。在语法分析时,也会验证语法的正确性。如果出现不符合语法的语句,就会抛出错误,编译报错一般就是这个阶段的产物。
转换
根据目的的不同,AST转换没有一套固定的标准,有时候只是对匹配节点简单的替换,有时候可能是对匹配子树结构的调整或者替换。一般这个过程包含遍历和转换两步。
抽象语法树可以使用一般树的遍历方法。如果忘记了,可以温习一下先序遍历、中序遍历和后序遍历。目前使用比较多的antlr中,使用了先序遍历和后序遍历。
生成
生成是AST解析的逆向工程,生成过程中也需要用到树的遍历。虽然有时候生成和转换可能糅合在一起同时进行,但是生成逻辑比单纯进行转换时要复杂。
在生成的遍历过程中,需要对所有不同类型语法单元的节点的所有情况定义不同的处理逻辑,而不同类型语法节点下子树的遍历顺序也有可能会不同。所以需要为所有情况进行枚举。
这种情况的感性认知,可以以上述例子中代码语法抽象树为例。在statement_list节点下,子树代表的语句块需要按顺序并列,所以在先遍历完while语句块子树之后,回到statement_list节点,再到return子树下,生成return语句需要另起一行。而while节点下需要先考虑条件语句,在不回车换行的基础上添加括号,完成while( b > 0 )语句的构造。同理while节点下while体中需要自动添加{}…使用抽象语法树的生成逻辑需要事无巨细的列出可能遇到的所有情况和处理方式。
AST抽象语法树的基本思想相关推荐
- php ast 抽象语法树,AST抽象语法树的基本思想
AST抽象语法树的基本思想 前言 AST概述 AST结构 AST解析 转换 生成 前言 在阅读java ORM框架spring data jpa的源码时,发现Hibernate(spring data ...
- AST(抽象语法树)实战入门:js逆向中滑块加密if语句转化
概述:AST 抽象语法树 实战 入门 案例 js逆向 js滑块 js加密 极验 瑞数 阿里滑块 5秒盾 引言: AST算得上是高端技能.如果把爬虫技能分为初中高三个阶段的话.常规的JS逆向找找参数, ...
- 应用ast抽象语法树修改js函数
原理:AST抽象语法树 目标:在每一个函数里面插入一个console.log()把函数传入的全部参数输出出来 关于:本文章是在基于我的个人理解且怕忘记知识所记录下来的给自己看并且分享自己的一个心得,文 ...
- JS实现AST抽象语法树问题
前端中的AST抽象语法树问题 四则运算 正则表达式 词法分析 语法分析 完整代码 github地址: https://github.com/feddiyao/Frontend-05-Template/ ...
- AST(抽象语法树)超详细
自己研究的东西会用到AST,就自己通过查阅资料,整理一下. 本文目录 第一部分:AST的作用 第二部分:AST的流程 第三部分: Eclipse AST的获取与访问 第一部分:AST的作用 首先来一个 ...
- ast抽象语法树_新抽象语法树(AST)给 PHP7 带来的变化
本文大部分内容参照 AST 的 RFC 文档而成:https://wiki.php.net/rfc/abstract_syntax_tree,为了易于理解从源文档中节选部分进行介绍. 我的官方群点击此 ...
- java AST 表达式_java 编译时注解-AST 抽象语法树简介
AST 语法入门 以前使用 Lombok 一直觉得是一个很棒的设计,可以同时兼顾注解的遍历和运行的性能. 运行时注解一直因为性能问题被人诟病. 自己尝试写过一些框架,但是耗费了比较多的精力,因为 AS ...
- python compiler.ast_ast --- 抽象语法树 — Python 3.7.9 文档
ast --- 抽象语法树¶ ast 模块帮助 Python 程序处理 Python 语法的抽象语法树.抽象语法或许会随着 Python 的更新发布而改变:该模块能够帮助理解当前语法在编程层面的样貌. ...
- 【转】抽象语法树简介(AST)
引用地址:http://blog.chinaunix.net/uid-26750235-id-3139100.html 抽象语法树简介 (一)简介 抽象语法树(abstract syntax code ...
最新文章
- 深入浅出依赖注入框架Dagger2
- UI开发模式-容器模式
- iphone 保存到沙盒中的图片的读取
- NIPS 2017论文解读 | 基于对比学习的Image Captioning
- 为什么非全站升级HTTPS不可?
- BD云20MB/s不限速,随时下架!
- Tomcat 配置详解/优化方案
- ec200t 拨号_移远EC20 R2.0 AT指令拨号流程
- Leetcode每日一题:83.remove-duplicates-from-sorted-list(删除排序链表中的重复元素)
- 数据库系统原理课程设计
- aio-pika的使用
- FAI自动部署debian
- 英文原文:6 Life Habits That Programming Could Teach You Today
- 扫盲教程:单片机IIC基础通信
- 企业微信公众号运营引流的三大法宝
- html实现选择头像,HTML5实现上传头像图片大小选择(简单实现)
- php加入语音播报功能_PHP实现语音播报功能
- 龙芯3a5000部署nacos 1.4低版本方法
- 鲍鱼数据案例(岭回归 、LASSO回归)
- 365天深度学习训练营-第P7周:咖啡豆识别