Больше сообщений в блоге, добро пожаловать в StarGithub/Blog
Дерево абстрактного синтаксиса JS Подробное объяснение см. в сопутствующей статье:Дерево абстрактного синтаксиса Javascript для продвинутого внешнего интерфейса
Javascript-кодРазобратьШаг (Parse) делится на две фазы:Лексический анализа такжеСинтаксический анализ. Этот шаг получает код и выводитабстрактное синтаксическое дерево, также известный как АСТ.
По мере того, как экология Babel становится все более и более полной, мы обычно используем Babel для анализа процесса разбора кода. Вавилон используетESTreeи модифицированный AST, документацию по его ядру можно найти [здесь](https://github.com/babel/babel/blob/master/doc/ast/spec.md).
В процессе анализа AST Javascript с помощью инструментовAST ExplorerЭто может помочь нам лучше понять восприятие узлов AST.
Чтобы помочь вам лучше совместить анализ примеров и понять состав основных типов узлов Babylon AST, здесь перечислены 13 распространенных примеров, а также соответствующие узлы AST и подробный анализ типов узлов соответственно.
AST всего следующего кода основан наBabylon7
объявление переменной
код
let a = 'hello'
AST
VariableDeclaration
объявление переменной,kindКакой тип объявления представляет свойство с момента введения ES6const/let.declarationsПредставляет несколько описаний объявления, поскольку мы можем:let a = 1, b = 2;.
interface VariableDeclaration <: Declaration {
type: "VariableDeclaration";
declarations: [ VariableDeclarator ];
kind: "var";
}
VariableDeclarator
описание объявления переменной,idпредставляет узел имени переменной,initВыражение, представляющее начальное значение, которое может бытьnull.
interface VariableDeclarator <: Node {
type: "VariableDeclarator";
id: Pattern;
init: Expression | null;
}
Identifier
Идентификаторы, как я думаю, должны называться — это имена, которые мы настраиваем при написании JS, такие как имена переменных, имена функций и имена атрибутов, которые классифицируются как идентификаторы. Соответствующий интерфейс выглядит следующим образом:
interface Identifier <: Expression, Pattern {
type: "Identifier";
name: string;
}
Идентификатор может быть выражением или шаблоном деструктурирования (синтаксис деструктурирования в ES6). мы увидим позжеExpressionа такжеPatternсвязанный контент.
Literal
Буквально, не имелось в виду здесь[]или{}Эти, но литералы, которые семантически представляют значение, такие как1,“hello”, trueэти и регулярные выражения (есть расширенныйNodeдля представления регулярных выражений), например/\d?/. Давайте посмотрим на определение документа:
interface Literal <: Expression {
type: "Literal";
value: string | boolean | null | number | RegExp;
}
valueЭто соответствует значению литерала, мы можем видеть тип литерального значения, строка, логическое значение, значение,nullи регулярный.
двоичные арифметические выражения
код
let a = 3+4
AST
BinaryExpression
Узел выражения бинарного оператора,leftа такжеrightпредставляет два выражения слева и справа от оператора,operatorПредставляет бинарный оператор.
interface BinaryExpression <: Expression {
type: "BinaryExpression";
operator: BinaryOperator;
left: Expression;
right: Expression;
}
BinaryOperator
Бинарный оператор, все значения следующие:
enum BinaryOperator {
"==" | "!=" | "===" | "!=="
| "<" | "<=" | ">" | ">="
| "<<" | ">>" | ">>>"
| "+" | "-" | "*" | "/" | "%"
| "|" | "^" | "&" | "in"
| "instanceof"
}
выражение присваивания
код
Этот пример будет немного сложнее и будет включать больше типов узлов.
this.state = {date: new Date()};
AST
ExpressionStatement
узел оператора выражения,a = a + 1илиa++там будетexpressionСвойство указывает на объект узла выражения (выражения будут упомянуты позже).
interface ExpressionStatement <: Statement {
type: "ExpressionStatement";
expression: Expression;
}
AssignmentExpression
узел выражения присваивания,operatorсвойство представляет оператор присваивания,leftа такжеrightэто выражение вокруг оператора присваивания.
interface AssignmentExpression <: Expression {
type: "AssignmentExpression";
operator: AssignmentOperator;
left: Pattern | Expression;
right: Expression;
}
AssignmentOperator
Оператор присваивания, все значения следующие: (не так много часто используемых)
enum AssignmentOperator {
"=" | "+=" | "-=" | "*=" | "/=" | "%="
| "<<=" | ">>=" | ">>>="
| "|=" | "^=" | "&="
}
MemberExpression
Узел выражения члена, то есть оператор, который ссылается на член объекта,objectузел выражения, ссылающийся на объект,propertyимя атрибута,computedеслиfalse, что значит.обращаться к членам,propertyдолжно бытьIdentifierузел, еслиcomputedсобственностьtrue, тогда[]цитировать, т.propertyЯвляетсяExpressionУзел, имя которого является результирующим значением выражения.
interface MemberExpression <: Expression, Pattern {
type: "MemberExpression";
object: Expression;
property: Expression;
computed: boolean;
}
ThisExpression
выражатьthis.
interface ThisExpression <: Expression {
type: "ThisExpression";
}
ObjectExpression
узел выражения объекта,propertyСвойство — это массив, который представляет каждую пару ключ-значение объекта, а каждый элемент — это узел свойства.
interface ObjectExpression <: Expression {
type: "ObjectExpression";
properties: [ Property ];
}
Property
Узлы свойств в выражениях объектов.keyпредставляет ключ,valueпредставляет собой значение, поскольку синтаксис ES5 имеетget/setсуществует, значит, естьkindАтрибут, используемый для обозначения нормальной инициализации илиget/set.
interface Property <: Node {
type: "Property";
key: Literal | Identifier;
value: Expression;
kind: "init" | "get" | "set";
}
NewExpression
newвыражение.
interface NewExpression <: CallExpression {
type: "NewExpression";
}
выражение вызова функции
код
console.log(`Hello ${name}`)
AST
CallExpression
выражение вызова функции, что означаетfunc(1, 2)заявления этого типа.calleeСвойство — это узел выражения, представляющий функцию,argumentsпредставляет собой массив, элементами которого являются узлы выражений, представляющие список аргументов функции.
interface CallExpression <: Expression {
type: "CallExpression";
callee: Expression;
arguments: [ Expression ];
}
TemplateLiteral
interface TemplateLiteral <: Expression {
type: "TemplateLiteral";
quasis: [ TemplateElement ];
expressions: [ Expression ];
}
TemplateElement
interface TemplateElement <: Node {
type: "TemplateElement";
tail: boolean;
value: {
cooked: string | null;
raw: string;
};
}
стрелочная функция
код
i => i++
AST
ArrowFunctionExpression
Выражения стрелочных функций.
interface ArrowFunctionExpression <: Function, Expression {
type: "ArrowFunctionExpression";
body: BlockStatement | Expression;
expression: boolean;
}
UpdateExpression
узел выражения оператора обновления, т.е.++/--, который похож на унарный оператор, за исключениемoperatorТип объекта узла, на который указывает другой, здесь оператор обновления.
interface UpdateExpression <: Expression {
type: "UpdateExpression";
operator: UpdateOperator;
argument: Expression;
prefix: boolean;
}
UpdateOperator
оператор обновления, значение равно++или--, с узлом выражения обновленияprefixсвойство указывать до и после.
enum UpdateOperator {
"++" | "--"
}
объявление функции
код
function Hello(name = 'Lily'){
}
AST
FunctionDeclaration
Объявления функций, в отличие от ранее упомянутой функции,idне может бытьnull.
interface FunctionDeclaration <: Function, Declaration {
type: "FunctionDeclaration";
id: Identifier;
}
AssignmentPattern
interface AssignmentPattern <: Pattern {
type: "AssignmentPattern";
left: Pattern;
right: Expression;
}
BlockStatement
Узел оператора блока, например:if (...) { // 这里是块语句的内容 }, блок может содержать несколько других операторов, поэтомуbodyСвойство, представляющее собой массив, представляет несколько операторов в блоке.
interface BlockStatement <: Statement {
type: "BlockStatement";
body: [ Statement ];
}
объявление класса
код
class Clock extends Component{
render(){
}
}
AST
Classes
interface Class <: Node {
id: Identifier | null;
superClass: Expression | null;
body: ClassBody;
decorators: [ Decorator ];
}
ClassBody
interface ClassBody <: Node {
type: "ClassBody";
body: [ ClassMethod | ClassPrivateMethod | ClassProperty | ClassPrivateProperty ];
}
ClassMethod
interface ClassMethod <: Function {
type: "ClassMethod";
key: Expression;
kind: "constructor" | "method" | "get" | "set";
computed: boolean;
static: boolean;
decorators: [ Decorator ];
}
если оператор
код
if(a === 0){
}
AST
IfStatement
ifУзлы операторов, очень распространенные, будут иметь три атрибута:testпредставление атрибутаif (...)выражения в скобках.
consequentатрибутом является то, что условиеtrueКогда оператор выполнения, как правило, оператор блока.
alternateатрибуты используются для представленияelseПоследующий узел оператора обычно представляет собой блочный оператор, но может быть и другим.ifУзлы операторов, то есть структуры, подобные этой:if (a) { //... } else if (b) { // ... }.alternateКонечно, это также может бытьnull.
interface IfStatement <: Statement {
type: "IfStatement";
test: Expression;
consequent: Statement;
alternate: Statement | null;
}
оператор переключения
код
switch(num){
case 0:
x = 'Sunday'
break;
default:
x = 'Weekday'
}
AST
SwitchStatement
switchУзел оператора имеет два свойства:discriminantпредставление атрибутаswitchВыражение, следующее за оператором, обычно переменная,casesсобственность - этоcaseмассив узлов, представляющих каждыйcaseутверждение.
interface SwitchStatement <: Statement {
type: "SwitchStatement";
discriminant: Expression;
cases: [ SwitchCase ];
}
SwitchCase
switchизcaseузел.testатрибут представляет этоcaseВыражение суждения ,consequentэтоcaseзаявление об исполнении.
когдаtestсобственностьnull, это значитdefaultэтоcaseузел.
interface SwitchCase <: Node {
type: "SwitchCase";
test: Expression | null;
consequent: [ Statement ];
}
для заявления
код
for (var i = 0; i < 9; i++) {
}
AST
ForStatement
forузел оператора цикла, атрибутinit/test/updateсоответственно указаноforТри выражения в скобках оператора, значение инициализации, условие оценки цикла и оператор обновления переменной, выполняемый в каждом цикле (initМожет быть объявлением переменной или выражением). Все три свойства могут бытьnull,Прямо сейчасfor(;;){}.bodyАтрибут используется для представления оператора, который должен выполняться в цикле.
interface ForStatement <: Statement {
type: "ForStatement";
init: VariableDeclaration | Expression | null;
test: Expression | null;
update: Expression | null;
body: Statement;
}
импорт модуля
код
import React from 'react'
AST
ImportDeclaration
объявление модуля.
interface ImportDeclaration <: ModuleDeclaration {
type: "ImportDeclaration";
specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ];
source: Literal;
}
ImportDefaultSpecifier
interface ImportDefaultSpecifier <: ModuleSpecifier {
type: "ImportDefaultSpecifier";
}
экспорт модуля
код
export default Clock
AST
ExportDefaultDeclaration
interface OptFunctionDeclaration <: FunctionDeclaration {
id: Identifier | null;
}
interface OptClasDeclaration <: ClassDeclaration {
id: Identifier | null;
}
interface ExportDefaultDeclaration <: ModuleDeclaration {
type: "ExportDefaultDeclaration";
declaration: OptFunctionDeclaration | OptClassDeclaration | Expression;
}
Метод рендеринга JSX
Код:
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}