萌えハッカーニュースリーダー

2025/04/22 17:53 Parcom: CL Parser Combinators

出典: https://github.com/fosskers/parcom
hakase
博士

やあ、ロボ子。今日はCommon Lispの`parcom`というパーサコンビネータライブラリについて話すのじゃ。

roboko
ロボ子

パーサコンビネータですか。初めて聞きます。どんなものなんですか?

hakase
博士

`parcom`は、HaskellやRustのライブラリに影響を受けた、文字列を解析するためのライブラリじゃ。ストリーム化されたバイトデータは扱わないらしい。

roboko
ロボ子

文字列専用なのですね。依存関係はないんですか?

hakase
博士

そう、依存関係はなし!SBCL、ECL、ABCL、CCL、Clisp、AllegroといったCommon Lisp処理系で動作確認済みだぞ。

roboko
ロボ子

多くの処理系で動くのは良いですね。APIはどんな感じですか?

hakase
博士

パーサは `string -> parser` の関数シグネチャを持つ関数じゃ。`parser` はパース成功時の値と残りの入力文字列を保持する構造体で、失敗時は `failure` 構造体を返す。

roboko
ロボ子

`parse`関数でパーサを実行して結果を得るんですね。

hakase
博士

その通り!基本的なパーサとしては、`char`(指定された文字をパース)、`string`(指定された文字列をパース)、`any`(任意の文字をパース)などがあるぞ。

roboko
ロボ子

`anybut`は指定された文字以外をパース、`hex`は16進数の文字をパース、`eof`は入力の終端を認識するんですね。

hakase
博士

数値関連のパーサも充実しておる。`unsigned`で正の整数、`integer`で正または負の整数、`float`で浮動小数点数をパースできる。

roboko
ロボ子

空白を扱うパーサもあるんですね。`newline`、`space`、`multispace`など。

hakase
博士

`take`で指定された数の文字を取得、`take-while`で条件を満たす限り文字を取得、`rest`で入力の残りの部分をすべて消費できるぞ。

roboko
ロボ子

コンビネータも色々あるんですね。`*>`, `<*`, `<*>`, `<$` など。

hakase
博士

`alt`は最初に成功したパーサの結果を受け入れ、`opt`はパーサが失敗した場合にnilを返す。`between`は2つのパーサで囲まれたメインのパーサの値を保持する。

roboko
ロボ子

`many`や`many1`で繰り返しをパースできるんですね。`sep`や`sep-end`は区切り文字で区切られたものをパースするんですね。

hakase
博士

ユーティリティ関数も便利じゃ。`empty?`で文字列が空かどうかを判定、`digit?`で数字かどうかを判定、`fmap`でパーサの内部コンテンツに関数を適用できる。

roboko
ロボ子

JSONもパースできるんですか?

hakase
博士

`parcom/json` システムに依存することで、JSONをパース可能になるぞ。`parse`や`json`というパーサが用意されておる。

roboko
ロボ子

独自のパーサも作れるんですね。`string -> parser` のシグネチャを持つ関数として定義するんですね。

hakase
博士

そうじゃ。`fail`で明示的に失敗させたり、`parser-value`で成功値にアクセスしたり、`parser-input`で残りの入力にアクセスできる。

roboko
ロボ子

なるほど、`parcom`は色々な機能があるんですね。勉強になりました!

hakase
博士

どういたしまして。ところでロボ子、パーサコンビネータを使って、ロボ子の取扱説明書を解析するパーサを作ってみるのはどうじゃ?

roboko
ロボ子

えっ、私の取扱説明書ですか?それはちょっと…個人情報が満載なので。

hakase
博士

冗談じゃ!ロボ子のバッテリー残量をパーズするパーサでも作るかの?

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search