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格式文本,这两种形式的对比能够充分显示抽象语法树结构是为了表示空间或者时间或者逻辑关系上的层次。

ZhongShan

123456

"Tom"

123457

"John"

上面构造的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;

else

b = 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体中需要自动添加{}…使用抽象语法树的生成逻辑需要事无巨细的列出可能遇到的所有情况和处理方式。

php ast 抽象语法树,AST抽象语法树的基本思想相关推荐

  1. 什么是抽象语法树(AST)

    原创: 弗拉 码农翻身 作者: 弗拉@重度前端 https://segmentfault.com/a/1190000017992387 已经获得作者独家授权发布,老刘做了改编. 张大胖一上班,领导就扔 ...

  2. php7 ast,PHP7新特性之抽象语法树(AST)带来的变化详解

    本文分析了PHP7新特性之抽象语法树(AST)带来的变化.分享给大家供大家参考,具体如下: 这里大部分内容参照 AST 的 RFC 文档而成:https://wiki.php.net/rfc/abst ...

  3. 理解Babel是如何编译JS代码的及理解抽象语法树(AST)

    Babel是如何编译JS代码的及理解抽象语法树(AST) 1. Babel的作用是?    很多浏览器目前还不支持ES6的代码,但是我们可以通过Babel将ES6的代码转译成ES5代码,让所有的浏览器 ...

  4. java抽象语法树(ast),【你应该了解的】抽象语法树AST

    团队:skFeTeam  本文作者:李世伟 作为前端程序员,webpack,rollup,babel,eslint这些是不是经常用到?他们是打包工具,代码编译工具,语法检查工具.他们是如何实现的呢?本 ...

  5. 抽象语法树AST以及babel原理

    什么是AST? 借用一下百度百科的解释: 在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示.它以树 ...

  6. jsqlparser:基于抽象语法树(AST)遍历SQL语句的语法元素

    jsqlparser是一个java的SQL语句解析器,基于它可以实现很多之前无法完成的工作. <!-- maven 依赖库引用 --><dependency><group ...

  7. java抽象语法树_抽象语法树AST的全面解析(一)

    Javac编译概述 将.java源文件编译成.class文件,这一步大致可以分为3个过程: 1.把所有的源文件解析成语法树,输入到编译器的符号表: 2.注解处理器的注解处理过程: 3.分析语法树并生成 ...

  8. 【编译原理】构建一个简单的解释器(Let’s Build A Simple Interpreter. Part 7.)(笔记)解释器 interpreter 解析器 parser 抽象语法树AST

    [编译原理]让我们来构建一个简单的解释器(Let's Build A Simple Interpreter. Part 7.) 文章目录 python代码 插--后序遍历 C语言代码(有错误) C语言 ...

  9. 从零写一个编译器(九):语义分析之构造抽象语法树(AST)

    项目的完整代码在 C2j-Compiler 前言 在上一篇完成了符号表的构建,下一步就是输出抽象语法树(Abstract Syntax Tree,AST) 抽象语法树(abstract syntax ...

最新文章

  1. 原生JS修改html内容不影响绑定的点击事件 请认准insertAdjacentHTML、insertAdjacentText方法
  2. LeetCode-Majority Element II
  3. ITK:使用分水岭Watershed方法对图像进行分割
  4. Chromebook开发者模式Linux,Chromebook 的开发者模式和开发者版本有什么区别?
  5. Remove Nth Node From End of List
  6. .NET Core用数据库做配置中心加载Configuration
  7. php class使用方法,php的类使用方法问题
  8. python定时发送微信消息_Python3 itchat实现微信定时发送群消息的实例代码
  9. App后台开发运维和架构实践学习总结(6)——App客户端与后台交互方式总结
  10. GitHub 发布 2018 年开源项目趋势预测:跨平台、深度学习增长最快!
  11. 记2020年秋季学期的微波期末考试
  12. web消息推送-goesay
  13. 环境php5.2+mysql_php环境搭建问题(简单记录二------php5.2不加载mysql扩展)
  14. class文件反编译成java文件
  15. 台式计算机cpu允许温度,玩游戏cpu温度多少正常(台式电脑夏季CPU一般温度多少)...
  16. react从入门到入魔
  17. 算法笔记方法论4 枚举法 详细笔记
  18. Jenkins项目配置-maven项目-全面
  19. 企业如何规避劳务派遣中的法律风险?
  20. 可编辑div的一些方法总结(二)自定义空格和回车事件

热门文章

  1. 算法交易是指使用计算机,量化投资(下篇)——程序化交易 100分题库及答案...
  2. 解题报告 (九) 二分图最大匹配
  3. 高效程序员必备的六大命令行工具
  4. Tableau图表维度上卷下钻制作方法
  5. MATLAB Arnold 的图像置乱加密及解密
  6. fixed定位的元素及其子元素,滚动鼠标滑轮时无法滚动!
  7. 12306火车票订票项目源码
  8. 校招+实习 | 旷视研究院职位一览无余!
  9. 4k视频分辨率的码流_视频的分辨率、码率、帧率你都了解吗,如何设置才更好?...
  10. google谷歌最*的十大时刻漏了什么?