美文网首页
不会学的AST

不会学的AST

作者: hellomyshadow | 来源:发表于2020-01-10 14:30 被阅读0次

小白总结的译文,出自《AST for JavaScript developers》

为什么要谈AST

如果你查看目前任何主流的项目中的 devDependencies,会发现这些年不计其数的插件诞生。我们归纳一下有:javascript转译、代码压缩、css预处理器、elint、pretiier 等。有很多js模块不会在生产环境用到,但是它们在开发过程中充当着重要的角色。所有的上述工具,不管怎样,都建立在了AST这个巨人的肩膀上。

AST与Devs.png

什么是AST

官方定义:It is a hierarchical program representation that presents source code structure according to the grammar of a programming language, each AST node corresponds to an item of a source code.

AST转化案例.png

这很简化,只是大体思想。实际上,真正AST每个节点会有更多的信息。从纯文本中,我们将得到树形结构的数据。每个条目和树中的节点一一对应。

如何生成AST

那怎么从纯文本中得到AST呢?我们知道当下的编译器都做了这件事情。

编译器生成AST.png

幸运的是,我们无需贯穿编译器的所有知识点,最后将高级语言转译为二进制代码。只需要关注词法分析和语法分析,这两步是从代码中生成AST的关键所在。

  • 词法分析
    也叫做扫描Scanner。它读取我们的代码,然后把它们按照预定的规则合并成一个个的标识tokens。同时,它会移除空白符、注释 等。最后,整个代码将被分割进一个tokens列表(或者说一维数组)。
词法分析.png

当词法分析源代码时,它会一个一个字母地读取代码,所以很形象地称之为扫描-scans;当它遇到空格,操作符,或者特殊符号时,会认为一个话已经完成了。

  • 语法分析
    即解析器。它会将词法分析出来的数组转化成树形的表达形式。同时验证语法,语法如果有错的话,抛出语法错误。
语法分析.png

当生成树时,解析器会删除一些没必要的标识tokens(比如不完整的括号),因此AST不是100%与源码匹配的,但已经能让我们知道如何处理了。说个题外话,解析器100%覆盖所有代码结构生成树叫做CST(具体语法树)

  • 生成AST结构
抽象语法树结构.png

玩转AST

astexplorer 是一个很棒的网站,可以在线玩转AST,其中包含了很多第三方AST库。除了JS,还有很多其他语言的AST库。

  • babylon
    babylon是一个很棒的第三方库,它被用在大名鼎鼎的babel中,一直支持最新的JS特性,不用担心以后JS又出新版导致代码大规模重构。
  • babel

Babel is not a ‘tool for having ES6 support’. Well, it is, but it is far not only what it is about.

经常把beble和支持es6/7/8联系起来,但它仅仅是一组插件中的一个。我们也可以使用它来压缩代码、react相关语法转译(如jsx)、flow插件 等。
babel是一个Javascript编译器。宏观来说,它分3个阶段运行代码:解析parsing --> 转译transforming --> 生成generation。我们可以给babel一些Javascript代码,它修改代码,然后生成新的代码返回。

babel是怎样修改代码的呢?没错!它创建了AST,遍历树,修改tokens,最后从AST中生成新的代码。

范例

babel的工作过程.png

babel使用babylon --> 首先解析代码成AST,然后遍历AST,再反转所有的变量名,最后生成代码!
正如我们看到的,第一步(解析)和第三步(生成)看起来非常常规,我们每次都会做这两步。所以,babel接管处理了它们。最后,我们最为关心的,那就是AST转译这一步了。

当我们开发babel-plugin时,只需要描述转化AST的节点visitors就可以了

babel-plugin.png

将它加入babel插件列表中,设置webpackbabel-loader配置 或者 .babelrc中的plugins即可。

  • JScodeshift
    比如你想要替换掉所有老掉牙的匿名函数,把它们变成Lambda表达式(箭头函数)。
匿名函数替换为箭头函数.png

这时候jscodeshift就登场了,jscodeshift是一个跑codemods的工具,codemods是一段描述AST要转化成什么样的代码,思想和babel的插件如出一辙。

some code.png

所以,如果你想创建自动把你的代码从旧的框架迁移到新的框架,这就是一种很nice的方式

比如 react 16prop-types 重构

reactupdate.png

有很多不同的codemodes已经创建了:
https://github.com/facebook/jscodeshift
https://github.com/reactjs/react-codemod

  • Prettier
格式化代码.png

Prettier 格式化我们的代码,调整长句,整理空格,括号等。所以它将代码作为输入,修改后的代码作为输出。听起来很熟悉对吧!

prettier工作过程.png

思路还是一样。首先,将代码生成AST。之后依然是处理AST,最后生成代码。但是,中间过程其实并不像它看起来那么简单。

相关文章

  • 不会学的AST

    小白总结的译文,出自《AST for JavaScript developers》 为什么要谈AST 如果你查看目...

  • Golang标准库——go(1)

    ast ast ast包声明用于表示Go包语法树的类型。 func FileExports FileExports...

  • 【转向JavaScript系列】AST in Modern Ja

    What is AST 什么是AST?AST是Abstract Syntax Tree(抽象语法树)的缩写。传说中...

  • AST与babel

    AST 什么是ast ast又称抽象语法树,以树形结构描述代码,一般是json对象。与ast相关的操作通常有三...

  • IDL Code Generator Design For Co

    前言 框架Overview IDL AST AST Struct

  • JS编译——AST

    JS编译——AST AST 抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Synt...

  • 2018-03-29

    js_Ast structure seems that it is a pure ast tree, but i ...

  • ast语法树变成render字符串

    ast语法树变成render字符串 ast语法树变成字符串generate(ast)=>html元素: hello...

  • AST

    什么是ast ast就是把一段代码,然后转换成一颗语法树。 ast 如何工作 1, 词法分析 2,句法分析 ast...

  • vue3原理

    AST AST:抽象语法树,Abstract Syntax Tree。TypeScript、babel、webpa...

网友评论

      本文标题:不会学的AST

      本文链接:https://www.haomeiwen.com/subject/owypactx.html