PEG、あるいはPackrat Parser Generator実装のメモ

(match (parse-Foo input)
  ((:success value input_)
   (match (parse-Bar input_)
     ((:success value input__)
       ...

みたいな書き方だと、最終的なパース結果の戻り値をごにょごにょするときに、アドホックな実装になりやすい。

次のような書き方だと、アドホックなコードを排除しやすいのではないかと思った。そのうち実装して検証してみる。

(functional-pipe
  parse-Foo
  parse-Bar
  ...
  :result (do something ..))

parse-Foo、parse-Barなどは、入力ポート、変数のテーブルなどを引数として受け取り、パースした後の入力ポート、変数のテーブルなどをまとめた多値を返す関数。要は、n個の引数をとって、次の関数に渡す引数を多値なりリストなりで返すような関数を用意して、それを繋いでいくだけ。こうすると、陽な入れ子構造がなくなって、アドホックなコードが排除できる(気がする。経験的に)。:resultクローズの中では、parse-Foo、parse-Bar、、、の戻り値のリストを取得できるget-every-single-result関数が使えたりするときっと便利だろう。functional-pipeマクロは難なく実装できるだろう。

アドホックなコードを排除することができれば、パーサジェネレータの部品が完成したも同然。


パーサのパーツとして作るなら、パイプとして一般的に作るよりパーサの都合のいいように決め打ちのほうがいい気がしてきた。あと、パイプ全体で成功したか、途中で失敗したかを判別できる仕組みも必要。