成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

高級(jí)前端基礎(chǔ)-JavaScript抽象語法樹AST

verano / 756人閱讀

摘要:本文主要介紹解析生成的抽象語法樹節(jié)點(diǎn),的實(shí)現(xiàn)也是基于的。原文地址解析器是把源碼轉(zhuǎn)化為抽象語法樹的解析器。參考文獻(xiàn)前端進(jìn)階之抽象語法樹抽象語法樹

前言

Babel為當(dāng)前最流行的代碼JavaScript編譯器了,其使用的JavaScript解析器為babel-parser,最初是從Acorn 項(xiàng)目fork出來的。Acorn 非常快,易于使用,并且針對(duì)非標(biāo)準(zhǔn)特性(以及那些未來的標(biāo)準(zhǔn)特性) 設(shè)計(jì)了一個(gè)基于插件的架構(gòu)。本文主要介紹esprima解析生成的抽象語法樹節(jié)點(diǎn),esprima的實(shí)現(xiàn)也是基于Acorn的。

原文地址

解析器 Parser

JavaScript Parser 是把js源碼轉(zhuǎn)化為抽象語法樹(AST)的解析器。這個(gè)步驟分為兩個(gè)階段:詞法分析(Lexical Analysis) 和 語法分析(Syntactic Analysis)。

常用的JavaScript Parser:

esprima

uglifyJS2

traceur

acorn

espree

@babel/parser

詞法分析

詞法分析階段把字符串形式的代碼轉(zhuǎn)換為 令牌(tokens)流。你可以把令牌看作是一個(gè)扁平的語法片段數(shù)組。

n * n;

例如上面n*n的詞法分析得到結(jié)果如下:

[
  { type: { ... }, value: "n", start: 0, end: 1, loc: { ... } },
  { type: { ... }, value: "*", start: 2, end: 3, loc: { ... } },
  { type: { ... }, value: "n", start: 4, end: 5, loc: { ... } },
]

每一個(gè) type 有一組屬性來描述該令牌:

{
  type: {
    label: "name",
    keyword: undefined,
    beforeExpr: false,
    startsExpr: true,
    rightAssociative: false,
    isLoop: false,
    isAssign: false,
    prefix: false,
    postfix: false,
    binop: null,
    updateContext: null
  },
  ...
}

和 AST 節(jié)點(diǎn)一樣它們也有 start,end,loc 屬性。

語法分析

語法分析就是根據(jù)詞法分析的結(jié)果,也就是令牌tokens,將其轉(zhuǎn)換成AST。

function square(n) {
  return n * n;
}

如上面代碼,生成的AST結(jié)構(gòu)如下:

{
  type: "FunctionDeclaration",
  id: {
    type: "Identifier",
    name: "square"
  },
  params: [{
    type: "Identifier",
    name: "n"
  }],
  body: {
    type: "BlockStatement",
    body: [{
      type: "ReturnStatement",
      argument: {
        type: "BinaryExpression",
        operator: "*",
        left: {
          type: "Identifier",
          name: "n"
        },
        right: {
          type: "Identifier",
          name: "n"
        }
      }
    }]
  }
}

下文將對(duì)AST各個(gè)類型節(jié)點(diǎn)做解釋。更多AST生成,入口如下:

eslint

AST Explorer

esprima

結(jié)合可視化工具,舉個(gè)例子

如下代碼:

var a = 42;
var b = 5;
function addA(d) {
    return a + d;
}
var c = addA(2) + b;

第一步詞法分析之后長成如下圖所示:

語法分析,生產(chǎn)抽象語法樹,生成的抽象語法樹如下圖所示

Base Node

所有節(jié)點(diǎn)類型都實(shí)現(xiàn)以下接口:

interface Node {
  type: string;
  range?: [number, number];
  loc?: SourceLocation;
}

該type字段是表示AST變體類型的字符串。該loc字段表示節(jié)點(diǎn)的源位置信息。如果解析器沒有生成有關(guān)節(jié)點(diǎn)源位置的信息,則該字段為null;否則它是一個(gè)對(duì)象,包括一個(gè)起始位置(被解析的源區(qū)域的第一個(gè)字符的位置)和一個(gè)結(jié)束位置.

interface SourceLocation {
    start: Position;
    end: Position;
    source?: string | null;
}

每個(gè)Position對(duì)象由一個(gè)line數(shù)字(1索引)和一個(gè)column數(shù)字(0索引)組成:

interface Position {
    line: uint32 >= 1;
    column: uint32 >= 0;
}
Programs
interface Program <: Node {
    type: "Program";
    sourceType: "script" | "module";
    body: StatementListItem[] | ModuleItem[];
}

表示一個(gè)完整的源代碼樹。

Scripts and Modules

源代碼數(shù)的來源包括兩種,一種是script腳本,一種是modules模塊

當(dāng)為script時(shí),body為StatementListItem。
當(dāng)為modules時(shí),body為ModuleItem。

類型StatementListItemModuleItem類型如下。

type StatementListItem = Declaration | Statement;
type ModuleItem = ImportDeclaration | ExportDeclaration | StatementListItem;
ImportDeclaration

import語法,導(dǎo)入模塊

type ImportDeclaration {
    type: "ImportDeclaration";
    specifiers: ImportSpecifier[];
    source: Literal;
}

ImportSpecifier類型如下:

interface ImportSpecifier {
    type: "ImportSpecifier" | "ImportDefaultSpecifier" | "ImportNamespaceSpecifier";
    local: Identifier;
    imported?: Identifier;
}

ImportSpecifier語法如下:

import { foo } from "./foo";

ImportDefaultSpecifier語法如下:

import foo from "./foo";

ImportNamespaceSpecifier語法如下

import * as foo from "./foo";
ExportDeclaration

export類型如下

type ExportDeclaration = ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration;

ExportAllDeclaration從指定模塊中導(dǎo)出

interface ExportAllDeclaration {
    type: "ExportAllDeclaration";
    source: Literal;
}

語法如下:

export * from "./foo";

ExportDefaultDeclaration導(dǎo)出默認(rèn)模塊

interface ExportDefaultDeclaration {
    type: "ExportDefaultDeclaration";
    declaration: Identifier | BindingPattern | ClassDeclaration | Expression | FunctionDeclaration;
}

語法如下:

export default "foo";

ExportNamedDeclaration導(dǎo)出部分模塊

interface ExportNamedDeclaration {
    type: "ExportNamedDeclaration";
    declaration: ClassDeclaration | FunctionDeclaration | VariableDeclaration;
    specifiers: ExportSpecifier[];
    source: Literal;
}

語法如下:

export const foo = "foo";
Declarations and Statements

declaration,即聲明,類型如下:

type Declaration = VariableDeclaration | FunctionDeclaration | ClassDeclaration;

statements,即語句,類型如下:

type Statement = BlockStatement | BreakStatement | ContinueStatement |
    DebuggerStatement | DoWhileStatement | EmptyStatement |
    ExpressionStatement | ForStatement | ForInStatement |
    ForOfStatement | FunctionDeclaration | IfStatement |
    LabeledStatement | ReturnStatement | SwitchStatement |
    ThrowStatement | TryStatement | VariableDeclaration |
    WhileStatement | WithStatement;
VariableDeclarator

變量聲明,kind 屬性表示是什么類型的聲明,因?yàn)?ES6 引入了 const/let。

interface VariableDeclaration <: Declaration {
    type: "VariableDeclaration";
    declarations: [ VariableDeclarator ];
    kind: "var" | "let" | "const";
}
FunctionDeclaration

函數(shù)聲明(非函數(shù)表達(dá)式)

interface FunctionDeclaration {
    type: "FunctionDeclaration";
    id: Identifier | null;
    params: FunctionParameter[];
    body: BlockStatement;
    generator: boolean;
    async: boolean;
    expression: false;
}

例如:

function foo() {}

function *bar() { yield "44"; }

async function noop() { await new Promise(function(resolve, reject) { resolve("55"); }) }
ClassDeclaration

類聲明(非類表達(dá)式)

interface ClassDeclaration {
    type: "ClassDeclaration";
    id: Identifier | null;
    superClass: Identifier | null;
    body: ClassBody;
}

ClassBody聲明如下:

interface ClassBody {
    type: "ClassBody";
    body: MethodDefinition[];
}

MethodDefinition表示方法聲明;

interface MethodDefinition {
    type: "MethodDefinition";
    key: Expression | null;
    computed: boolean;
    value: FunctionExpression | null;
    kind: "method" | "constructor";
    static: boolean;
}
class foo {
    constructor() {}
    method() {}
};
ContinueStatement

continue語句

interface ContinueStatement {
    type: "ContinueStatement";
    label: Identifier | null;
}

例如:

for (var i = 0; i < 10; i++) {
    if (i === 0) {
        continue;
    }
}
DebuggerStatement

debugger語句

interface DebuggerStatement {
    type: "DebuggerStatement";
}

例如

while(true) {
    debugger;
}
DoWhileStatement

do-while語句

interface DoWhileStatement {
    type: "DoWhileStatement";
    body: Statement;
    test: Expression;
}

test表示while條件

例如:

var i = 0;
do {
    i++;
} while(i = 2)
EmptyStatement

空語句

interface EmptyStatement {
    type: "EmptyStatement";
}

例如:

if(true);

var a = [];
for(i = 0; i < a.length; a[i++] = 0);
ExpressionStatement

表達(dá)式語句,即,由單個(gè)表達(dá)式組成的語句。

interface ExpressionStatement {
    type: "ExpressionStatement";
    expression: Expression;
    directive?: string;
}

當(dāng)表達(dá)式語句表示一個(gè)指令(例如“use strict”)時(shí),directive屬性將包含該指令字符串。

例如:

(function(){});
ForStatement

for語句

interface ForStatement {
    type: "ForStatement";
    init: Expression | VariableDeclaration | null;
    test: Expression | null;
    update: Expression | null;
    body: Statement;
}
ForInStatement

for...in語句

interface ForInStatement {
    type: "ForInStatement";
    left: Expression;
    right: Expression;
    body: Statement;
    each: false;
}
ForOfStatement

for...of語句

interface ForOfStatement {
    type: "ForOfStatement";
    left: Expression;
    right: Expression;
    body: Statement;
}
IfStatement

if 語句

interface IfStatement {
    type: "IfStatement";
    test: Expression;
    consequent: Statement;
    alternate?: Statement;
}

consequent表示if命中后內(nèi)容,alternate表示else或者else if的內(nèi)容。

LabeledStatement

label語句,多用于精確的使用嵌套循環(huán)中的continue和break。

interface LabeledStatement {
    type: "LabeledStatement";
    label: Identifier;
    body: Statement;
}

如:

var num = 0;
outPoint:
for (var i = 0 ; i < 10 ; i++){
        for (var j = 0 ; j < 10 ; j++){
            if( i == 5 && j == 5 ){
                break outPoint;
            }
            num++;
        }
}
ReturnStatement

return 語句

interface ReturnStatement {
    type: "ReturnStatement";
    argument: Expression | null;
}
SwitchStatement

Switch語句

interface SwitchStatement {
    type: "SwitchStatement";
    discriminant: Expression;
    cases: SwitchCase[];
}

discriminant表示switch的變量。

SwitchCase類型如下

interface SwitchCase {
    type: "SwitchCase";
    test: Expression | null;
    consequent: Statement[];
}
ThrowStatement

throw語句

interface ThrowStatement {
    type: "ThrowStatement";
    argument: Expression;
}
TryStatement

try...catch語句

interface TryStatement {
    type: "TryStatement";
    block: BlockStatement;
    handler: CatchClause | null;
    finalizer: BlockStatement | null;
}

handler為catch處理聲明內(nèi)容,finalizer為finally內(nèi)容。

CatchClaus 類型如下

interface CatchClause {
    type: "CatchClause";
    param: Identifier | BindingPattern;
    body: BlockStatement;
}

例如:

try {
    foo();
} catch (e) {
    console.erroe(e);
} finally {
    bar();
}
WhileStatement

while語句

interface WhileStatement {
    type: "WhileStatement";
    test: Expression;
    body: Statement;
}

test為判定表達(dá)式

WithStatement

with語句(指定塊語句的作用域的作用域)

interface WithStatement {
    type: "WithStatement";
    object: Expression;
    body: Statement;
}

如:

var a = {};

with(a) {
    name = "xiao.ming";
}

console.log(a); // {name: "xiao.ming"}
Expressions and Patterns

Expressions可用類型如下:

type Expression = ThisExpression | Identifier | Literal |
    ArrayExpression | ObjectExpression | FunctionExpression | ArrowFunctionExpression | ClassExpression |
    TaggedTemplateExpression | MemberExpression | Super | MetaProperty |
    NewExpression | CallExpression | UpdateExpression | AwaitExpression | UnaryExpression |
    BinaryExpression | LogicalExpression | ConditionalExpression |
    YieldExpression | AssignmentExpression | SequenceExpression;

Patterns可用有兩種類型,函數(shù)模式和對(duì)象模式如下:

type BindingPattern = ArrayPattern | ObjectPattern;
ThisExpression

this 表達(dá)式

interface ThisExpression {
    type: "ThisExpression";
}
Identifier

標(biāo)識(shí)符,就是我們寫 JS 時(shí)自定義的名稱,如變量名,函數(shù)名,屬性名,都?xì)w為標(biāo)識(shí)符。相應(yīng)的接口是這樣的:

interface Identifier {
    type: "Identifier";
    name: string;
}
Literal

字面量,這里不是指 [] 或者 {} 這些,而是本身語義就代表了一個(gè)值的字面量,如 1,“hello”, true 這些,還有正則表達(dá)式(有一個(gè)擴(kuò)展的 Node 來表示正則表達(dá)式),如 /d?/。

interface Literal {
    type: "Literal";
    value: boolean | number | string | RegExp | null;
    raw: string;
    regex?: { pattern: string, flags: string };
}

例如:

var a = 1;
var b = "b";
var c = false;
var d = /d/;
ArrayExpression

數(shù)組表達(dá)式

interface ArrayExpression {
    type: "ArrayExpression";
    elements: ArrayExpressionElement[];
}

例:

[1, 2, 3, 4];
ArrayExpressionElement

數(shù)組表達(dá)式的節(jié)點(diǎn),類型如下

type ArrayExpressionElement = Expression | SpreadElement;

Expression包含所有表達(dá)式,SpreadElement為擴(kuò)展運(yùn)算符語法。

SpreadElement

擴(kuò)展運(yùn)算符

interface SpreadElement {
    type: "SpreadElement";
    argument: Expression;
}

如:

var a = [3, 4];
var b = [1, 2, ...a];

var c = {foo: 1};
var b = {bar: 2, ...c};
ObjectExpression

對(duì)象表達(dá)式

interface ObjectExpression {
    type: "ObjectExpression";
    properties: Property[];
}

Property代表為對(duì)象的屬性描述

類型如下

interface Property {
    type: "Property";
    key: Expression;
    computed: boolean;
    value: Expression | null;
    kind: "get" | "set" | "init";
    method: false;
    shorthand: boolean;
}

kind用來表示是普通的初始化,或者是 get/set。

例如:

var obj = {
    foo: "foo",
    bar: function() {},
    noop() {}, // method 為 true
    ["computed"]: "computed"  // computed 為 true
}
FunctionExpression

函數(shù)表達(dá)式

interface FunctionExpression {
    type: "FunctionExpression";
    id: Identifier | null;
    params: FunctionParameter[];
    body: BlockStatement;
    generator: boolean;
    async: boolean;
    expression: boolean;
}

例如:

var foo = function () {}
ArrowFunctionExpression

箭頭函數(shù)表達(dá)式

interface ArrowFunctionExpression {
    type: "ArrowFunctionExpression";
    id: Identifier | null;
    params: FunctionParameter[];
    body: BlockStatement | Expression;
    generator: boolean;
    async: boolean;
    expression: false;
}

generator表示是否為generator函數(shù),async表示是否為async/await函數(shù),params為參數(shù)定義。

FunctionParameter類型如下

type FunctionParameter = AssignmentPattern | Identifier | BindingPattern;

例:

var foo = () => {};
ClassExpression

類表達(dá)式

interface ClassExpression {
    type: "ClassExpression";
    id: Identifier | null;
    superClass: Identifier | null;
    body: ClassBody;
}

例如:

var foo = class {
    constructor() {}
    method() {}
};
TaggedTemplateExpression

標(biāo)記模板文字函數(shù)

interface TaggedTemplateExpression {
    type: "TaggedTemplateExpression";
    readonly tag: Expression;
    readonly quasi: TemplateLiteral;
}

TemplateLiteral類型如下

interface TemplateLiteral {
    type: "TemplateLiteral";
    quasis: TemplateElement[];
    expressions: Expression[];
}

TemplateElement類型如下

interface TemplateElement {
    type: "TemplateElement";
    value: { cooked: string; raw: string };
    tail: boolean;
}

例如

var foo = function(a){ console.log(a); }
foo`test`;
MemberExpression

屬性成員表達(dá)式

interface MemberExpression {
    type: "MemberExpression";
    computed: boolean;
    object: Expression;
    property: Expression;
}

例如:

const foo = {bar: "bar"};
foo.bar;
foo["bar"]; // computed 為 true
Super

父類關(guān)鍵字

interface Super {
    type: "Super";
}

例如:

class foo {};
class bar extends foo {
    constructor() {
        super();
    }
}
MetaProperty

(這個(gè)不知道干嘛用的)

interface MetaProperty {
    type: "MetaProperty";
    meta: Identifier;
    property: Identifier;
}

例如:

new.target  // 通過new 聲明的對(duì)象,new.target會(huì)存在

import.meta
CallExpression

函數(shù)執(zhí)行表達(dá)式

interface CallExpression {
    type: "CallExpression";
    callee: Expression | Import;
    arguments: ArgumentListElement[];
}

Import類型,沒搞懂。

interface Import {
    type: "Import"
}

ArgumentListElement類型

type ArgumentListElement = Expression | SpreadElement;

如:

var foo = function (){};
foo();
NewExpression

new 表達(dá)式

interface NewExpression {
    type: "NewExpression";
    callee: Expression;
    arguments: ArgumentListElement[];
}
UpdateExpression

更新操作符表達(dá)式,如++、--;

interface UpdateExpression {
  type: "UpdateExpression";
  operator: "++" | "--";
  argument: Expression;
  prefix: boolean;
}

如:

var i = 0;
i++;
++i; // prefix為true
AwaitExpression

await表達(dá)式,會(huì)與async連用。

interface AwaitExpression {
    type: "AwaitExpression";
    argument: Expression;
}

async function foo() {
    var bar = function() {
        new Primise(function(resolve, reject) {
            setTimeout(function() {
                resove("foo")
            }, 1000);
        });
    }
    return await bar();
}

foo() // foo
UnaryExpression

一元操作符表達(dá)式

interface UnaryExpression {
  type: "UnaryExpression";
  operator: UnaryOperator;
  prefix: boolean;
  argument: Expression;
}

枚舉UnaryOperator

enum UnaryOperator {
  "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" | "throw"
}
BinaryExpression

二元操作符表達(dá)式

interface BinaryExpression {
    type: "BinaryExpression";
    operator: BinaryOperator;
    left: Expression;
    right: Expression;
}

枚舉BinaryOperator

enum BinaryOperator {
  "==" | "!=" | "===" | "!=="
     | "<" | "<=" | ">" | ">="
     | "<<" | ">>" | ">>>"
     | "+" | "-" | "*" | "/" | "%"
     | "**" | "|" | "^" | "&" | "in"
     | "instanceof"
     | "|>"
}
LogicalExpression

邏輯運(yùn)算符表達(dá)式

interface LogicalExpression {
    type: "LogicalExpression";
    operator: "||" | "&&";
    left: Expression;
    right: Expression;
}

如:

var a = "-";
var b = a || "-";

if (a && b) {}
ConditionalExpression

條件運(yùn)算符

interface ConditionalExpression {
    type: "ConditionalExpression";
    test: Expression;
    consequent: Expression;
    alternate: Expression;
}

例如:

var a = true;
var b = a ? "consequent" : "alternate";
YieldExpression

yield表達(dá)式

interface YieldExpression {
    type: "YieldExpression";
    argument: Expression | null;
    delegate: boolean;
}

例如:

function* gen(x) {
  var y = yield x + 2;
  return y;
}
AssignmentExpression

賦值表達(dá)式。

interface AssignmentExpression {
    type: "AssignmentExpression";
    operator: "=" | "*=" | "**=" | "/=" | "%=" | "+=" | "-=" |
        "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=";
    left: Expression;
    right: Expression;
}

operator屬性表示一個(gè)賦值運(yùn)算符,leftright是賦值運(yùn)算符左右的表達(dá)式。

SequenceExpression

序列表達(dá)式(使用逗號(hào))。

interface SequenceExpression {
    type: "SequenceExpression";
    expressions: Expression[];
}
var a, b;
a = 1, b = 2
ArrayPattern

數(shù)組解析模式

interface ArrayPattern {
    type: "ArrayPattern";
    elements: ArrayPatternElement[];
}

例:

const [a, b] = [1,3];

elements代表數(shù)組節(jié)點(diǎn)

ArrayPatternElement如下

type ArrayPatternElement = AssignmentPattern | Identifier | BindingPattern | RestElement | null;
AssignmentPattern

默認(rèn)賦值模式,數(shù)組解析、對(duì)象解析、函數(shù)參數(shù)默認(rèn)值使用。

interface AssignmentPattern {
    type: "AssignmentPattern";
    left: Identifier | BindingPattern;
    right: Expression;
}

例:

const [a, b = 4] = [1,3];
RestElement

剩余參數(shù)模式,語法與擴(kuò)展運(yùn)算符相近。

interface RestElement {
    type: "RestElement";
    argument: Identifier | BindingPattern;
}

例:

const [a, b, ...c] = [1, 2, 3, 4];
ObjectPatterns

對(duì)象解析模式

interface ObjectPattern {
    type: "ObjectPattern";
    properties: Property[];
}

例:

const object = {a: 1, b: 2};
const { a, b } = object;
結(jié)束

AST的作用大致分為幾類

IDE使用,如代碼風(fēng)格檢測(eslint等)、代碼的格式化,代碼高亮,代碼錯(cuò)誤等等

代碼的混淆壓縮

轉(zhuǎn)換代碼的工具。如webpack,rollup,各種代碼規(guī)范之間的轉(zhuǎn)換,ts,jsx等轉(zhuǎn)換為原生js

了解AST,最終還是為了讓我們了解我們使用的工具,當(dāng)然也讓我們更了解JavaScript,更靠近JavaScript。

參考文獻(xiàn)

前端進(jìn)階之 Javascript 抽象語法樹

抽象語法樹(Abstract Syntax Tree)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102602.html

相關(guān)文章

  • 平庸前端碼農(nóng)之蛻變 — AST

    摘要:為什么要談抽象語法樹如果你查看目前任何主流的項(xiàng)目中的,會(huì)發(fā)現(xiàn)前些年的不計(jì)其數(shù)的插件誕生。什么是抽象語法樹估計(jì)很多同學(xué)會(huì)和圖中的喵一樣,看完這段官方的定義一臉懵逼。它讀取我們的代碼,然后把它們按照預(yù)定的規(guī)則合并成一個(gè)個(gè)的標(biāo)識(shí)。 前言 首先,先說明下該文章是譯文,原文出自《AST for JavaScript developers》。很少花時(shí)間特地翻譯一篇文章,咬文嚼字是件很累的事情,實(shí)在...

    dreamans 評(píng)論0 收藏0
  • AST抽象語法——最基礎(chǔ)javascript重點(diǎn)知識(shí),99%的人根本不了解

    摘要:抽象語法樹,是一個(gè)非?;A(chǔ)而重要的知識(shí)點(diǎn),但國內(nèi)的文檔卻幾乎一片空白。事實(shí)上,在世界中,你可以認(rèn)為抽象語法樹是最底層。通過抽象語法樹解析,我們可以像童年時(shí)拆解玩具一樣,透視這臺(tái)機(jī)器的運(yùn)轉(zhuǎn),并且重新按著你的意愿來組裝。 抽象語法樹(AST),是一個(gè)非?;A(chǔ)而重要的知識(shí)點(diǎn),但國內(nèi)的文檔卻幾乎一片空白。本文將帶大家從底層了解AST,并且通過發(fā)布一個(gè)小型前端工具,來帶大家了解AST的強(qiáng)大功能 ...

    godiscoder 評(píng)論0 收藏0
  • JavaScript 語法與代碼轉(zhuǎn)化實(shí)踐

    摘要:語法樹與代碼轉(zhuǎn)化實(shí)踐歸納于筆者的現(xiàn)代開發(fā)語法基礎(chǔ)與實(shí)踐技巧系列文章中。抽象語法樹抽象語法樹的作用在于牢牢抓住程序的脈絡(luò),從而方便編譯過程的后續(xù)環(huán)節(jié)如代碼生成對(duì)程序進(jìn)行解讀。 JavaScript 語法樹與代碼轉(zhuǎn)化實(shí)踐 歸納于筆者的現(xiàn)代 JavaScript 開發(fā):語法基礎(chǔ)與實(shí)踐技巧系列文章中。本文引用的參考資料聲明于 JavaScript 學(xué)習(xí)與實(shí)踐資料索引中,特別需要聲明是部分代碼片...

    Gemini 評(píng)論0 收藏0
  • 抽象語法(Abstract Syntax Tree)

    摘要:例如會(huì)被分解成解析語法分析這個(gè)過程是將詞法單元流數(shù)組轉(zhuǎn)換成一個(gè)由元素逐級(jí)嵌套所組成的代表了程序語法結(jié)構(gòu)的樹,這個(gè)樹就叫抽象語法樹。常用的有使用生成并使用抽象語法樹。 一般來說,程序中的一段源代碼在執(zhí)行之前會(huì)經(jīng)歷下面三個(gè)步驟1 分詞/詞法分析這個(gè)過程會(huì)將由字符組成的字符串分解成有意義的代碼快,這些代碼塊被稱為詞法單元。例如 var a = 4;會(huì)被分解成 var、a、=、4、; 2 解析...

    余學(xué)文 評(píng)論0 收藏0
  • JavaScript 是如何工作的:解析、抽象語法AST)+ 提升編譯速度5個(gè)技巧

    摘要:無論你使用的是解釋型語言還是編譯型語言,都有一個(gè)共同的部分將源代碼作為純文本解析為抽象語法樹的數(shù)據(jù)結(jié)構(gòu)。和抽象語法樹相對(duì)的是具體語法樹,通常稱作分析樹。這是引入字節(jié)碼緩存的原因。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 14 篇。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過了前面的章節(jié),可以在這里找到它們: JavaS...

    raoyi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<