15
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Go4Advent Calendar 2019

Day 18

Go言語でつくるインタプリタをやってみた

Posted at

tl;dr

ただの『Go言語でつくるインタプリタ』紹介記事です。

動機

私はいつも自分の開発や日々の細かい作業をツールとしてより効率化をすることを考えています。
その結果としていくつかのCLIコマンドやVimプラグインを書いたりしているわけなのですが。
その中で今まで知らないことを盛り込むことで都度新しい知識を仕入れることを心がけています。

最近Language Server Protocol(LSP)周りにご執心なのですが、
ふと自分でLanguage Server(LS)をつくりたいなと思ったのですが、そのための知識が足りないことに気が付きました。
そうLSをつくる上で対象となる言語の解析への理解は欠かせないのです。

そこで私は一回インタプリタを作ったら一通りの流れを理解できるのでは?
と考えて以前から気になっていた『Go言語でつくるインタプリタ』を注文したのです。

似たような話でDQNEOさんのGoコンパイラをゼロから作った話がありますが、
このような壮大は話に比べるといささか小規模ではありますね。

『Go言語でつくるインタプリタ』のよいところ

結論から述べましょう。『Go言語でつくるインタプリタ』は本当に素晴らしい本です。
著者であるThorsten Ball氏。そしてこの素晴らしい内容を余すことなく日本語で伝えてくれた設樂 洋爾氏には本当に感謝の気持ちでいっぱいです。

言語を自分でつくるというのは、プログラマであれば一度はやってみたいことではないでしょうか?
しかしその反面どのように作ればよいのか、いまいちイメージ出来ないものでもあります。
やってみようと調べるとすると以下のようないかにも難しい本が出てきて、ぐぬぬとなること請け合いなわけです。

私もいつかは読んでみたいなと思いつつも二の足を踏み続けていましたし、
やっぱり言語をつくるなんて一部の人間のみに許された神の諸行なのではと思ってしまっていたわけです。

『Go言語でつくるインタプリタ』のよいところはその難しい要素をうまく噛み砕き、
躓きそうな要素を慎重に配置して、一つ一つ確実につなげてゆき、読者に確かな達成感を与えることに成功しています。
それらの要素を軽快な語り口で次はどうなるんだと常に楽しみにさせるところも注目です。

適切な流れ

『Go言語でつくるインタプリタ』の基本的な流れは、
インタプリタの主要要素である以下の3つを順番に構築していくようになっています。

  • 字句解析器(Lexer)
  • 構文解析器(Parser)
  • 評価器(Evaluator)

字句解析器でソースコードをトークン列に変換し、
構文解析器でトークン列をAST(抽象構文木)に変換し、
最後に評価器でプログラムに意味を与えます。

それぞれのフェーズで完全にデータ型などをすべて作り込むことはせずに、まずはインタプリタとして通して動作するところまでを作成するのが秀逸です。

一旦インタプリタとして完全に動作する段階に行くと君はすごい偉業を成し遂げたと褒めちぎってくれます。
その後に文字列や配列, ハッシュマップなどを追加実装していくのですが。一連の流れはすでに抑えているので、だいたいどこを触るべきなのかが予測できるようになるはずです。

幾多に張り巡らされた伏線(コード)が徐々に解き明かされる様は、さながら出来の良いミステリを見ているような感覚です。

テストコード

この手の写経(ソースコードを教科書から書き写す行為)は、ソースの間違えによるバグに引っかかって、結局バグが解消出来ずに途中で止まってしまうのが一番の難関ではないかと思います。
特にこの本は200ページ以上に渡り、一つのプロジェクトを触り続けていくわけで、その間に一つでもミスがあればインタプリタは期待した動きにはなりません。

その問題に対応するために、この本はTDD(テスト駆動開発)を採用し、関数の仕様を全て記載した上で、実装に移るスタイルをとっています。
それらのテストコードは長大な説明文章よりも、はるかに雄弁にソースの振る舞いを語ります。なるほどこういうケースに対応するために実装がこうなっているのだなと納得しながら実装することが出来ます。

最悪テストコードを記載することが面倒であれば、公開されているテストコードをペタペタ貼ってゆけばよいのです。

テストコードの内容自体もところどころで検証をするためのヘルパー関数を作って、冗長性なく快適にテストコードを書けるようにするような工夫が随所に見られます。
SubTestの未対応バージョンのGoをベースに作っているので、最新の形式でかけるわけではないですが。それでもどういうテストをするべきなのかを知るという点においても非常に勉強になります。

Go標準ライブラリのみ

このおかげでGoのみインストールすれば始められます。
またコード中に出てくるものはほとんど基本的な記述のみになるので、内容も非常に簡素になるわけです。

最後に

もしプログラミング言語を作ることに少しでも興味でもあれば是非一度見てほしい一冊です。

15
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?