Open11

ESTree 互換っぽい AST を出力する JavaScript のパーサーまとめ

Sosuke SuzukiSosuke Suzuki

https://github.com/estree/estree

ESTree という JavaScript の AST の仕様がある。ESTree っぽいものを出力してくれるパーサーをまとめていく。

雑にまとめているので興味ある人とか詳しい人は適当に追記してもらって構いません。

Sosuke SuzukiSosuke Suzuki

@babel/parser

https://github.com/babel/babel/tree/b1f57e5fb58f7e890b3be58965e014f6fd4950e0/packages/babel-parser

Babel で使われているパーサー。最新の JavaScript だけでなく、まだ ECMAScript に入っていないプロポーザルや TypeScript、Flow もオプションで対応している。また、AST は ESTree と一部互換性がないものを出力するが、estree プラグインを使うことで、ESTree 互換の AST を出力させることもできる。

Prettier のデフォルトパーサー。@babel/eslint-parserを使うことで ESLint のパーサーとしても使うことができる。

Sosuke SuzukiSosuke Suzuki

@typescript-eslint/typescript-estree

https://github.com/typescript-eslint/typescript-eslint/tree/21d1b62a0b84b502d2cf12674b3d141994a3ffd4/packages/typescript-estree

@typescript-eslint/parser の内部で使われている TypeScript をパースするためのパーサー。

内部的には TypeScript Compiler API を使ってパースした AST を ESTree 互換の形に変換している。新しい TypeScript の構文は RC が出てから実装される。

JavaScript の範囲では ESTree との互換性があるが、TypeScript の部分は特に仕様とかはなく、実装が仕様のような状態である。@babel/parser の出力する TypeScript AST との互換性を一応意識しているが、微妙にずれているので注意。

TypeScript Compiler API の AST が難しいことがあるので、楽に TypeScript を解析したいときにも使える。型情報を上手く扱えるかはやったことがないのでわからないが、EStree Node <-> TS Compiler API Node の WeakMap とかを取得できる API があるので、それと https://github.com/dsherret/ts-morph とかを使えば比較的楽に型を使った操作もできるんじゃないだろうか。

Prettier の TypeScript 用デフォルトパーサー。

Sosuke SuzukiSosuke Suzuki

Acorn

https://github.com/acornjs/acorn

ESTree 互換の AST を出力する JavaScript パーサー。

@babel/parser のもとになった(@babel/parser は acorn のフォーク、現在ではかなり異なる実装になっているが)。

新しい ECMAScript の機能は Stage 4 になってから実装される。

しかし Acorn はプラグインを書くことでデフォルトでは対応していない構文にも対応できる。これは @babel/parser にはない機能である。

ESLint のデフォルトパーサーである Espree で使われているほか、webpack のパーサーとしても使われている。

Sosuke SuzukiSosuke Suzuki

Espree

https://github.com/eslint/espree

ESLint でデフォルトで使われているパーサー。もともとは Esprima のフォークとしてはじまったが、現在では内部で Acorn を使っている。

ESLint で使用する上で Acorn のみでは不十分な箇所を補っているようだ。

実は Prettier でも --parser=espree を指定することで Espree を使ってパースができる。実用性というよりは、エコシステム間で不和が生じないようにテストに使うために使われている。

Sosuke SuzukiSosuke Suzuki

Meriyah

https://github.com/meriyah/meriyah

パフォーマンスを重視した JavaScript のパーサー。あまり有名ではないが出来はよい。

実は Prettier でも --parser=meriyah を指定することで Meriyah を使ってパースができる。これは実用性を考えて実装された。実際に Prettier 自身のコードをフォーマットするときは Meriyah パーサーを使っている(速いから)。

Sosuke SuzukiSosuke Suzuki

Esprima

https://github.com/jquery/esprima

SpiderMonkey Parser API をもとに実装されたパーサー。
ESTree 互換の JavaScript パーサーとしては最も古い(はず)。

現在ではあまり活発に開発が行われていないように見えるが、実際はよく知らない。