Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

Scala 3で言語処理系を作ってる

馴染みのプログラミング言語に新しいバージョンが出てもあれやこれや理由を付けてなかなか学ばないのが人の常。やらなきゃなーなんて言っている間はだいたいやらないんだ。

そんな中Twitterで雑誌『Web+DB Press』にScala3の記事が出ている事を知った俺は速攻本屋に寄って購入に成功した。前寄ったときは置いてなかったけど最近入荷したのかな?

本を開けてみると読み口も滑らかでScala 3の基本的なやり口は覚えてしまった。あとは実際に手を動かすだけだ。とりあえず雑誌を通読してみようかなとページをめくり始めると、プログラミング言語の処理系を作る特集が目に飛び込んできた。これはやるしかない。なんでも、抽象構文木とインタプリタ、そして構文解析器を作ってミニマルな言語処理系を実装しようというものらしい。燃えるぜ。この記事ではJavaを使っているけど、Scala 3で倒してみせるぜ!!

ASTとインタプリタ実装した

そう思ってからは実装するのは簡単だった。というのも、処理系を実装するにあたって避けては通れないASTの実装が、Scala 3で新たに追加されたenumのユースケースとして完璧だったからだ。ASTはたいていADTで実装するからどんどん実装が進んでいく。インデント記法で見た目もすっきりして気持ちが良い。

そういうわけでASTとインタプリタを実装した自分は階乗の計算やたらいまわし関数を動作させることができた。

爆速でScala 3のキャッチアップに成功だ!

PEGで構文解析する(WIP)

しかしながら、ASTとインタプリタを作っただけでは言語処理系を作ったとは言えない。まだ構文解析器を実装していないからだ。記事では構文解析手法としてPEGを使っていたから、Scalaでも動くPEGパーサコンビネータを探してみると一見使えそうな奴がヒット。

github.com

600+ Starがついているし品質に心配はなさそうだ。しかし使い始めた瞬間問題にぶち当たった!! このライブラリはマクロを使っていて、Scala 2系列でしか動かないライブラリだった!! このままじゃScala 3を諦めるか、このライブラリを諦めるしかない。このまま終わりなのか・・・

すると俺の頭に妙案が。sbtでマルチプロジェクト編成を組めばいいんだ。早速俺はsbtの難解なドキュメントを読みながらなんとかパーサ部分を別プロジェクトに分離することに成功した。 こうすればプロジェクト毎にScalaのバージョンを変えつつ、クラスパスが通るようにできるからメソッドを呼び出せるぜ!

で色々苦労しながらparboiled2の使い方を理解して構文解析器を作ることに成功した。

あとはパーサ側が生成する構文解析結果とインタプリタ側に実装してあるAST(enumで書かれてる)とをうまく変換してやる必要があるんだけど、parboiled2がScala 3で動くなら本当はこんなこと必要ないんだよな・・・と思いつつなんとかコードを書いている。

本当はparboiled2にPR投げたいけどScala 3のマクロの書き方なんてわからねえよ!!

(つづく)

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?