toFrankie / blog

种一棵树,最好的时间是十年前。其次,是现在。
21 stars 1 forks source link

初尝 AST #294

Open toFrankie opened 1 year ago

toFrankie commented 1 year ago

配图源自 Freepik

概念

在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。

之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于 if-condition-then 这样的条件跳转语句,可以使用带有三个分支的节点来表示。

初次见面

以 JavaScript 为例,通过 EsprimaAST Explorer 等平台,就可以跟 AST 初次见面,交个朋友。

x + y

以上最简单的表达式,可以表示为这样一棵树:

type: Program
-body
  -#1
    type: ExpressionStatement
    -expression
      type: BinaryExpression
      operator: +
        -left
          type: Identifier
          name: x
        -right
          type: Identifier
          name: y
sourceType: script

如果用 JSON 表示是这样的:

{
  "type": "Program",
  "body": [
    {
      "type": "ExpressionStatement",
      "expression": {
        "type": "BinaryExpression",
        "operator": "+",
        "left": {
          "type": "Identifier",
          "name": "x"
        },
        "right": {
          "type": "Identifier",
          "name": "y"
        }
      }
    }
  ],
  "sourceType": "script"
}

Esprima 编写更多的案例,可以发现每一层的结构都是相似的:

{
  "type": "FunctionDeclaration",
  "id": {...},
  "params": [...],
  "body": {...}
}
{
  "type": "Identifier",
  "name": "..."
}
{
  "type": "BinaryExpression",
  "operator": "...",
  "left": {...},
  "right": {...}
}

这些每层结构也称为节点(Node),一个 JavaScript 程序就是由成千上万的节点构成的。

AST 节点很多很多,不需要全部记住。

如果有需要,但又不记得的话,可以借助 EsprimaAST Explorer 去查看,后者还支持切换多种解析器,比如:

如果你想要查看所有节点,可以去对应官网查看,比如 @babel/parser (babylon) Spec 等。

前面提到可切换 AST 解析器,是因为每一种 AST 规范又有细微的差别,但基本上都遵循 ESTree Spec 的。被更多人广泛使用的应该是 Babel AST 吧,因此接下来学习也是基于它来展开。

未完待续...