From 606e5580a263aa829f82a0cff5574047f2fed24f Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 3 Sep 2014 13:55:36 +0300 Subject: [PATCH 1/3] Added Parser AST format specs. --- README.md | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1c197eb..0ef1d93 100644 --- a/README.md +++ b/README.md @@ -149,9 +149,9 @@ _JSX uses the same punctuators and braces as ECMAScript. WhiteSpace, LineTermina Parser Implementations ---------------------- -- [acorn-jsx](https://github.com/RReverser/acorn-jsx): A fork of acorn. -- [esprima-fb](https://github.com/facebook/esprima): A fork of esprima. -- [sweet-jsx](https://github.com/andreypopp/sweet-jsx): A sweet.js macro. +- [acorn-jsx][acorn-jsx]: A fork of acorn. +- [esprima-fb][esprima-fb]: A fork of esprima. +- [sweet-jsx][sweet-jsx]: A sweet.js macro. Transpilers ----------- @@ -232,3 +232,93 @@ Prior Art --------- The JSX syntax is similar to the [E4X Specification (ECMA-357)](http://www.ecma-international.org/publications/standards/Ecma-357.htm). E4X is a deprecated specification with deep reaching semantic meaning. JSX partially overlaps with a tiny subset of the E4X syntax. However, JSX has no relation to the E4X specification. + +AST Format +---------- + +ECMAScript+JSX parsers ([esprima-fb][esprima-fb], [acorn-jsx][acorn-jsx]) return AST, conformant with [Mozilla AST format](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API) and extended with following node types: + +__JSX Element__ + +``` +interface XJSElement <: Expression { + type: "XJSElement", + openingElement: XJSOpeningElement, + children: [ Literal | XJSExpressionContainer | XJSElement ], + closingElement: XJSClosingElement | null +} +``` + +__JSX Boundary Tags__ + +``` +interface XJSOpeningElement <: Node { + type: "XJSOpeningElement", + name: XJSIdentifier | XJSMemberExpression | XJSNamespacedName, + attributes: [ XJSAttribute | XJSSpreadAttribute ], + selfClosing: boolean; +} + +interface XJSClosingElement <: Node { + type: "XJSClosingElement", + name: XJSIdentifier | XJSMemberExpression | XJSNamespacedName +} +``` + +__JSX Names__ + +``` +interface XJSIdentifier <: Identifier { + type: "XJSIdentifier"; +} + +interface XJSMemberExpression <: Expression { + type: "XJSMemberExpression"; + object: XJSMemberExpression | XJSIdentifier, + property: XJSIdentifier +} + +interface XJSNamespacedName <: Expression { + type: "XJSNamespacedName"; + namespace: XJSIdentifier, + name: XJSIdentifier +} +``` + +__JSX Attributes__ + +``` +interface XJSAttribute <: Node { + type: "XJSAttribute", + name: XJSIdentifier | XJSNamespacedName, + value: Literal | XJSExpressionContainer | XJSElement | null +} + +// This is already used by ES6 parsers, but not included +// in Mozilla's spec yet. +interface SpreadElement <: Pattern { + type: "SpreadElement"; + argument: Expression; +} + +interface XJSSpreadAttribute <: SpreadElement { + type: "XJSSpreadAttribute"; +} +``` + +__JSX Expression Container__ + +``` +interface XJSExpressionContainer <: Node { + type: "XJSExpressionContainer", + expression: Expression | XJSEmptyExpression; +} + +interface XJSEmptyExpression <: Node { + type: "XJSEmptyExpression" +} +``` + +[acorn-jsx]: https://github.com/RReverser/acorn-jsx +[esprima-fb]: https://github.com/facebook/esprima +[sweet-jsx]: https://github.com/andreypopp/sweet-jsx From 24387aaa659fe7fa66229b05fa8d4d1cf454fff7 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 3 Sep 2014 14:06:26 +0300 Subject: [PATCH 2/3] AST Format refactorings. --- README.md | 72 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 0ef1d93..c41387c 100644 --- a/README.md +++ b/README.md @@ -236,52 +236,56 @@ The JSX syntax is similar to the [E4X Specification (ECMA-357)](http://www.ecma- AST Format ---------- -ECMAScript+JSX parsers ([esprima-fb][esprima-fb], [acorn-jsx][acorn-jsx]) return AST, conformant with [Mozilla AST format](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API) and extended with following node types: +JSX extends ECMAScript [Mozilla AST format](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API) with following node types: -__JSX Element__ +__JSX Names__ ``` -interface XJSElement <: Expression { - type: "XJSElement", - openingElement: XJSOpeningElement, - children: [ Literal | XJSExpressionContainer | XJSElement ], - closingElement: XJSClosingElement | null +interface XJSIdentifier <: Identifier { + type: "XJSIdentifier"; +} + +interface XJSNamespacedName <: Expression, Pattern { + type: "XJSNamespacedName"; + namespace: XJSIdentifier, + name: XJSIdentifier +} + +interface XJSMemberExpression <: Expression, Pattern { + type: "XJSMemberExpression"; + object: XJSMemberExpression | XJSIdentifier, + property: XJSIdentifier } ``` -__JSX Boundary Tags__ +__JSX Expression Container__ ``` -interface XJSOpeningElement <: Node { - type: "XJSOpeningElement", - name: XJSIdentifier | XJSMemberExpression | XJSNamespacedName, - attributes: [ XJSAttribute | XJSSpreadAttribute ], - selfClosing: boolean; +interface XJSEmptyExpression <: Node { + type: "XJSEmptyExpression" } -interface XJSClosingElement <: Node { - type: "XJSClosingElement", - name: XJSIdentifier | XJSMemberExpression | XJSNamespacedName +interface XJSExpressionContainer <: Node { + type: "XJSExpressionContainer", + expression: Expression | XJSEmptyExpression; } ``` -__JSX Names__ +__JSX Boundary Tags__ ``` -interface XJSIdentifier <: Identifier { - type: "XJSIdentifier"; +interface XJSBoundaryElement <: Node { + name: XJSIdentifier | XJSMemberExpression | XJSNamespacedName; } -interface XJSMemberExpression <: Expression { - type: "XJSMemberExpression"; - object: XJSMemberExpression | XJSIdentifier, - property: XJSIdentifier +interface XJSOpeningElement <: XJSBoundaryElement { + type: "XJSOpeningElement", + attributes: [ XJSAttribute | XJSSpreadAttribute ], + selfClosing: boolean; } -interface XJSNamespacedName <: Expression { - type: "XJSNamespacedName"; - namespace: XJSIdentifier, - name: XJSIdentifier +interface XJSClosingElement <: XJSBoundaryElement { + type: "XJSClosingElement" } ``` @@ -306,16 +310,14 @@ interface XJSSpreadAttribute <: SpreadElement { } ``` -__JSX Expression Container__ +__JSX Element__ ``` -interface XJSExpressionContainer <: Node { - type: "XJSExpressionContainer", - expression: Expression | XJSEmptyExpression; -} - -interface XJSEmptyExpression <: Node { - type: "XJSEmptyExpression" +interface XJSElement <: Expression { + type: "XJSElement", + openingElement: XJSOpeningElement, + children: [ Literal | XJSExpressionContainer | XJSElement ], + closingElement: XJSClosingElement | null } ``` From 460fadf40d06a956005554d0acadc5cc6150f8d4 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 3 Sep 2014 14:20:19 +0300 Subject: [PATCH 3/3] Added "AST tools" section. --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index c41387c..97cd6c7 100644 --- a/README.md +++ b/README.md @@ -321,6 +321,13 @@ interface XJSElement <: Expression { } ``` +__Tools that work with JSX AST__ + +* Parsing: [acorn-jsx][acorn-jsx], [esprima-fb][esprima-fb]. +* Traversal: [estraverse-fb](https://github.com/RReverser/estraverse-fb). +* Node creation and declarative traversal: [ast-types](https://github.com/benjamn/ast-types) +* Transpiling to ECMAScript AST: [jsx-transpiler](https://github.com/RReverser/jsx-transpiler) + [acorn-jsx]: https://github.com/RReverser/acorn-jsx [esprima-fb]: https://github.com/facebook/esprima [sweet-jsx]: https://github.com/andreypopp/sweet-jsx