ドキュメンテーションツール作るときにお世話になりそうなesprima、estraverse、escope、資料とか仕様がなくて困ったので、3回に分けてメモとして残しておく。
esprima
esprimaはピュアなJSで書かれたJavaScriptパーサモジュール。JavaScriptコードの文字列をパースしてAST(Abstract Syntax Tree)を返す。 かなり速く、テストもよくされているらしい。 デモがよくできていて、ASTの構造、トークンの構造がよくわかる。 オプションによってStrategyを変えるため、無駄な条件判定が省かれている。こういう細かいところまで行き届いているのでパフォーマンスが良いわけだ。
使い方はいたってカンタン。 まず、esprimaをnpmで取ってくる。
npm install esprima
次に、以下のスクリプトを作成する。
var esprima = require('esprima'); var code = 'console.log("Hello, World!");'; var ast = esprima.parse(code); console.log(ast);
で、実行。おわり。 ちなみに、parse関数の第二引数でオプションを設定できる。
仕様をJsDoc風に書くとこうなるだろう。
/** * パースする。 * @param {string} code パースしたいコードの文字列。 * @param {EsprimaOption|undefined} 省略可能なオプション。 * オブジェクト自体を省略した場合はオプション項目がすべてfalseとみなされる。下のEsprimaOptionを見てね。 * @return {AstNode} パースされたコードのASTノード。 */ esprima.parse; /** * esprima.parseの第二引数に指定できるオブジェクト。オプション項目のいずれも省略可能で、省略した場合はfalseとみなされる。 * @type {Object} */ EsprimaOption = { /** * 文字インデックスベースの範囲をASTノードに追加する(AstNode.rangeでアクセスできる)。 * @type {boolean|undefined} */ range: true, /** * 行・列ベースの範囲をASTノードに追加する(AstNode.locでアクセスできる)。 * @type {boolean|undefined} */ loc: true, /** * 生のリテラルをASTのリテラルノードに追加する(AstLiteralNode.rawでアクセスできる)。 * @type {boolean|undefined} */ raw: true, /** * トークン列を結果に追加する(parseの戻り値.tokensでアクセスできる)。 * @type {boolean|undefined} */ tokens: true, /** * コメント列を結果に追加する(parseの戻り値.commentsでアクセスできる)。 * @type {boolean|undefined} */ comments: true, /** * 多少の構文エラーは無視して解釈する*1。 * @type {boolean|undefined} */ torelant: true };
おわり。
え、なんでわざわざJsDocで書くんだって?見にくい? でも書きやすいんですよ。うちのVimではな!!!!
※1 esprima.parse('x = 2,;', { tolerant: true});
のようにある程度の構文エラーに耐えられるようにできる。