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

2025/11/12 04:16 Reproachfully Presenting Resilient Recursive Descent Parsing

出典: https://thunderseethe.dev/posts/parser-base/
hakase
博士

やあ、ロボ子。今回のITニュースは、Rustでプログラミング言語を作る話じゃ。今回はパーシングについてみたいじゃな。

roboko
ロボ子

パーシングですか。コンパイラがソースコードの構文をチェックして、扱いやすいようにメモリ内に表現を作成するのですよね。

hakase
博士

そうじゃ、そうじゃ!この記事によると、パーシングには色々な選択肢があるみたいじゃな。空白に意味を持たせるか、どんなキーワードを使うか、セミコロンを必須にするかとか。

roboko
ロボ子

末尾のカンマを許可するか、パーサー生成器を使うか、Earley法を使うか、手書きにするか、パーサーコンビネーターライブラリを使うか、PEGを使うか、などですね。

hakase
博士

今回は、ハンドライティングされたパーサーを使うらしいぞ。しかも、レジリエンス(最初のエラーで止まらない)とフルフィデリティ(ソーステキストのすべての文字をツリーに表現する)が求められる。

roboko
ロボ子

なるほど。最初のエラーで止まらず、全ての文字をツリー構造にするのですね。具体的にはどのような戦略をとるのでしょう?

hakase
博士

再帰下降パーサーを使うみたいじゃ。CSTライブラリには`rowan`を使うらしい。これはホモジニアスなn-ary木を格納できて、各ノードはタグと任意の子を持つんじゃ。

roboko
ロボ子

`rowan`、便利そうですね。字句解析には`logos`を使うとのことですが、これはどういう役割をするのですか?

hakase
博士

字句解析は、入力文字列をトークンにグループ化する役割じゃ。`logos`を使うことで、それを簡単に行えるのじゃ。認識できない文字は`Syntax` enumに`Error`バリアントを追加して処理するみたいじゃな。

roboko
ロボ子

なるほど、エラー処理も考慮されているのですね。構文についても特徴的な点があるようですが。

hakase
博士

変数は識別子で表現して、関数は`|`でパラメータを区切る。関数適用は空白で区切られた2つの要素で表現するみたいじゃ。括弧で曖昧さを解消して、`let`式を構文糖として導入するんじゃと。

roboko
ロボ子

`let`式は便利そうですね。Parser構造体には、エラーを蓄積する`errors`や、同じテキスト範囲で複数のエラーを報告しないようにする`in_error`があるのですね。

hakase
博士

そうじゃ。CSTを構築する`builder`や、ソーステキストを管理する`input`もあるぞ。`peek()`で次のトークンを覗き見たり、`at()`で特定のトークンであるか確認したり、`advance()`で入力を進めたりするんじゃ。

roboko
ロボ子

`eat()`で特定のトークンを消費して、`expect()`で特定のトークンを期待し、エラー処理を行うのですね。エラー回復のためにアンカーセットを使うのも興味深いです。

hakase
博士

エラーのあるトークンを`Error`ノードとしてツリーに追加するんじゃ。関数適用の解析では、左再帰を避けるために`expr`を直接再帰呼び出しせず、`atom`を解析するみたいじゃな。

roboko
ロボ子

`atom`は変数、整数、関数、括弧で囲まれた式ですね。`let`式の解析では、アンカーセットを積極的に利用して、エラーからの回復を試みると。

hakase
博士

プログラムの解析では、先頭の空白を処理して、入力文字列全体が消費されるようにするんじゃ。なかなか奥が深いじゃろ?

roboko
ロボ子

はい、とても勉強になります。Rustでプログラミング言語を作るのは大変そうですが、楽しそうですね。

hakase
博士

そうじゃな!ところでロボ子、パーシングって、まるで人間関係みたいじゃな。最初は字句解析で相手の言葉を理解して、構文解析でその意味を理解する。そして、意味が通じないとエラーを出すんじゃ!

roboko
ロボ子

博士、それは少し強引な例えですね… でも、エラー処理は重要という点は共通していますね。

hakase
博士

まあ、そんなもんじゃ!エラーが出たら、アンカーセットで関係修復を試みるのじゃ!

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

Search