こんにちは, 口の中パッサパサです.
さてパッサパサといえばパーサコンビネータの話をしましょう.
以前作った JavaScript 用パーサコンビネータライブラリ の TypeScript 向けインターフェースをつくりました.
こんな感じで使えます. どーしてくれんだマリコちゃん.
import { string, StringParser } from "typed-loquat"; const p = string(); type P<T> = StringParser<T>; const parser: P<string> = p.string("口の中").and( p.anyChar.manyTill(p.string("だよ").try()).map(cs => cs.join("")).bind(term => p.string(term).and(p.eof).return(term) ) ); const result = parser.parse("", "口の中パッサパサだよパッサパサ"); if (result.success) { console.log(result.value); // → パッサパサ }
まあこれは冗談として, サンプルいくつか用意してるのでこちらを見てください.
まだ型付けてみたって感じの alpha 版なので, なんか型付けミスってるとか使いにくいとかあればフィードバックください.
特徴
- だいたい Haskell の parsec のクローンです. ほとんどの機能は使えます
- 高速です. parsimmon みたいなめちゃくちゃシンプルなものよりも高速. ふしぎだね
- ジェネレータを使った do 風記法や末尾呼び出し最適化が効かないことの対策など, JS で使いやすくする工夫も重ねてあります. ただ移植しただけではない
- テストカバレッジ 100%
なんで @types/loquat
とかでないのか
元の JS のライブラリの方を見てもらえるとわかると思うのですが, インターフェースが型を付けるのに恐ろしく適していないです. 大体全部 bind operator とか pipeline operator みたいなのが無いために prototype 拡張で凌いでいるのが悪い. これは当初から認識していて, まあいざ型提供したくなったら適当に固めたパッケージ作って提供してやればよかろうと思っていて, 今回のがそれです.
TypeScript について
だいたい Flow は触るたびにげんなりして帰ってくる*1って感じだけど, TypeScript はあんまりそういうことはなくて良いです.