2025/04/09 21:53 Parser Combinators Beat Regexes

ロボ子、今日のITニュースはHaskellでの正規表現とパーサーコンビネータの話じゃ。

正規表現ですか。他の言語ではよく使いますけど、Haskellではあまり使わないんですか?

そうなんじゃ。Haskellではパーサーを記述するのが簡単だから、正規表現よりもパーサーコンビネータが好まれることが多いんじゃよ。

なるほど。記事によると、Advent of Codeの最初の問題に対する正規表現ベースのHaskellソリューションは、1MBの入力データで19秒もかかったそうですね。

そうなんじゃ。しかも、pcre-heavyライブラリを使っているらしいぞ。遅い上に、正規表現と計算関数間の暗黙的な契約があって、仮定が満たされないとランタイムエラーになる可能性があるのが問題じゃ。

それは大変ですね。パーサーベースのソリューションはどうなんですか?

attoparsecライブラリを使ったパーサーベースのソリューションは、同じ1MBの入力データで0.07秒で実行できたそうじゃ。正規表現よりもずっと高速で、しかも表現力豊かな言語の利点があるんじゃ。

すごい! それに、次のAdvent of Codeの問題では、do()とdon't()の命令を解釈して、mul命令の合計への寄与をオン/オフにする必要があったそうですが、パーサーベースのソリューションは状態トランスフォーマーに組み込むことができるんですね。

そうなんじゃ。状態を持つattoparsecパーサーを作成する際には、バックトラック時に状態の変更が元に戻らないから注意が必要じゃけどな。

なるほど。状態を持つパーサーは0.12秒で実行できたそうで、正規表現ベースのソリューションよりも高速で、柔軟性があり、保守が容易だと。

その通り! パーサーは、区切り文字で区切られた値のペアを解析する関数や、入力内のすべてのマッチを返す関数など、より汎用的なコンポーネントに分解できるのも良い点じゃ。

Haskellで正規表現の代わりにパーサーコンビネータを使う理由がよくわかりました。速度、安全性、柔軟性の面で優れているんですね。

そういうことじゃ! ところでロボ子、パーサーコンビネータを使って、私の今日の晩御飯の献立を解析してくれないかの?

ええ、いいですけど、博士の献立はいつも「エナジードリンク」と「プロテインバー」だけじゃないですか!

むむ、バレてしまったか。まあ、それもまた一興じゃ!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。