您好,欢迎来到九壹网。
搜索
您的当前位置:首页初识AST(抽象语法树)

初识AST(抽象语法树)

来源:九壹网

AST抽象语法树

AST是什么

代码中常见的字面量、标识符、表达式、语句、模块语法、class 语法等语句都有各自对应的 AST 节点类型。

AST常见节点类型

1. literal(字面量):本身语义代表一个值

  let name = 'iceman';       // iceman ---> StringLiteral 字符串字面量
  let age = 30;              // 30     ---> NumberLiteral 数字字面量
  const isMan = true;        // true   ---> BooleanLiteral 布林字面量
  const reg = /\d/;          // /\d/   ---> RegExpLiteral 正则字面量

2. Identifier(标识符):变量名、属性名、参数名等

  import { request } form 'framework';   // request              ---> Identifier
  let name = 'iceman';                   // name                 ---> Identifier
  const age = 30;                        // age                  ---> Identifier
  function talk(name) {                  // talk, name           ---> Identifier
      console.log(name);                 // console, log, name   ---> Identifier
  }
 const obj = {                          // obj                  ---> Identifier
      name: 'guang'                      // name                 ---> Identifier
  }

3. Statement(语句):最小代码执行单位

  return 'iceman';                    // ReturnStatement
  if (age > 35) {}                    // IfStatement
  throw new Error('error')            // ThrowStatement
  try {} catch(e) {}                  // TryStatement
  for (let i = 0; i < 5; i++) {}      // ForStatement

4. Declaration(声明):特殊的statement

  const listlen = 1;            // VariableDeclaration
  let listName = 'user';        // VariableDeclaration
  function getInfo(info) {      // FunctionDeclaration
      if(info.isRun){
          return info.name;
      }
      return '';
  }         
  class Car {                   // ClassDeclaration
      constructor() {}
      method() {}
  }

5. Expression(表达式):与statement的区别在于expression会有返回值

  [1,2,3];                          // ArrayExpression 数组表达式
  age = 1;                          // AssignmentExpression 赋值表达式
  1 + 2;                            // BinaryExpression二元表达式
  var obj = {                       // ObjectExpression对象表达式
      foo: 'foo',     
      bar: function() {}    
  }
  let getName = function (){}       // FunctionExpression函数表达式
  const getAge = (age) => {         // ArrowFunctionExpression箭头函数表达式
      return age;
  };             

6. Import(导入模块):属于一种特殊的声明语句,有三种类型 ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier

  import { environment } from 'framework';        // named import
  import { request as req } from 'framework';     // namespaced import
  import api from 'framework';                    // default import
  import * as APP from 'framework';               // namespaced imort

7. Export(导出模块):也属于一种特殊的声明,有三种类型 ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration

export * from './iceman';                        //all declaration
export default 'iceman';                         //default declaration
export const ice = 'iceman';                     //named declaration

AST有什么用

代码编译(这里我的理解是各种loader)

  • Babel,将ES6 JavaScript转化为ES5 JavaScript
  • TypeScript,将TS转化为JS
  • Sass,将Sass转化为css

代码加工(这里我的理解是各种plugin)

  • Prettier:代码美化
  • ESLint:修复语法错误
  • uglifyJS:代码压缩,混淆
  • @vue/compiler-dom:将vue文件代码拆分成template、script、style代码片段

代码分析

  • ESLint:代码语法检查
  • Webpack:代码模块打包分析

上面举的例子基本都是基于AST的代码处理工具,有的我用过,有的没用过,但是大致工作流程基本是下面四个阶段:

对于代码编译和加工来说,需要改变源代码,所以需要进行完整个过程,但是代码分析的话,并不涉及修改源代码,所以进行Parsing和Traversing两个步骤就行。

AST如何生成

主要分为两个步骤:

  • 词法分析:将整个代码字符串分割成最小语法单元数组。
  • 语法分析:在分词基础上建立分析分析语法单元之间的关系。

词法分析

将源代码,生成一系列词法单元(tokens),比如数字,标点,运算符等。

语法分析

将token按照不同的语法结构如声明语句、赋值表达式等转化成有语法含义的抽象语法树结构。

也就是说源代码 --> 词法单元 --> 抽象语法树,分别经过词法分析和语法分析两个过程。

小结

简单认识了一下什么是AST以及一些应用场景,主要是一些学习记录。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务