博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Abstract Syntax Tree 抽象语法树简介
阅读量:7040 次
发布时间:2019-06-28

本文共 2865 字,大约阅读时间需要 9 分钟。

追本溯源

在使用前端许多工具插件的时候,我们大多知道每个工具库、每个插件能做什么,不过很多同学其实并不清楚背后用到的技术,如webpack、rollup、UglifyJS、Lint等很多的工具和库的核心都是通过Abstract Syntax Tree 抽象语法树这个概念来实现对代码的检查、分析等操作的。通过了解抽象语法树这个概念,你也可以随手编写类似的工具,发现一个新的世界。

Abstract Syntax Tree 抽象语法树定义

理论的知识总是有些枯燥乏味,不过客官别急,一步一步来。

其实这些工具的原理都是通过JavaScript Parser把代码转化为一颗抽象语法树(AST),这颗树定义了代码的结构,通过操纵这颗树,我们可以精准的定位到声明语句、赋值语句、运算语句等等,实现对代码的分析、优化、变更等操作。

wikipedia定义:

In computer science, an abstract syntax tree (AST), or just syntax tree, is a tree representation of the abstract syntactic structure of source code written in a programming language.

翻译为:

在计算机科学中,抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。

Javascript的语法是为了给开发者更好的编程而设计的,但是不适合程序的理解。所以需要转化为AST来更适合程序分析,浏览器编译器一般会把源码转化为AST来进行进一步的分析等其他操作。

以下只介绍Javascript相关的抽象语法树

比如说有一段代码:

var a = 3;a + 5;复制代码

那么它的抽象语法树就类似:

JavaScript Parser

JavaScript Parser, 把js源码转化为抽象语法树的解析器。

浏览器会把js源码通过解析器转为抽象语法树,再进一步转化为字节码或直接生成机器码。

一般来说每个js引擎都会有自己的抽象语法树格式,Chrome的v8引擎,firefox的SpiderMonkey引擎等等,MDN提供了详细SpiderMonkey AST format的详细说明,算是业界的标准。

发展到现在可能不同的JavaScript Parser的AST格式会不同,或基于SpiderMonkey AST format,或重新设计自己的AST format,或基于SpiderMonkey AST format优化改进。通过优化抽象语法树,来使程序运行的更快,也是一种提高效率的方法。

常用的JavaScript Parser有:

EsprimaUglifyJS2TraceurAcornShift复制代码

在Esprima的官网有一个比较各个Parser解析速度的列表。 看下来Acorn是公认的最快的。

UglifyJS2的作者自己实现了一套js的抽象语法树,用到了继承,和现有的扁平的抽象语法树都有所不同,但作者也提供使用不同的抽象语法树来解析代码。

可以在线看到不同的parser解析js代码后得到的AST。

可以在线可视化的看到AST。

生成并使用抽象语法树 通过 esprima , 把一个名字为ast的空函数的源码生成一颗AST树:

var esprima = require('esprima');var code = 'function ast(){}';var ast = esprima.parse(code);复制代码

生成的抽象语法树长这样:

"type": "Program",  "body": [    {      "type": "FunctionDeclaration",      "id": {        "type": "Identifier",        "name": "ast",        "range": [          9,          12        ]      },      "params": [],      "body": {        "type": "BlockStatement",        "body": [],        "range": [          14,          16        ]      },      "generator": false,      "expression": false,      "range": [        0,        16      ]    }  ],  "sourceType": "module",  "range": [    0,    16  ]}复制代码

通过 estraverse 遍历并且更新抽象语法树,把函数名称改为ast_awsome:

...var estraverse = require('estraverse');estraverse.traverse(ast, {    enter: function (node) {        node.name += "_awsome";    }});复制代码

通过 escodegen 将AST重新生成为源码:

...var escodegen = require("escodegen");var regenerated_code = escodegen.parse(ast)复制代码

AST三板斧:

通过 esprima 把源码转化为AST 通过 estraverse 遍历并更新AST 通过 escodegen 将AST重新生成源码 抽象语法树的用途 浏览器最先就会把源码解析为抽象语法树,对浏览器而言AST的作用非常重要。

对开发者而言,AST的作用就是可以精准的定位到代码的任何地方,它就像是是你的手术刀,对代码进行一系列的操作。

常见的几种用途:

代码语法的检查、代码风格的检查、代码的格式化、代码的高亮、代码错误提示、代码自动补全等等 如JSLint、JSHint对代码错误或风格的检查,发现一些潜在的错误 IDE的错误提示、格式化、高亮、自动补全等等 代码混淆压缩 UglifyJS2等 优化变更代码,改变代码结构使达到想要的结构 代码打包工具webpack、rollup等等 CommonJS、AMD、CMD、UMD等代码规范之间的转化 CoffeeScript、TypeScript、JSX等转化为原生Javascript 总结 抽象语法树在前端领域中的应用广泛,通过抽象语法树大家可以实现很多功能,发现编写工具提高效率带来的乐趣。

参考文章

转载自 , 感谢原作者

你可能感兴趣的文章
做一个统计单词数目的Atom插件
查看>>
MD5Utils 简单计算MD5
查看>>
7月27日云栖精选夜读丨阿里巴巴机器翻译在跨境电商场景下的应用和实践
查看>>
你所不知道的setTimeout
查看>>
京信通信:数据智能为生产调试“增效瘦身”
查看>>
「实用教程」登录失败超过一定次数如何锁定帐号?
查看>>
java创建线程的三种方式
查看>>
ElasticSearch DSL Script使用案例分享
查看>>
你真的懂JavaScript计时器吗?
查看>>
CI框架如何在主目录application目录之外使用uploadify上传插件和bootstrap前端框架:...
查看>>
游乌镇
查看>>
使用Akka持久化——持久化与快照
查看>>
springboot之RMI的使用
查看>>
【NLP】揭秘马尔可夫模型神秘面纱系列文章(三)
查看>>
openstack 云服务上创建的虚拟机,主机名修改
查看>>
css3 贝塞尔曲线cubic-bezier(x1, y1, x2, y2)
查看>>
远程连接docker daemon,Docker Remote API
查看>>
C语言dll文件的说明以及生成、使用方法
查看>>
【Web API系列教程】1.3 — 实战:用ASP.NET Web API和Angular.js创建单页面应用程序(上)...
查看>>
java基础学习_面向对象(上)03_day08总结
查看>>