AST

#工程化

AST

什么是AST

ASTAbstract Syntax Tree 的简称,是前端工程化绕不过的一个名词。它涉及到工程化诸多环节的应用,比如:

  1. 如何将 Typescript 转化为 Javascript (typescript)
  2. 如何将 SASS/LESS 转化为 CSS (sass/less)
  3. 如何将 ES6+ 转化为 ES5 (babel)
  4. 如何将 Javascript 代码进行格式化 (eslint/prettier)
  5. 如何识别 React 项目中的 JSX (babel)
  6. GraphQL、MDX、Vue SFC 等等

而在语言转换的过程中,实质上就是对其 AST 的操作,核心步骤就是 AST 三步走

  1. Code -> AST (Parse)
  2. AST -> AST (Transform)
  3. AST -> Code (Generate)

TS转换JS的过程:TS的Code 转成 TS的AST;TS的AST转成JS的AST;JS的AST转成JS的Code

img

以下是一段代码,及其对应的 AST(抽象的语法树)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Code
const a = 4

// AST
{
"type": "Program",
"start": 0,
"end": 11,
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 11,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 11,
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"name": "a"
},
"init": {
"type": "Literal",
"start": 10,
"end": 11,
"value": 4,
"raw": "4"
}
}
],
"kind": "const"
}
],
"sourceType": "module"
}

不同的语言拥有不同的解析器,比如 Javascript 的解析器和 CSS 的解析器就完全不同。(一般JS的解析器是babel,CSS的解析器是postCss)

对相同的语言,也存在诸多的解析器,也就会生成多种 AST,如 babelespree

AST Explorer (opens new window)中,列举了诸多语言的解析器(Parser),及转化器(Transformer)。

image-20220529211605976

image-20220529211636863

使用不同的解析器,就会解析出不同的AST

词法分析 (Lexical Analysis)

词法分析用以将代码转化为 Token 流,维护一个关于 Token 的数组

img

1
2
3
4
5
6
7
8
9
10
// Code
a = 3

// Token
[
{ type: { ... }, value: "a", start: 0, end: 1, loc: { ... } },
{ type: { ... }, value: "=", start: 2, end: 3, loc: { ... } },
{ type: { ... }, value: "3", start: 4, end: 5, loc: { ... } },
...
]

词法分析后的 Token 流也有诸多应用,如:

  1. 代码检查,如 eslint 判断是否以分号结尾,判断是否含有分号的 token
  2. 语法高亮,如 highlight/prism 使之代码高亮
  3. 模板语法,如 ejs 等模板也离不开

语法分析 (Syntactic Analysis)

语法分析将 Token 流转化为结构化的 AST,方便操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
"type": "Program",
"start": 0,
"end": 5,
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 5,
"expression": {
"type": "AssignmentExpression",
"start": 0,
"end": 5,
"operator": "=",
"left": {
"type": "Identifier",
"start": 0,
"end": 1,
"name": "a"
},
"right": {
"type": "Literal",
"start": 4,
"end": 5,
"value": 3,
"raw": "3"
}
}
}
],
"sourceType": "module"
}

AST的应用

html的AST解析器

可参考一个最简编译器的实现 the super tiny compiler

参考链接

AST是啥和它的应用


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!