AST(AbstractSyntaxTree)题目内容ASTAST定义、用法、原理ASTAST实例ASTAST应用AST定义AST(AbstractSyntaxTree)抽象语法树,简称AST,是源码吧据说它不仅适用于JavaScript,也适用于其他语言,如:Python、Rust等)语法结构的抽象表示。它以树的形式表示编程语言的语法结构,树上的每个节点代表源代码中的一个结构。文法【摘要】:指这里的文法,并不代表真正文法中出现的每一个细节。AST使用我们常见的词法分析器和语法分析器(它可以将JavaScript源代码转换成AST),比如下面例子中的esprima,当然还有其他的,比如:acorn、shift、traceur等。AST抽象语法树的用途非常广泛,比如:vscode、atom、sublime中的代码高亮、代码格式化、错误提示、代码自动补全;eslint,更漂亮的检查代码错误或样式;babel将ES6翻译成ES5..所以如果你想优化JavaScript的编译和运行速度,对AST的理解是必不可少的。AST原理编译过程JavaScript执行的过程首先是读取JavaScript文件中的字符流,然后通过词法分析器生成token,再通过语法分析器(Parser)生成AST树,最后转化为机器码供执行。varname="jackdan";第一步是读取上面的字符流'varname="jackdan"';第二步分词:将'varname="jackdan"'的整个代码串拆分成最小的语法Cell数组;如下:[{type:'Keyword',value:'var'},{type:'Identifier',value:'name'},{type:'Punctuator',value:'='},{type:'String',value:'"jackdan"'}]第三步语法分析:在分词的基础上建立并分析语法单元之间的关系;如下:-Programtype:"Program"-body:[-VariableDeclaration{type:"VariableDeclaration"-declarations:[-VariableDeclarator{type:"VariableDeclarator"-id:Identifier{type:"Identifier"name:"name"}-init:Literal{type:"Literal"value:"jackdan"raw:"jackdan"}}]kind:"var"}]下面重点讲原理中的词法分析和语法分析。接触过这两位的人应该都不会太陌生。Lexicalanalysis词法分析:也称为扫描器,简单地调用next()方法逐个读取字符,然后与定义的JavaScript关键字符进行比较,生成相应的Token。Token是不可分割的最小单位。例如:varname="jackdan";//先读v,再继续读a,最后读r组成var//var的三个字符在JavaScript中被识别为关键字,作为一个整体,语义化了不能再分解了,所以我们也把它看成一个Token。从上面的代码示例中不难得出。在词法分析器中,每个关键字都是一个Token,每个标识符都是一个Token,每个运算符都是一个Token,每个标点符号也是一个Token。除此之外,还会过滤掉程序中的注释和空白字符(换行符、空格、制表符等)。最后,我们看到整个代码被划分为一个标记列表(或一维数组)。[{type:'Keyword',value:'var'},{type:'Identifier',value:'name'},{type:'Punctuator',value:'='},{type:'String',value:'"jackdan"'}]句法分析句法分析是将词法分析的tokns列表转化为具有语法意义的抽象句法树结构。同时校验语法(高亮、自动补全等),语法错误则抛出语法错误。-程序类型:“程序”-主体:[-VariableDeclaration{type:“VariableDeclaration”-声明:[-VariableDeclarator{type:“VariableDeclarator”-id:Identifier{type:“Identifier”name:“name”}-init:Literal{type:"Literal"value:"jackdan"raw:"jackdan"}}]kind:"var"}]ASTinstance//sourcecodevarname="jackdan";//AST抽象语法树/****+------------+*|分配(=)|*+------------+*/\*/\*+----++---------+*|名称||“杰克丹”|*+----++--------+**///输出结构代码-Programtype:"Program"-body:[-VariableDeclaration{type:"VariableDeclaration"-declarations:[-VariableDeclarator{type:"VariableDeclarator"-id:Identifier{type:"Identifier"name:"name"}-init:Literal{type:"Literal"value:"jackdan"raw:"jackdan"}}]kind:"var"}]>varesprima=require('esprima');>varprogram='varname="jackdan"';>esprima.tokenize(program);[{type:'Keyword',value:'var'},{type:'Identifier',value:'name'},{type:'Punctuator',value:'='},{type:'String',value:'"jackdan"'}]>esprima.parse(程序);Script{type:'Program',body:[VariableDeclaration{type:'VariableDeclaration',declarations:[Array],kind:'var'}],sourceType:'script'}杰克丹的思考
