ESTree 互換っぽい AST を出力する JavaScript のパーサーまとめ
ESTree という JavaScript の AST の仕様がある。ESTree っぽいものを出力してくれるパーサーをまとめていく。
雑にまとめているので興味ある人とか詳しい人は適当に追記してもらって構いません。
@babel/parser
Babel で使われているパーサー。最新の JavaScript だけでなく、まだ ECMAScript に入っていないプロポーザルや TypeScript、Flow もオプションで対応している。また、AST は ESTree と一部互換性がないものを出力するが、estree
プラグインを使うことで、ESTree 互換の AST を出力させることもできる。
Prettier のデフォルトパーサー。@babel/eslint-parser
を使うことで ESLint のパーサーとしても使うことができる。
@typescript-eslint/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 用デフォルトパーサー。
Acorn
ESTree 互換の AST を出力する JavaScript パーサー。
@babel/parser
のもとになった(@babel/parser
は acorn のフォーク、現在ではかなり異なる実装になっているが)。
新しい ECMAScript の機能は Stage 4 になってから実装される。
しかし Acorn はプラグインを書くことでデフォルトでは対応していない構文にも対応できる。これは @babel/parser
にはない機能である。
ESLint のデフォルトパーサーである Espree で使われているほか、webpack のパーサーとしても使われている。
Espree
ESLint でデフォルトで使われているパーサー。もともとは Esprima のフォークとしてはじまったが、現在では内部で Acorn を使っている。
ESLint で使用する上で Acorn のみでは不十分な箇所を補っているようだ。
実は Prettier でも --parser=espree
を指定することで Espree を使ってパースができる。実用性というよりは、エコシステム間で不和が生じないようにテストに使うために使われている。
Meriyah
パフォーマンスを重視した JavaScript のパーサー。あまり有名ではないが出来はよい。
実は Prettier でも --parser=meriyah
を指定することで Meriyah を使ってパースができる。これは実用性を考えて実装された。実際に Prettier 自身のコードをフォーマットするときは Meriyah パーサーを使っている(速いから)。
flow-parser
Flow のパーサー。本体は OCaml で記述されているが npm パッケージとして配布されており、ESTree 互換の AST を出力する。
Prettier での Flow のデフォルトパーサー。
Esprima
SpiderMonkey Parser API をもとに実装されたパーサー。
ESTree 互換の JavaScript パーサーとしては最も古い(はず)。
現在ではあまり活発に開発が行われていないように見えるが、実際はよく知らない。
hermes-parser
Facebook の Hermes エンジン のパーサーを WebAssembly コンパイルしたものらしい。
ES6、Flow、JSX の構文に対応している。
オプションで Babel Compatible な AST を吐くこともできる。