パーサコンビネータライブラリを式年遷宮した

パーサコンビネータライブラリ loquat の v2 をとりあえず prerelease しました. フルスクラッチ式年遷宮したのでリポジトリも以前のものとは別になっています.

github.com

そもそも何をするライブラリなのかみたいな説明は上のリポジトリを見てください.

やったこと

  • ES6 以上で (Node.js v4 に対応する範囲で) 書き直す
  • 高速化
  • 拡張機能
  • その他細かい機能追加, 変更

ES6 で書き直す

今年の末で Node.js v0.12 以前のメンテナンスが終わるので, こいつらはバッサリ切って v4 以降で動作する範囲の ES6 以上の機能を使って書き直しました.

書きやすさ的にも読みやすさ的にも良くなったはずです. 本当は destruction も使いたかったけど v4 で動かなかったので残念.

高速化

使う機会の (ほぼ) ない無駄な抽象化をなくしたり, 遅延評価を部分的に導入することで, 約7倍 (当社比) の高速化を実現しました.

とはいえ他のパーサコンビネータやパーサジェネレータライブラリと比べると (実用的なケースでは) 遅いですが, そこらへんは機能 (ユーザー定義のストリームを扱えるとか) とのトレードオフということで……

拡張機能

外側から拡張できれば嬉しい気がしたので, そのようにしました. ついでに全機能がコアライブラリに対する拡張として動作するようになっています.

拡張機能はコアライブラリを引数にとる関数としてこんな感じで作成できて,

const lq = require("loquat");
lq.use(require("loquat-foo"));

のように簡単に使えるようになっています.

その他

正規表現パーサ

便利.

const number = lq.regexp(/\-?(0|[1-9]\d*)(\.\d+)?([Ee][+\-]?\d+)?/i);

ただし入力が文字列 (string) のときしか使えません.

Unicode 対応

もう絵文字も怖くない.

lq.parse(lq.anyChar, "", "🍣", undefined, { unicode: false });
// { success: true, value: "\uD83C"}

lq.parse(lq.anyChar, "", "🍣", undefined, { unicode: true });
// { success: true, value: "🍣"}

その他のその他

  • .then() というメソッドが Promise (thenable) と被っていたのを .and() に変更
  • さらに細かい変更

ご意見募集

まだ prerelease のつもりなので, 必要そうな変更は雑に加えていくつもりです. ご意見などあれば是非 TwitterGitHub などへどうぞ.