AST抽象语法树
栏目: JavaScript · 发布时间: 5年前
内容简介:1.概念
1.概念
抽象语法树(abstract syntax code,AST) 是源代码的 抽象语法结构的树状表示
。这里特指编程语言的源代码。
树上的每个节点都表示源代码中的一种结构,之所以说是抽象的,是因为 抽象语法树并不会表示出真实语法出现的每一个细节
,比如说,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现。
抽象语法树
并不依赖于源语言的语法,也就是说 语法分析
阶段所采用的上下文无文文法,因为在写文法时,经常会对文法进行等价的转换(消除左递归,回溯,二义性等),这样会给文法分析引入一些多余的成分,对后续阶段造成不利影响,甚至会使合个阶段变得混乱。因些,很多编译器经常要独立地构造语法分析树,为前端,后端建立一个清晰的接口。
抽象语法树在很多领域有广泛的应用,比如浏览器,智能编辑器,编译器等。
2.为何需要抽象语法树(抽象语法树作用)
编程语言太多,需要一个统一的结构让计算机识别。
作用:比如 typescript
的类型检查,IDE的语法高亮,代码检查,转译等等,都是需要先将代码转化成AST在进行后续的操作。
3.抽象语法树的生成过程(编译)
js为例:
词法分析(lexical analysis)
:进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer,简称Lexer),也叫扫描器(Scanner,例如 typescript
源码中的 scanner.ts
), 字符流
转换成对应的 Token流
。
tokenize:
tokenize就是按照一定的规则,例如token令牌(通常代表关键字,变量名,语法符号等),将代码分割为一个个的“串”,也就是语法单元)。涉及到词法解析的时候,常会用到tokennize。
语法分析(parse analysis)
: 是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成语法树,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确。源程序的结构由上下文无关文法描述。
例如:对
const a = 1; const b = a + 1; 复制代码
的编译过程。
图片地址: www.processon.com/view/link/5…
词法解析过程
:一边扫描源代码一边进行分类,例如扫描到第一行 const a = 1
,首先扫描到 const
,会生成一个语法单元说这是关键字 const
,接着扫描到 a
,这是变量名 a
,接着操作符 =
,接着常量 1
,等等,构成一个个token流。
语法分析过程
:将token流转化为一个有元素层级嵌套所组成的代表程序语法结构的树,这个树被叫做抽象语法树AST。
4.扩展测试:如何将 const a = 1
转化成 var a = 1
1. 新建一个 testAst
的工程
mkdir testAst复制代码
testAst
下新建 test.js
文件
touch test.js复制代码
-
testAst
下安装esprima
的npm模块,得到AST
npm i esprima --save复制代码
test.js
写入代码
const esprima = require('esprima'); let code = 'const a = 1'; const ast = esprima.parseScript(code); console.log(ast); 复制代码
2.运行 test.js
node test.js复制代码
3.得到生成的AST
也可通过 esprima.org/demo/parse.… ,输入代码,在线查看AST
-
testAst
下安装estraverse
的npm模块,遍历更新AST
npm i estraverse --save 复制代码
4.修改代码如下:
const esprima = require('esprima'); const estraverse = require('estraverse'); let code = 'const a = 1'; const ast = esprima.parseScript(code); estraverse.traverse(ast, { enter: function (node) { node.kind = "var"; } }); console.log(ast);复制代码
5.运行 test.js
,得到更新过后的AST
-
testAst
下安装escodegen
的npm模块,得到转译后的代码
npm i escodegen --save复制代码
6.修改代码如下:
const esprima = require('esprima'); const estraverse = require('estraverse'); const escodegen = require('escodegen'); let code = 'const a = 1'; const ast = esprima.parseScript(code); estraverse.traverse(ast, { enter: function (node) { node.kind = "var"; } }); const transformCode = escodegen.generate(ast); console.log(transformCode); 复制代码
7.运行 test.js
,得到转译后的代码
参考文档:
-
https://segmentfault.com/a/1190000012943992
- https://baike.baidu.com/item/语法分析/8853407?fr=aladdin
- baike.baidu.com/item/词法分析
- blog.csdn.net/feng98ren/a…
- https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md#toc-asts
以上所述就是小编给大家介绍的《AST抽象语法树》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Swift语法快速入门(一)之 Swift基础语法
- 在ES6中使用扩展语法有什么好处?它与rest语法有什么不同?
- Python 基础语法
- go语法
- JPQL 语言语法
- reStructuredText简明语法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。