温故知新(九一)什么是抽象语法树,有哪些用途
一、什么是 AST
抽象语法树(Abstract Syntax Tree)简称 AST,是源代码的抽象语法结构的树状表现形式。webpack、eslint 等很多工具库的核心都是通过抽象语法树这个概念来实现对代码的检查、分析等操作。
像我们常用的浏览器就是通过将 js 代码转化为抽象语法树来进行下一步的分析等其他操作。所以将 js 转化为抽象语法树更利于程序的分析。
如上图中变量声明语句,转换为 AST 之后就是右图中显示的样式
左图中对应的:
- var 是一个关键字
- AST 是一个定义者
- is tree 是一个字符串
- ; 是 Semicoion
首先一段代码转换成的抽象语法树是一个对象,该对象会有一个顶级的 type 属性 Program;第二个属性是 body 是一个数组。
body 数组中存放的每一项都是一个对象,里面包含了所有的对于该语句的描述信息
- type:描述该语句的类型 -->变量声明的语句
- kind:变量声明的关键字 -->var
- declarations:声明内容的数组,里面每一项也是一个对象
- type:描述该语句的类型
- id:描述变流量名称的对象
- type:定义
- name:变量的名字
- init:初始化变量值的对象
- type:类型
- value:值 “is value”不带引号
- row:""is tree"" 带引号
二、词法分析和语法分析
JavaScript 是解释型语言,一般通过 -->词法分析-->语法分析-->语法树,就可以开始解释执行了
2.1 词法分析
也叫扫描,是将字符串流转换为记号流(kokens),他会读取我们的代码然后按照一定的规则合成一个个的标识,比如说:const a = 2,这段代码通常会被分解成 const、a、=、2
[{ type: "Keyword", value: "const" },{ type: "Identifier", value: "a" },{ type: "Punctuator", value: "=" },{ type: "Numeric", value: "2" },
];
当词法分析源代码的时候,他会一个一个字符的读取代码,所以很形象的称之为扫描- scans。当他遇到空格、操作符,或者特殊符号的时候,他会认为一个话已经完成了。
2.2 语法分析
也成解析器,将词法分析出来的数组转换成树的形式,同时验证语法。语法如果有错的话,抛出语法错误。
{"type": "Program","body": [{"type": "VariableDeclaration","declarations": [{"type": "VariableDeclarator","id": {"type": "Identifier","name": "a"},"init": {"type": "Literal","value": 2,"raw": "2"}}],"kind": "const"}],"sourceType": "script"
}
三、AST 能做什么
语法检查、代码风格检查、格式化代码、语法高亮、错误提示、自动补全等
代码混淆压缩
优化变更代码,改变代码结构等等
3.1插件工具推荐
比如说,有个函数 function a(){} 我想把它变成 function b(){} ,在 webpack 中代码编译完成后 require('a') -->_ _webpack__require("*/**/a.js")
可以使用的插件工具
- esprima:code=>AST 代码转 AST
- estraverse:traverse AST 转换树
- escodegen:AST=>code
使用示例:
const esprima = require("esprima");
const estraverse = require("estraverse");
const code = `function getUser(){}`;// 生成AST
const ast = esprima.parseScript(code);
// 转换 AST,只会遍历 type 属性
// traverse 方法中有进入和离开两个钩子函数
estraverse.traverse(ast, {enter(node) {console.log("enter -> node.type", node.type);},leave(node) {console.log("leave -> node.type", node.type);},
});
/*
enter -> node.type Program
enter -> node.type FunctionDeclaration
enter -> node.type Identifier
leave -> node.type Identifier
enter -> node.type BlockStatement
leave -> node.type BlockStatement
leave -> node.type FunctionDeclaration
leave -> node.type Program
*/
3.2 修改函数的名字
语法解析
{"type": "Program","body": [{"type": "FunctionDeclaration","id": {"type": "Identifier","name": "getUser"},"params": [],"body": {"type": "BlockStatement","body": []},"generator": false,"expression": false,"async": false}],"sourceType": "script"
}
根据语法解析后,可以看到 type 为 Identifier 的时候就是该函数的名字,我们可以直接修改它便可实现一个更改函数名字的 AST 工具。
实现:
// 转换树
estraverse.traverse(ast, {// 进入离开修改都是可以的enter(node) {console.log("enter -> node.type", node.type);if (node.type === "Identifier") {node.name = "hello";}},leave(node) {console.log("leave -> node.type", node.type);},
});
// 生成新的代码
const result = escodegen.generate(ast);
console.log(result);
// function hello() {}
温故知新(九一)什么是抽象语法树,有哪些用途相关推荐
- 从零写一个编译器(九):语义分析之构造抽象语法树(AST)
项目的完整代码在 C2j-Compiler 前言 在上一篇完成了符号表的构建,下一步就是输出抽象语法树(Abstract Syntax Tree,AST) 抽象语法树(abstract syntax ...
- 抽象语法树 Abstract syntax tree
什么是抽象语法树? 在计算机科学中,抽象语法和抽象语法树其实是源代码的抽象语法结构的树状表现形式 在线编辑器 我们常用的浏览器就是通过将js代码转化为抽象语法树来进行下一步的分析等其他操作.所以将js ...
- js 数组 实现 完全树_JavaScript的工作原理:解析、抽象语法树(AST)+ 提升编译速度5个技巧
摘要: JS的"编译原理". 原文:JavaScript的工作原理:解析.抽象语法树(AST)+ 提升编译速度5个技巧 作者:前端小智 Fundebug经授权转载,版权归原作者所有 ...
- 用 C 语言开发一门编程语言 — 抽象语法树
目录 文章目录 目录 前文列表 抽象语法树的结构 使用递归来遍历树结构 实现求值计算 抽象语法树与行为树 前文列表 <用 C 语言开发一门编程语言 - 交互式解析器l> <用 C 语 ...
- 【编译原理】构建一个简单的解释器(Let’s Build A Simple Interpreter. Part 7.)(笔记)解释器 interpreter 解析器 parser 抽象语法树AST
[编译原理]让我们来构建一个简单的解释器(Let's Build A Simple Interpreter. Part 7.) 文章目录 python代码 插--后序遍历 C语言代码(有错误) C语言 ...
- JavaScript 是如何工作的:解析、抽象语法树(AST)+ 提升编译速度5个技巧
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 14 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...
- 超级详细AST抽象语法树Javascript
AST 抽象语法树 Program 程序(开始) interface Program <: Node {type: "Program";body: [ Statement ] ...
- php7 ast,PHP7新特性之抽象语法树(AST)带来的变化详解
本文分析了PHP7新特性之抽象语法树(AST)带来的变化.分享给大家供大家参考,具体如下: 这里大部分内容参照 AST 的 RFC 文档而成:https://wiki.php.net/rfc/abst ...
- 详解AST抽象语法树
浅谈 AST 先来看一下把一个简单的函数转换成AST之后的样子. // 简单函数 function square(n) {return n * n; }// 转换后的AST {type: " ...
最新文章
- C++知识点27——使用C++标准库(常用的泛型算法2)
- small2java_java类
- MVC和MVVM以及MVP的介绍
- 2006年软件500强
- 转:iOS-CoreLocation:无论你在哪里,我都要找到你!
- linux mysql 磁盘空间_磁盘空间满了之后MySQL会怎样
- SVN中Branch/tag的比较
- 机器学习初探(手写数字识别)HOG图片
- 项目计划与控制-若干题目
- CVPR 2022 论文和开源项目合集
- 时间复杂度与空间复杂度的研究
- Dism++ 一款传说中的系统工具,使用简介
- win10为单个网卡配置多个IP地址
- 三个一工程_C语言阶段第二阶段部分程序整理
- PDF编辑技巧 PDF怎么复制页面
- 重庆兴渝计算机培训中心,重庆兴渝职业中等专业学校招生录取分数线
- 繁简体(GB-Big5)字符串互转的JAVA方式实现
- php apache停止工作,apache http server已停止工作解决过程
- Spring AOP tx:advice
- stm32f103电子钟心得体会_STM32时钟小结